Одним из основных принципов объединения данных D3 является то, что оно идемпотентно. Другими словами, если вы неоднократно оцениваете объединение данных с одними и теми же данными, результат вывода будет одинаковым. Поэтому, если вы правильно отображаете диаграмму, заботясь о выбранных параметрах ввода, обновления и выхода - все, что вам нужно делать при изменении размера, это повторно визуализировать диаграмму полностью.
Есть несколько других вещей, которые вы должны сделать, одна из них - отменить обработчик изменения размера окна, чтобы уменьшить его. Кроме того, вместо того, чтобы жестко кодировать ширину / высоту, это должно быть достигнуто путем измерения содержащего элемента.
В качестве альтернативы, ваша диаграмма отображается с использованием d3fc , который представляет собой набор компонентов D3, которые правильно обрабатывают соединения данных. Он также имеет декартову диаграмму, которая измеряет его, содержащий элемент, облегчающий создание «отзывчивых» диаграмм:
// create some test data
var data = d3.range(50).map(function(d) {
return {
x: d / 4,
y: Math.sin(d / 4),
z: Math.cos(d / 4) * 0.7
};
});
var yExtent = fc.extentLinear()
.accessors([
function(d) { return d.y; },
function(d) { return d.z; }
])
.pad([0.4, 0.4])
.padUnit('domain');
var xExtent = fc.extentLinear()
.accessors([function(d) { return d.x; }]);
// create a chart
var chart = fc.chartSvgCartesian(
d3.scaleLinear(),
d3.scaleLinear())
.yDomain(yExtent(data))
.yLabel('Sine / Cosine')
.yOrient('left')
.xDomain(xExtent(data))
.xLabel('Value')
.chartLabel('Sine/Cosine Line/Area Chart');
// create a pair of series and some gridlines
var sinLine = fc.seriesSvgLine()
.crossValue(function(d) { return d.x; })
.mainValue(function(d) { return d.y; })
.decorate(function(selection) {
selection.enter()
.style('stroke', 'purple');
});
var cosLine = fc.seriesSvgArea()
.crossValue(function(d) { return d.x; })
.mainValue(function(d) { return d.z; })
.decorate(function(selection) {
selection.enter()
.style('fill', 'lightgreen')
.style('fill-opacity', 0.5);
});
var gridlines = fc.annotationSvgGridline();
// combine using a multi-series
var multi = fc.seriesSvgMulti()
.series([gridlines, sinLine, cosLine]);
chart.plotArea(multi);
// render
d3.select('#simple-chart')
.datum(data)
.call(chart);
Вы можете увидеть это в действии в этом коде:
https://codepen.io/ColinEberhardt/pen/dOBvOy
где вы можете изменить размер окна и убедиться, что диаграмма правильно перерисована.
Обратите внимание, что в качестве полного раскрытия я являюсь одним из сопровождающих d3fc.