附件是我在JS中的最小工作示例。我只能显示初始数据,但当我更改滑块时,数据不会更新。在这里,我的代码哪里出错了?对于糟糕的结构,我很抱歉--我仍然是D3的初学者。
https://jsfiddle.net/pv02z8em/1/
chartGroup
.selectAll('.line-series')
.data(data, d=> d.x)
.join(
enter => {
enter.append('path')
.attr('class', d => `line-series x_${d.x}`)
.attr("d", drawLine(data))
.style('stroke', 'dodgerblue')
.style('stroke-width', 2)
.style('fill', 'none')
.style('opacity', 1)
},
update => { update.transition().duration(500) },
exit => { exit.remove() }
)
}发布于 2021-02-28 20:13:50
您在该代码中有几个问题:
您没有根据滑块的ID选择滑块。滑块应该是
;
在侦听器中,您不会调用
;
移走里面的所有东西
这与路径本身无关,否则每次用户移动滑块时都会创建不同的SVG;
你的
结构当前正在追加
几个
路径,一个在另一个之上。这肯定不是你想要的。它可能只是:
让path = chartGroup.selectAll('.line-series') .data(
数据
);path = path.enter() .append(‘路径’).attr(‘类’,“线条系列”) .attr("d",d => drawLine(d)) .style(‘描边’,‘渐变蓝’).style(‘描边宽度’,2) .style(‘填充’,‘无’).style(‘不透明度’,1) .merge(path) path.transition().duration(500).attr("d",d => drawLine(d))
以下是您的代码,其中包含这些和其他细微更改:
svg {
display: inline-block;
position: relative;
vertical-align: top;
overflow: hidden;
}
.x-axis,
.y-axis {
font: 16px sans-serif;
}
.axis-label {
font: 18px sans-serif;
}
.chart-title {
font: 24px sans-serif;
}
.x-axis .tick:first-of-type text {
fill: none;
}
.body {
display: flex;
}
.chart-group-container {
margin: 10px 20px 20px 20px;
}
.controls-container {
display: flex;
flex-direction: column;
}
.controls-header {
color: black;
padding: 0.5rem 2rem;
text-align: left;
}
.controls-body {
overflow: auto;
font-size: 0.8em;
cursor: default;
}
.slidecontainer {
text-align: left;
margin: 10px;
font-family: sans-serif;
font-size: 14px;
}
#slider-x-range {
vertical-align: bottom;
}
Document
UI Controls
Adjust x axis
10
100
//let sinWave = Math.sin(x)
let range = function(start, stop, step) {
step = step || 1;
let arr = []
for (let i = start; i < stop; i += step) {
arr.push(i);
}
return arr;
}
let generateSinWave = function(x) {
let y = []
x.forEach(function(i) {
y.push(Math.sin(i))
});
return y;
}
const generateData = (n) => {
x = range(0, n, 1)
y = generateSinWave(x)
let labels = ['x', 'y']
let data = []
for (let i = 0; i < x.length; i++) {
data.push({
x: x[i],
y: y[i]
})
}
return data;
}
let margin = {
top: 50,
right: 30,
bottom: 30,
left: 100
},
width = 800 - margin.left - margin.right
height = 400 - margin.top - margin.bottom;
let xScale = d3.scaleLinear()
.range([0, width])
let yScale = d3.scaleLinear()
.range([height, 0])
.nice()
let drawLine = d3.line()
.x(d => xScale(d.x))
.y(d => yScale(d.y))
.curve(d3.curveBasis);
let svg = d3.select('.viz')
.append('svg')
.attr("viewBox", `0 0 ${width + margin.left + margin.right} ${height + margin.top + margin.bottom}`)
.attr("preserveAspectRatio", "xMinYMin meet")
//.attr('width', `${width + margin.left + margin.right}px`)
//.attr('height', `${height + margin.top + margin.bottom}px`)
//.classed("svg-content", true);
.append('g')
.attr('class', 'line-chart-container')
.attr('transform', `translate(${margin.left}, ${margin.top})`);
/* d3.select(".line-chart-container")
.attr("style", "outline: thin solid black;")
.attr("margin-right", "102px") */
const chartGroup = svg.append('g').attr('class', 'line-chart')
// Draw x axis
const xAxis = d3.axisBottom(xScale).tickSizeOuter(0);
const xAxisDraw = svg
.append('g')
.attr('class', 'x-axis')
//.style('font', '14px sans-serif')
.attr('transform', `translate(0, ${height / 2})`)
.call(xAxis);
const yAxis = d3
.axisLeft(yScale)
.ticks(10)
//.tickSizeInner(-width);
const yAxisDraw = svg
.append('g')
.attr('class', 'y-axis')
.call(yAxis);
// x axis label
svg.append('text')
.attr('class', 'axis-label')
.attr('text-anchor', 'end')
.text('X axis')
.attr('x', width)
.attr('y', height - margin.bottom + 50)
// y axis label
svg.append('text')
.attr('class', 'axis-label')
.attr('text-anchor', 'end')
.attr('transform', 'rotate(-90)')
.attr('x', margin.top + 50 - (height / 2))
.attr('y', margin.left - 160)
.text('Y axis')
// Draw Header
const header = svg
.append('g')
.attr('class', 'chart-title')
.attr('transform', `translate(${width / 2 - 75}, ${margin.top - 75})`)
.append('text')
header.append('tspan').text('Sine wave')
function buildLine(data) {
xScale.domain([d3.min(data, d => d.x), d3.max(data, d => d.x)])
yScale.domain([d3.min(data, d => d.y), d3.max(data, d => d.y)])
let path = chartGroup
.selectAll('.line-series')
.data([data]);
path = path.enter().append('path')
.attr('class', "line-series")
.attr("d", d => drawLine(d))
.style('stroke', 'dodgerblue')
.style('stroke-width', 2)
.style('fill', 'none')
.style('opacity', 1)
.merge(path)
path.transition().duration(500).attr("d", d => drawLine(d))
}
let xRangeSlider = document.getElementById('slider-x-range');
xRangeSlider.min = 10;
xRangeSlider.max = 100;
let data = generateData(xRangeSlider.value)
buildLine(data)
d3.select('#slider-x-range')
.on("change", d => {
data = generateData(xRangeSlider.value)
buildLine(data)
});
正如您将发现的那样,转换可能不是您所期望的:这是一个无关的问题,即
属性字符串(您可以找到更多信息
这里
)。
https://stackoverflow.com/questions/66408600
复制相似问题