Я пытаюсь использовать библиотеку d3.js для анимации графика.В конце концов я буду получать данные асинхронно из веб-сокета, но для примера я просто использую комбинацию setInterval
+ getRandomInt
.Мне нужно добавить новые данные к уже известным данным и соответствующим образом обновить график.Важным моментом является то, что я не хочу стирать старые данные - вся история должна отображаться на графике бесконечно.
Мне удалось анимировать график, но моя проблема в том, что последний добавленный элемент (правый конец графика) просто добавляется без анимации.Это выглядит странно, и я хотел бы это исправить.
Я, вероятно, должен отметить, что я хочу отображать самые последние данные, как только они доходят до браузера, поэтому скрыть последний элемент невозможно.
<html>
<head>
<title>Simple Line Graph using SVG and d3.js</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
</head>
<body>
<script>
const margins = [80, 80, 80, 80]; // margins
const width = 1000 - margins[1] - margins[3]; // width
const height = 400 - margins[0] - margins[2]; // height
const svg = d3
.select("body")
.append("svg")
.attr("width", width + margins[1] + margins[3])
.attr("height", height + margins[0] + margins[2])
.append("svg:g")
.attr("transform", "translate(" + margins[3] + "," + margins[0] + ")");
const data = [1, 5, 2, 13, 0];
const x = d3.scale
.linear()
.domain([0, data.length])
.range([0, width]);
const y = d3.scale
.linear()
.domain([d3.min(data), d3.max(data)])
.range([height, 0]);
const lineFunction = d3.svg
.line()
.x((_, i) => x(i))
.y(d => y(d))
.interpolate("cardinal");
svg
.append("path")
.attr("d", lineFunction(data))
.attr("stroke-width", 5)
.attr("stroke", "red")
.attr("fill", "none");
setInterval(() => {
data.push(getRandomInt(1, 10));
x.domain([0, data.length]);
y.domain([d3.min(data), d3.max(data)]);
svg
.transition()
.duration(750)
.select("path")
.attr("d", lineFunction(data));
}, 1000);
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
</script>
</body>
</html>