d3.js 使用新数据重新绘制d3图

v7pvogib  于 2022-11-12  发布在  其他
关注(0)|答案(1)|浏览(273)

我对d3很陌生。你能帮我一下吗,为什么我的图形在我按下按钮生成新数据后不重画?它画了一次,但在我按下按钮后它只记录新的数据数组到控制台。我删除旧数据错误吗?
为了防止我单独导入d3函数,这就是为什么它被写为select而不是d3.select的原因。除了更新图形之外,一切都正常。
谢谢你,这里有一个类似的问题,我试着用类似的方法来做,但是我不知道我做错了什么。

const randomValue = randomInt(0, 100);
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sen', 'Oct', 'Nov', 'Dec'];

let data = months.map(m => ({
    label: m,
    value: randomValue()
}))

let values = data.map(m => m.value)

const yScale = scaleLinear().domain([0, 100]).range([0, height]);
const colorScale = scaleLinear().domain([0, 100]).range(['#d22626', '#086cdc']);
const $chartContainer = $root.append('g')
    .classed('.mz-chart__container', true)
    .attr('transform', `translate(${padding}, ${100})`);    

const xScale = scaleBand().domain(months).range([0, width]).paddingInner(0.2);
const hAxis = axisBottom().scale(xScale);
$root.append("g")
    .attr('transform', `translate(${padding}, ${height+100})`)
    .call(hAxis);

const vAxisScale = scaleLinear().domain([0, 100]).range([height, 0]);
const vAxis = axisLeft()
    .scale(vAxisScale)
    .tickSize(-width, 0, 0)
    .tickFormat((y, x) => y);

$root.append("g")
    .attr("transform", "translate(40, 100)")
    .call(vAxis);

function updateChart() {
    data = months.map(m => ({
        label: m,
        value: randomValue()
    }))

    console.log(data);
    let chartbars = $chartContainer.selectAll('.mz-chart__bar').data(data)

    chartbars
        .exit()
        .remove()

    chartbars
        .enter()
        .append('g')
        .classed('mz-chart__bar', true)
        .append('rect')
        .attr('x', (d, i) => xScale(d.label))
        .attr('y', (d, i) => height - yScale(d.value))
        .attr('height', (d, i) => yScale(d.value))
        .attr('width', (d, i) => xScale.bandwidth())
        .attr('fill', d => colorScale(d.value));
}

select(".mz-button").on("click", updateChart)
updateChart()
mrwjdhj3

mrwjdhj31#

您有一个进入选择和一个退出选择,但您没有使用更新选择。
selection.enter()仅在所选元素少于数据数组中的项时创建元素:它被用来创建所有的元素,因为不存在。输入选择不包含预先存在的元素,但是,这些元素在更新选择(chartbars)中。
我们可以通过合并现有的和新的条,然后对它们进行样式化,来强制它们具有适当的属性:

let newbars = chartbars
    .enter()
    .append('g')
    .classed('mz-chart__bar', true)
    .append('rect');

chartbars.select('rect').merge(newbars)  
    .attr('x', (d, i) => xScale(d.label))
    .attr('y', (d, i) => height - yScale(d.value))
    .attr('height', (d, i) => yScale(d.value))
    .attr('width', (d, i) => xScale.bandwidth())
    .attr('fill', d => colorScale(d.value));

例如:
第一个

  • 因为我们使用enter().append()添加了一个嵌套元素,但我们选择的是g父元素,所以我们需要使用www.example.com('rect')为更新选择中的每个元素选择一个子矩形chartbars.select,然后将其与newbars(新添加的矩形的选择)合并。*
  • 我修改了您的代码中的间距和大小-我也不确定,但我相信您希望红色条更大(这需要切换y刻度范围内的值)。最后,我删除了多余的y刻度。*

相关问题