D3.js输入,更新,退出问题

时间:2015-06-16 17:43:19

标签: javascript d3.js charts updates

我有一个相对简单的条形图。我想在.transition()事件的数据集之间.on("click")。我得到的是完全重绘附加到DOM ID的附加图表,而不是删除原始图表并转换或替换它。我想我误解了如何正确.remove()

d3.json("data/cfilt-steps.json", function(d) {

    d.forEach(function(d) { 
        parseDate = d3.time.format("%Y-%m-%d").parse;
        d.date = parseDate(d.date); d.value = +d.value;
        });

    margin      = {top:5, right:5, bottom: 40, left:5},
    height      = 150 - margin.top - margin.bottom, 
    width       = 500 - margin.left - margin.right, 
    barPadding  = 1;

    steps    = crossfilter(d), 
    monthdim = steps.dimension(function(d){ thisDate = new Date(d.date); return thisDate.getMonth(); }),
    monthgrp = monthdim.group().reduceSum(function(d){ return d.value; });
    daydim   = steps.dimension(function(d){ thisDate = new Date(d.date); return thisDate.getDay(); }),
    daygrp   = daydim.group().reduceSum( function(d) { return d.value; });

    stepColor = d3.scale.threshold()
            .domain([100, 150, 200, 250, 300, 400, 500])
            .range(["#E3E3E3", "#D0DFD2", "#C3DABC", "#BDCB87", "#CAB44E", "#E29517", "#FF6600"]);

    d3.select("#monthly-steps-previous-selector")
            .on("click", function(d) {reDraw(monthgrp.all()) })   

    d3.select("#monthly-steps-next-selector")
            .on("click", function(d) {reDraw(daygrp.all()); })    

    function reDraw(data) {

        xScale = d3.scale.ordinal().domain(monthdim).range(0, width);

        yScale = d3.scale.linear().domain([0, d3.max(data, function(d){return d.value;})]).range([height, 5]);

        var stepbars = d3.select("#steps-bar")
            .append("svg:svg")
            .attr("width", width)
            .attr("height", height)

        stepbars.selectAll("rect")
            .data(data)
            .enter().append("rect")
            .attr("x", function(d,i){ return i * width/data.length; })
            .attr("y", function(d){ return yScale(d.value); })
            .attr("width", width/data.length - barPadding)
            .attr("height", function(d) { return height-yScale(d.value); })
            .attr("fill", function(d){ return stepColor(d.value/2000); })

    } 

reDraw(monthgrp.all());

});

有人能告诉我这应该是什么样的,或告诉我我做错了什么?

1 个答案:

答案 0 :(得分:1)

你的reDraw函数附加了svg,这意味着每次调用redraw时都会附加一个新的svg,因此是双图表。我建议把行

var stepbars = d3.select("#steps-bar")
        .append("svg:svg")
        .attr("width", width)
        .attr("height", height)

在reDraw函数上方。

此外,您的重绘功能不会调用删除。我会做类似的事情:

//Select and bind to data
var selection = stepbars.selectAll("rect")
        .data(data);

//Enter and create new rectangles
selection.enter()
        .append("rect");

//Update all rectangles
selection.attr("x", function(d,i){ return i * width/data.length; })
        .attr("y", function(d){ return yScale(d.value); })
        .attr("width", width/data.length - barPadding)
        .attr("height", function(d) { return height-yScale(d.value); })
        .attr("fill", function(d){ return stepColor(d.value/2000); });

//Remove unused rectangles
selection.exit().remove();