0%

Histogram

Histogram

设计思路

直方图用于统计样本及其数量的度量,由于中国疫情已经过去,使用历史数据筛选出来太麻烦了,所以我找了美国疫情的当天的数据(Cases, Deaths, Recovery, Hospitalization)[1]

先找一个模板[2],然后修改。

后来我又加入了button的功能[3],用于查看那4类数据。

效果图

Covid-19 statistics in US of all states, 7th, Oct, 2020

HTML源代码

<html>
<head><p>Covid-19 statistics in US of all states, 7th, Oct, 2020</p></head>
<body>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.js"></script>
<style>
.button {
background-color: #fff5eb;
border: none;
border-radius: 8px;
color: #936223;
padding: 8px 20px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
box-shadow: 0 8px 12px 0 rgba(0,0,0,0.2), 0 3px 6px 0 rgba(0,0,0,0.19);
}
</style>
<button class = "button" onclick="choose(1)">Cases</button>
<button class = "button" onclick="choose(2)">Deaths</button>
<button class = "button" onclick="choose(3)">Recov.</button>
<button class = "button" onclick="choose(4)">Hosp.</button>

<div id = "covid19"></div>
<script>
var p = d3.select("body").selectAll("p");
p.style("color","#87753c").style("font-size","24px");

var margin = {top: 30, right: 30, bottom: 30, left: 40},
width = 600 - margin.left - margin.right,
height = 450 - margin.top - margin.bottom;

var svg = d3.select("#covid19")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var x = d3.scaleLinear().range([0, width]);
var xAxis = d3.axisBottom().scale(x);
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.attr("class","myXaxis");

var y = d3.scaleLinear().range([height, 0]);
var yAxis = d3.axisLeft().scale(y);
svg.append("g")
.attr("class","myYaxis");

var cases = [], deaths = [], recovery = [], hosp = [];
d3.csv("https://raw.githubusercontent.com/Co10/d3_files/master/CSV_files/02/covid-19_US_7th%2COct%2C20.csv", function(data){
data.map(function(d) {
cases.push(d.Cases);
deaths.push(d.Deaths);
recovery.push(d.Recovery);
hosp.push(d.Hospitalization);
});
})
function choose(choice) {
var datas = [];
switch(choice){
case 1: datas = cases; break;
case 2: datas = deaths; break;
case 3: datas = recovery; break;
case 4: datas = hosp; break;
default: datas = cases; break;
}
update(datas);
}

function update(datas) {
var durSpeed = 1000;
var maxX = d3.max(datas, function(d) { return +d });
x.domain([0, maxX])
svg.selectAll(".myXaxis").transition()
.duration(durSpeed)
.call(xAxis);

var bins = d3.histogram()
.domain(x.domain())
.thresholds(x.ticks(90))
(datas);

y.domain([0, d3.max(bins, function(d) { return d.length; })]);
svg.selectAll(".myYaxis")
.transition()
.duration(durSpeed)
.call(yAxis);

var u = svg.selectAll(".rectTrans")
.data(bins);

u.enter()
.append("rect")
.attr("class", "rectTrans")
.merge(u)
.transition()
.duration(durSpeed)
.attr("x", 1)
.attr("transform", function(d) { return "translate(" + x(d.x0) + "," + y(d.length) + ")"; })
.attr("width", function(d) { return x(d.x1) - x(d.x0) - 1; })
.attr("height", function(d) { return height - y(d.length); })
.style("fill", "#f26e5d");


svg.append("text")
.attr("x", width)
.attr("y", height+10)
.text("count")
.style("font-size", "10px")
.attr("alignment-baseline","middle")
svg.append("text")
.attr("x", 6)
.attr("y", 0)
.text("frequency")
.style("font-size", "10px")
.attr("alignment-baseline","middle")
}

choose(1);
</script>
</body>
</html>

实现方法

d3.histogram()创建直方图。用bins存每一桶的数据。

Summary

数据选的是2020年10月7日(或者说是6日)美国各个州的感染、死亡、恢复、住院数量,各个州差别可能会比较大,所以数据还是太稀疏了,有些数据中间的数据点空了一大片。

修正方法是将X轴中间的空白处折叠,但是我不会折叠啊……

本来也想加入渐变色的,越后面颜色越深表示越严重,但是改来改去没改出来……

Reference

[1] https://en.wikipedia.org/wiki/COVID-19_pandemic_in_the_United_States#covid19-container

[2] https://www.d3-graph-gallery.com/graph/histogram_basic.html

[3] https://www.d3-graph-gallery.com/graph/line_change_data.html