【问题标题】:Updating D3 column chart with different values and different data sizes使用不同的值和不同的数据大小更新 D3 柱形图
【发布时间】:2012-06-20 15:12:06
【问题描述】:

背景

我正在尝试使用D3.js 创建一个可重复使用的图表对象。我已经设置了一个chart() 函数,它将生成一个柱形图。在任何列上的click 事件中,图表将使用新的随机数据数组进行更新,该数组将包含随机数量的数据点(即原始图表可能有 8 列,但更新后可能有 20 列或4 列)。

问题

假设我的原始数据集中有 8 个数据点(因此有 8 列)。当我用随机数据更新图表时,列会适当地将它们的高度调整为新值 - 但不会添加新条。此外,虽然列的宽度会适当调整以适应容器的宽度和新的数据点数量,但如果该数据点数量小于原始集,则原始数据集中的一些列将一直存在,直到数据点数大于或等于原始数据点数。

我的最终目标是动态添加新数据或动态删除新数据计数范围之外的旧数据。

我已经创建了一个jsfiddle 的行为。您可能需要多次单击这些列才能看到我所描述的行为。此外,我在下面粘贴了我的代码。

提前致谢!

function chart(config) {
    
    // set default options
    var defaultOptions = {
        selector: '#chartZone',
        class: 'chart',
        id: null,
        data: [1,2,6,4, 2, 6, 7, 2],
        type: 'column', 
        width: 200,
        height: 200,
        callback: null,
        interpolate: 'monotone'
    };

    // fill in unspecified settings in the config with the defaults
    var settings = $.extend(defaultOptions, config);
        
    function my() { // generate chart with this function        
    
        var w = settings.width,
            h = settings.height,
            barPadding = 3,
            scale = 10,
            max = d3.max(settings.data);        
    
        var svg = d3.select(settings.selector) // create the main svg container
            .append("svg")
            .attr("width",w)
            .attr("height",h);
    
        var y = d3.scale.linear().range([h, 0]),
            yAxis = d3.svg.axis().scale(y).ticks(5).orient("left"),
            x = d3.scale.linear().range([w, 0]);
                    
        y.domain([0, max]).nice();
        x.domain([0, settings.data.length - 1]).nice();        

        var rect = svg.selectAll("rect")
          .data(settings.data)
          .enter()
          .append("rect")
          .attr("x", function(d,i) {
            return i * (w / settings.data.length);
          })
          .attr("y", function(d) {
            return h - h * (d / max);
          })
          .attr("width", w / settings.data.length - barPadding)
          .attr("height", function(d) {
            return h * (d / max);
          })
          .attr("fill", "rgb(90,90,90)");
                      
        svg.append("svg:g")
           .attr("class", "y axis")
           .attr("transform", "translate(-4,0)")
           .call(yAxis);        
               
        svg.on("click", function() {
            var newData = [], maxCap = Math.round(Math.random() * 100);
                    
            for (var i = 0; i < Math.round(Math.random()*100); i++) {
                var newNumber = Math.random() * maxCap;
                newData.push(Math.round(newNumber));                
            }    
        
            newMax = d3.max(newData);
        
            y.domain([0, newMax]).nice();
        
            var t = svg.transition().duration(750);
        
            t.select(".y.axis").call(yAxis);
       
            rect.data(newData)
                 .transition().duration(750)
                 .attr("height", function(d) {
                    return h * (d / newMax);
                 })
                 .attr("x", function(d,i) {
                    return i * (w / newData.length);
                 })
                 .attr("width", w / newData.length - barPadding)
                 .attr("y", function(d) {
                    return h - h * (d / newMax);
                 });
            });
        }

    my();

    return my;

}

var myChart = chart();

【问题讨论】:

  • 我对 D3.js 不熟悉,但也许过渡设计为仅在条数不变的情况下才起作用。即只有高度可能会改变。

标签: javascript charts svg d3.js


【解决方案1】:

这里实际上发生了几件事 - 正如您所指出的,新数据范围之外的数据不会被删除,而且现有数据范围之外的新数据也不会被添加。这一切都与您在代码中修改的选择有关 - 您的更新函数应该使用 enter()exit() 选择来处理这些 - 请参阅 Thinking with Joins

这是一个更新的小提琴:http://jsfiddle.net/LPtTm/11/

【讨论】:

    猜你喜欢
    • 2013-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-01
    相关资源
    最近更新 更多