數據來自csv文件。
繪製效果圖:
數據集解釋:數據信息爲美國六個主要城市每個月的光照時間變化。
代碼詳細解釋:
let Color = new Array();
// 隨機生成每個城市的代表顏色
for (let i = 0; i < 6; ++i) {
Color[i] = 'rgba(' + Math.random() * 255 + ',' + Math.random() * 255 + ',' + Math.random() * 255 + ',' + 0.8 + ')';
}
首先生成所有城市的顏色。所有顏色的rgb數值均隨機生成。
// 構造比例尺
xScale = d3.scaleLinear()
.domain([0, 350])
.range([0, w - inner.left - inner.right])
.nice();
xAxis = d3.axisBottom(xScale);
svg.append("g")
.attr("transform", "translate(" + inner.left + "," + (h - inner.bottom - 40) + ")")
.call(xAxis);
構造下方的比例尺。將比例尺平放放在底部。
// 解析csv數據
d3.csv("sunshine.csv").then(function (d) {
Data = d;
// 首先按月份排序
Data.sort(function (a, b) {
return a.monthnum - b.monthnum;
});
console.log(Data);
draw();
});
解析csv數據。注意這個過程是異步的,接下來所進行的所有操作均在draw函數中執行。
//右下方數值,表示月份
let comment = svg.append("text")
.attr("x", w - inner.right - inner.right)
.attr("y", h - inner.bottom - inner.bottom - 40)
.attr("fill", "black")
.text(function () {
return Data[idx].month;
})
.style("font-size", "40");
添加右下角的文本數據,表示當前狀態所示的月份。
// 綁定該年的數據
const groups = svg.selectAll("g")
.data(DataEntry).enter()
.append("g");
// 生成標籤和矩形
let labels = groups.data(DataEntry)
.enter().append("text")
.text(d => d.city)
.attr("x", function (d, i) {
return inner.left - 10;
})
.style("font-size", 20)
.attr("text-anchor", "end");
let rects = groups.data(DataEntry)
.enter().append("rect")
.attr("x", inner.left)
.attr("height", H * 0.65)
.attr("fill", function (d, i) {
return Color[i];
})
.attr("width", function (d) {
return xScale(d.sunshine);
});
數據主體部分,即表示數據的直方圖以及數據旁邊的城市名稱。注意利用text-anchor來控制文本的對齊信息。此處爲右對齊。
// 設定更新函數
function UpdateElement() {
// 通過data指定綁定的鍵值
labels.data(DataEntry, d => d.city)
.transition()
.duration(600)
.attr("y", function (d, i) {
return i * H + inner.bottom + 40;
});
rects.data(DataEntry, d => d.city)
.transition()
.duration(600)
.attr("y", function (d, i) {
return i * H + inner.bottom;
})
.attr("width", function (d) {
return xScale(d.sunshine);
});
}
設定更新函數。
這裏一定要注意,利用data來綁定更新數據,d => d.city爲設置的綁定的鍵值。否則綁定其他信息會導致結果出錯。
// 更新函數
function update(t) {
let W = new Array();
for (let i = 0; i < 6; ++i)
W.push(Data[t * 6 + i]);
W.sort(function (a, b) {
return b.sunshine - a.sunshine;
});
DataEntry = W;
comment.text(DataEntry[0].month);
UpdateElement();
}
// 調用更新函數,每0.7s更新一次
setInterval(function () {
update((++idx) % 12);
}, 700);
設置更新函數以及調用更新函數。
完整代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>7</title>
</head>
<body>
<script src="https://d3js.org/d3.v5.js"></script>
<script>
let w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
let h = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
w *= 0.98;
h *= 0.90;
let inner = {top: 100, right: 100, bottom: 50, left: 200};
let xScale, xAxis;
let DataEntry = new Array();
let Data = new Array();
let H = (h - inner.bottom - inner.top) / 6 * 0.95;
let Color = new Array();
// 隨機生成每個城市的代表顏色
for (let i = 0; i < 6; ++i) {
Color[i] = 'rgba(' + Math.random() * 255 + ',' + Math.random() * 255 + ',' + Math.random() * 255 + ',' + 0.8 + ')';
}
// 添加畫布
let svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h)
.append("g");
// 構造比例尺
xScale = d3.scaleLinear()
.domain([0, 350])
.range([0, w - inner.left - inner.right])
.nice();
xAxis = d3.axisBottom(xScale);
svg.append("g")
.attr("transform", "translate(" + inner.left + "," + (h - inner.bottom - 40) + ")")
.call(xAxis);
// 月份循環變量
let idx = 0;
// 解析csv數據
d3.csv("sunshine.csv").then(function (d) {
Data = d;
// 首先按月份排序
Data.sort(function (a, b) {
return a.monthnum - b.monthnum;
});
console.log(Data);
draw();
});
function draw() {
//右下方數值,表示月份
let comment = svg.append("text")
.attr("x", w - inner.right - inner.right)
.attr("y", h - inner.bottom - inner.bottom - 40)
.attr("fill", "black")
.text(function () {
return Data[idx].month;
})
.style("font-size", "40");
// 添加該月份的所有的城市信息
for (let i = 0; i < 6; ++i)
DataEntry.push(Data[idx * 6 + i]);
DataEntry.sort(function (a, b) {
return b.sunshine - a.sunshine;
});
// console.log(DataEntry);
// 綁定該年的數據
const groups = svg.selectAll("g")
.data(DataEntry).enter()
.append("g");
// 生成標籤和矩形
let labels = groups.data(DataEntry)
.enter().append("text")
.text(d => d.city)
.attr("x", function (d, i) {
return inner.left - 10;
})
.style("font-size", 20)
.attr("text-anchor", "end");
let rects = groups.data(DataEntry)
.enter().append("rect")
.attr("x", inner.left)
.attr("height", H * 0.65)
.attr("fill", function (d, i) {
return Color[i];
})
.attr("width", function (d) {
return xScale(d.sunshine);
});
// 設定更新函數
function UpdateElement() {
// 通過data指定綁定的鍵值
labels.data(DataEntry, d => d.city)
.transition()
.duration(600)
.attr("y", function (d, i) {
return i * H + inner.bottom + 40;
});
rects.data(DataEntry, d => d.city)
.transition()
.duration(600)
.attr("y", function (d, i) {
return i * H + inner.bottom;
})
.attr("width", function (d) {
return xScale(d.sunshine);
});
}
UpdateElement();
// 更新函數
function update(t) {
let W = new Array();
for (let i = 0; i < 6; ++i)
W.push(Data[t * 6 + i]);
W.sort(function (a, b) {
return b.sunshine - a.sunshine;
});
DataEntry = W;
comment.text(DataEntry[0].month);
UpdateElement();
}
// 調用更新函數,每0.7s更新一次
setInterval(function () {
update((++idx) % 12);
}, 700);
}
svg.append("text")
.text("Monthly Hours of Sunshine")
.attr("x", w / 2)
.attr("y", 30)
.style("font-size", 25)
.attr("text-anchor", "middle");
</script>
</body>
</html>
另附sunshine.csv中的數據
city,lon,lat,month,monthnum,sunshine
Seattle,-122.335167,47.608013,Jan,0,69
Seattle,-122.335167,47.608013,Feb,1,108
Seattle,-122.335167,47.608013,Mar,2,178
Seattle,-122.335167,47.608013,Apr,3,207
Seattle,-122.335167,47.608013,May,4,253
Seattle,-122.335167,47.608013,Jun,5,268
Seattle,-122.335167,47.608013,Jul,6,312
Seattle,-122.335167,47.608013,Aug,7,281
Seattle,-122.335167,47.608013,Sep,8,221
Seattle,-122.335167,47.608013,Oct,9,142
Seattle,-122.335167,47.608013,Nov,10,72
Seattle,-122.335167,47.608013,Dec,11,52
Chicago,-87.623177,41.881832,Jan,0,135
Chicago,-87.623177,41.881832,Feb,1,136
Chicago,-87.623177,41.881832,Mar,2,187
Chicago,-87.623177,41.881832,Apr,3,215
Chicago,-87.623177,41.881832,May,4,281
Chicago,-87.623177,41.881832,Jun,5,311
Chicago,-87.623177,41.881832,Jul,6,318
Chicago,-87.623177,41.881832,Aug,7,283
Chicago,-87.623177,41.881832,Sep,8,226
Chicago,-87.623177,41.881832,Oct,9,193
Chicago,-87.623177,41.881832,Nov,10,113
Chicago,-87.623177,41.881832,Dec,11,106
New York,-73.935242,40.73061,Jan,0,154
New York,-73.935242,40.73061,Feb,1,171
New York,-73.935242,40.73061,Mar,2,213
New York,-73.935242,40.73061,Apr,3,237
New York,-73.935242,40.73061,May,4,268
New York,-73.935242,40.73061,Jun,5,289
New York,-73.935242,40.73061,Jul,6,302
New York,-73.935242,40.73061,Aug,7,271
New York,-73.935242,40.73061,Sep,8,235
New York,-73.935242,40.73061,Oct,9,213
New York,-73.935242,40.73061,Nov,10,169
New York,-73.935242,40.73061,Dec,11,155
San Francisco,-122.446747,37.733795,Jan,0,165
San Francisco,-122.446747,37.733795,Feb,1,182
San Francisco,-122.446747,37.733795,Mar,2,251
San Francisco,-122.446747,37.733795,Apr,3,281
San Francisco,-122.446747,37.733795,May,4,314
San Francisco,-122.446747,37.733795,Jun,5,330
San Francisco,-122.446747,37.733795,Jul,6,300
San Francisco,-122.446747,37.733795,Aug,7,272
San Francisco,-122.446747,37.733795,Sep,8,267
San Francisco,-122.446747,37.733795,Oct,9,243
San Francisco,-122.446747,37.733795,Nov,10,189
San Francisco,-122.446747,37.733795,Dec,11,156
Houston,-95.358421,29.749907,Jan,0,144
Houston,-95.358421,29.749907,Feb,1,141
Houston,-95.358421,29.749907,Mar,2,193
Houston,-95.358421,29.749907,Apr,3,212
Houston,-95.358421,29.749907,May,4,266
Houston,-95.358421,29.749907,Jun,5,298
Houston,-95.358421,29.749907,Jul,6,294
Houston,-95.358421,29.749907,Aug,7,281
Houston,-95.358421,29.749907,Sep,8,238
Houston,-95.358421,29.749907,Oct,9,239
Houston,-95.358421,29.749907,Nov,10,181
Houston,-95.358421,29.749907,Dec,11,146
Miami,-80.191788,25.761681,Jan,0,222
Miami,-80.191788,25.761681,Feb,1,227
Miami,-80.191788,25.761681,Mar,2,266
Miami,-80.191788,25.761681,Apr,3,275
Miami,-80.191788,25.761681,May,4,280
Miami,-80.191788,25.761681,Jun,5,251
Miami,-80.191788,25.761681,Jul,6,267
Miami,-80.191788,25.761681,Aug,7,263
Miami,-80.191788,25.761681,Sep,8,216
Miami,-80.191788,25.761681,Oct,9,215
Miami,-80.191788,25.761681,Nov,10,212
Miami,-80.191788,25.761681,Dec,11,209