В книге «Визуализация данных с помощью кулинарной книги D3» (глава 8) появляется пример, где автор рисует две строки. В основном, данные создаются случайным образом:Обновление данных в простой многоразовой диаграмме D3
var numberOfSeries = 2,
numberOfDataPoint = 11,
data = [];
for (var i = 0; i < numberOfSeries; ++i)
data.push(d3.range(numberOfDataPoint).map(function (i) {
return {x: i, y: randomData()};
}));
Затем автор создает экземпляр диаграммы и определяет область Шкалы:
var chart = lineChart()
.x(d3.scale.linear().domain([0, 10]))
.y(d3.scale.linear().domain([0, 10]));
После этого, данные вводят с помощью метода :
data.forEach(function (series) {
chart.addSeries(series);
});
И, наконец, диаграмма оказывается вызовом render()
метод:
chart.render();
Кроме того, участок имеет Update
днище, что позволяет обновлять данные показали, вызвав эту функцию:
function update() {
for (var i = 0; i < data.length; ++i) {
var series = data[i];
series.length = 0;
for (var j = 0; j < numberOfDataPoint; ++j)
series.push({x: j, y: randomData()});
}
chart.render();
}
Моя проблема заключается в том, что я не могу понять, как эти данные обновляются в сюжете без вызова метода снова, после нажатия кнопки Update
, то есть в функции update()
. Внутренние данные хранятся в переменной _data
, которая может быть изменена с помощью метода . Есть идеи?
Большое спасибо!
Полный код here, но после я скопировал самые важные части:
function lineChart() { // <-1A
var _chart = {};
var _width = 600, _height = 300, // <-1B
_margins = {top: 30, left: 30, right: 30, bottom: 30},
_x, _y,
_data = [],
_colors = d3.scale.category10(),
_svg,
_bodyG,
_line;
_chart.render = function() { // <-2A
if (!_svg) {
_svg = d3.select("body").append("svg") // <-2B
.attr("height", _height)
.attr("width", _width);
renderAxes(_svg);
defineBodyClip(_svg);
}
renderBody(_svg);
};
// Axis rendering functions ...
function renderBody(svg) { // <-2D
if (!_bodyG)
_bodyG = svg.append("g")
.attr("class", "body")
.attr("transform", "translate("
+ xStart() + ","
+ yEnd() + ")") // <-2E
.attr("clip-path", "url(#body-clip)");
renderLines();
}
function renderLines() {
_line = d3.svg.line() //<-4A
.x(function (d) { return _x(d.x); })
.y(function (d) { return _y(d.y); });
_bodyG.selectAll("path.line")
.data(_data)
.enter() //<-4B
.append("path")
.style("stroke", function (d, i) {
return _colors(i); //<-4C
})
.attr("class", "line");
_bodyG.selectAll("path.line")
.data(_data)
.transition() //<-4D
.attr("d", function (d) { return _line(d); });
}
//Some getter/setters functions and other stuff
_chart.addSeries = function (series) { // <-1D
_data.push(series);
return _chart;
};
return _chart; // <-1E
}
function randomData() {
return Math.random() * 9;
}
function update() {
for (var i = 0; i < data.length; ++i) {
var series = data[i];
series.length = 0;
for (var j = 0; j < numberOfDataPoint; ++j)
series.push({x: j, y: randomData()});
}
chart.render();
}
var numberOfSeries = 2,
numberOfDataPoint = 11,
data = [];
for (var i = 0; i < numberOfSeries; ++i)
data.push(d3.range(numberOfDataPoint).map(function (i) {
return {x: i, y: randomData()};
}));
var chart = lineChart()
.x(d3.scale.linear().domain([0, 10]))
.y(d3.scale.linear().domain([0, 10]));
data.forEach(function (series) {
chart.addSeries(series);
});
chart.render();
Спасибо за быстрый ответ. Кстати, можете ли вы порекомендовать мне какую-нибудь книгу/учебник для чего-то большего, что «начиная с D3»? Некоторые ссылки с хорошей практикой и дизайном? –
Я не читал его сам, но я считаю, что [книга Скотта Мюррея] (http://alignedleft.com/work/d3-book) неплоха. –