gpt4 book ai didi

javascript - 移动折线图上的圆圈

转载 作者:行者123 更新时间:2023-12-04 10:00:10 24 4
gpt4 key购买 nike

想在我的实时折线图上绘制圆圈。图表每次迭代都会生成随机 y 值并将其绘制在图表上,从而移动域。这是我的代码 -

const svg = d3.select('svg');
const MARGIN = {TOP: 50, BOTTOM: 50, LEFT: 50, RIGHT: 50};
const WIDTH = svg.attr('width') - MARGIN.LEFT - MARGIN.RIGHT;
const HEIGHT = svg.attr('height') - MARGIN.TOP - MARGIN.BOTTOM;

const limit = 60;
const duration = 500;
let dataList = [];

let g = svg.append('g').attr('transform', `translate( ${MARGIN.LEFT}, ${MARGIN.TOP} )`);

g.append('defs').append('clipPath')
.attr('id', 'clip2')
.append('rect')
.attr('x', 0)
.attr('y', 0)
.attr('width', WIDTH)
.attr('height', HEIGHT);

// ParseTime

const timeScale = d3.scaleTime()
.range([0, WIDTH]);

const valueScale = d3.scaleLinear()
.domain([0, 10])
.range([HEIGHT, 0]);

const line = d3.line()
.curve(d3.curveBasis)
.x((d) => timeScale(d.time))
.y((d) => valueScale(d.value));

const xAxis = d3.axisBottom(timeScale);

const axisCall = g.append('g')
.attr('transform', `translate(0, ${HEIGHT})`);

axisCall.call(xAxis);

g.append('g')
.attr('class', 'axis axis--y')
.call(d3.axisLeft(valueScale))

let pathsG = g.append('g').attr('id', 'paths').attr('class', 'paths').attr('clip-path', 'url(#clip2)');

function updateChart() {
let now = Date.now();
dataList.push({
time: now,
value: Math.floor(Math.random() * 10)
});

// Shift domain
timeScale.domain([now - ((limit - 2) * duration), now - duration]);

axisCall.transition().duration(duration).ease(d3.easeLinear, 2).call(xAxis);

let minerG = pathsG.selectAll('.minerLine').data([dataList]);
let minerGEnter = minerG.enter()
.append('g')
.attr('class', 'minerLine')
.merge(minerG);

let minerSVG = minerGEnter.selectAll('path').data(function(d) {
return [d];
});

let minerSVGenter = minerSVG.enter()
.append('path').attr('class', 'line')
.style('stroke', '#D073BA')
.style('fill', 'none')
.merge(minerSVG)
.transition()
.duration(duration)
.ease(d3.easeLinear, 2)
.attr('d', line(dataList))
.attr('transform', null);

let circles = minerGEnter.selectAll('circle')/*.data(function(d) {
return [d];
});*/
circles.data(dataList)
.enter()
.append('circle')
.merge(circles)
.transition()
.duration(duration)
.ease(d3.easeLinear, 2)
.attr('r', 5)
.attr('cx', (d, i) => timeScale(d.time))
.attr('cy', d => valueScale(d.value));

circles.exit().remove();

}

setInterval(function(){
//console.log('hello');
updateChart();
}, 500);
<!DOCTYPE html>
<html>
<head></head>
<title>Real-time Line Chart D3</title>
<link rel="stylesheet" href="styles.css">
<script src="https://d3js.org/d3.v5.min.js"></script>
<body>
<svg width="960" height="500">
</svg>
<script src="bundle.js"></script>
</body>
</html>


如您所见,图表正在运行,但圆圈不起作用。他们是两个问题。图表显示圆圈进入图表的动画,圆圈似乎有错误的 y 值。我很确定我添加圆圈的方式不正确。尝试从在线代码中获取示例,但没有任何效果。

任何想法如何解决这两个问题?

最佳答案

圆圈的位置没有错,它们是正确的。它们可能看起来是错误的,因为您正在对路径使用内插器 ( d3.curveBasis ),该路径会对其进行修改:删除内插器可以清楚地表明这一点,如下面的演示所示。此外,关于转换,解决方案可能是在输入选择中设置圆圈的位置,并且只转换 x在更新选择中的位置。

这是您的代码,仅进行了这 2 处更改:

const svg = d3.select('svg');
const MARGIN = {
TOP: 50,
BOTTOM: 50,
LEFT: 50,
RIGHT: 50
};
const WIDTH = svg.attr('width') - MARGIN.LEFT - MARGIN.RIGHT;
const HEIGHT = svg.attr('height') - MARGIN.TOP - MARGIN.BOTTOM;

const limit = 60;
const duration = 500;
let dataList = [];

let g = svg.append('g').attr('transform', `translate( ${MARGIN.LEFT}, ${MARGIN.TOP} )`);

g.append('defs').append('clipPath')
.attr('id', 'clip2')
.append('rect')
.attr('x', 0)
.attr('y', 0)
.attr('width', WIDTH)
.attr('height', HEIGHT);

// ParseTime

const timeScale = d3.scaleTime()
.range([0, WIDTH]);

const valueScale = d3.scaleLinear()
.domain([0, 10])
.range([HEIGHT, 0]);

const line = d3.line()
.x((d) => timeScale(d.time))
.y((d) => valueScale(d.value));

const xAxis = d3.axisBottom(timeScale);

const axisCall = g.append('g')
.attr('transform', `translate(0, ${HEIGHT})`);

axisCall.call(xAxis);

g.append('g')
.attr('class', 'axis axis--y')
.call(d3.axisLeft(valueScale))

let pathsG = g.append('g').attr('id', 'paths').attr('class', 'paths').attr('clip-path', 'url(#clip2)');

function updateChart() {
let now = Date.now();
dataList.push({
time: now,
value: Math.floor(Math.random() * 10)
});

// Shift domain
timeScale.domain([now - ((limit - 2) * duration), now - duration]);

axisCall.transition().duration(duration).ease(d3.easeLinear, 2).call(xAxis);

let minerG = pathsG.selectAll('.minerLine').data([dataList]);
let minerGEnter = minerG.enter()
.append('g')
.attr('class', 'minerLine')
.merge(minerG);

let minerSVG = minerGEnter.selectAll('path').data(function(d) {
return [d];
});

let minerSVGenter = minerSVG.enter()
.append('path').attr('class', 'line')
.style('stroke', '#D073BA')
.style('fill', 'none')
.merge(minerSVG)
.transition()
.duration(duration)
.ease(d3.easeLinear, 2)
.attr('d', line(dataList))
.attr('transform', null);

let circles = minerGEnter.selectAll('circle').data(function(d) {
return d;
});

circles.exit().remove();

circles = circles.enter()
.append('circle')
.attr('r', 5)
.attr('cx', (d, i) => timeScale(d.time))
.attr('cy', d => valueScale(d.value))
.merge(circles);

circles.transition()
.duration(duration)
.ease(d3.easeLinear, 2)
.attr('cx', (d, i) => timeScale(d.time));

}

setInterval(function() {
//console.log('hello');
updateChart();
}, 500);
<!DOCTYPE html>
<html>

<head></head>
<title>Real-time Line Chart D3</title>
<link rel="stylesheet" href="styles.css">
<script src="https://d3js.org/d3.v5.min.js"></script>

<body>
<svg width="960" height="500">
</svg>
<script src="bundle.js"></script>
</body>

</html>

关于javascript - 移动折线图上的圆圈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61851969/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com