我正在使用d3js相对于当前时间从右向左移动圆点。我有几个问题: 1. .exit()。remove()不起作用。节点一旦离开视图,就不会被删除。 2.圈子的过渡有点跳跃
var circles = g.selectAll('path')
circles.data(data)
.enter()
.append('path')
.attr("d", symbol.type(d3.symbolCircle))
.merge(circles)
.attr("transform", (d) => "translate(" + x(d.x) + "," + y(d.y) + ")");
circles.exit().remove();
您可以在此处查看我的完整代码:http://jsfiddle.net/hsdhott/3tdhuLgm/
答案 0 :(得分:0)
除了您的输入-退出-更新模式不正确(请检查下面的代码段)外,这里的最大问题是数据:
selection.exit()
方法不会神奇地选择元素-通常用于以后使用remove()
-基于任何任意条件的元素,例如“退出视图” 。它仅基于数据。问题是您的数据永远不会停止增长:
if (count % 10 === 0) {
var point = {
x: globalX,
y: ((Math.random() * 200 + 50) >> 0)
};
data.push(point);
}
因此,在这种情况下,一种非常快速的解决方案是根据您的x
域删除数据点:
data = data.filter(function(d) {
return d.x > globalX - 10000;
});
这只是一个建议,请使用所需的逻辑从数据数组中删除对象。但是,无论使用哪种逻辑,都必须删除它们。
关于过渡过渡,问题在于您使用的是selection.transition
和setInterval
。那行不通,选择其中之一。
这是您更新的代码:
var data = [];
var width = 500;
var height = 350;
var globalX = new Date().getTime();
/* var globalX = 0; */
var duration = 250;
var step = 10;
var count = 0;
var chart = d3.select('#chart')
.attr('width', width + 50)
.attr('height', height + 50);
var x = d3.scaleTime()
.domain([globalX, (globalX - 10000)])
.range([0, width]);
var y = d3.scaleLinear()
.domain([0, 300])
.range([300, 0]);
// -----------------------------------
// Draw the axis
var xAxis = d3.axisBottom()
.scale(x)
.ticks(10)
.tickFormat(formatter);
var axisX = chart.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(0, 300)')
.call(xAxis);
// Append the holder for line chart and circles
var g = chart.append('g');
function formatter(time) {
if ((time.getSeconds() % 5) != 0) {
return "";
}
return d3.timeFormat('%H:%M:%S')(time);
}
function createData() {
// Generate new data
var point = {
x: globalX,
y: ((Math.random() * 200 + 50) >> 0)
};
data.push(point);
}
function callInterval() {
count++;
if (count % 3 === 0) createData();
}
// Main loop
function tick() {
// Generate new data
if (count % 10 === 0) {
var point = {
x: globalX,
y: ((Math.random() * 200 + 50) >> 0)
};
data.push(point);
}
data = data.filter(function(d) {
return d.x > globalX - 10000;
});
count++;
globalX = new Date().getTime();
var timer = new Date().getTime();
var symbol = d3.symbol().size([100]),
color = d3.schemeCategory10;
var circles = g.selectAll('path')
.data(data);
circles = circles.enter()
.append('path')
.attr("d", symbol.type(d3.symbolCircle))
.merge(circles)
.attr("transform", (d) => "translate(" + x(d.x) + "," + y(d.y) + ")");
circles.exit().remove();
// Shift the chart left
x.domain([timer - 10000, timer]);
axisX.call(xAxis);
g.attr('transform', null)
.attr('transform', 'translate(' + x(globalX - 10000) + ')');
// Remote old data (max 50 points)
if (data.length && (data[data.length - 1].x < (globalX - 10000))) data.shift();
}
tick();
setInterval(tick, 10);
.axis {
font-family: sans-serif;
font-size: 12px;
}
.line {
fill: none;
stroke: #f1c40f;
stroke-width: 3px;
}
.circle {
stroke: #e74c3c;
stroke-width: 3px;
fill: #FFF;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<svg id="chart"></svg>