D3.js:动态更改条形图

时间:2016-05-23 14:49:51

标签: javascript d3.js

我现在已经尝试了很多D3.js而且我有这个条形图,我必须在点击按钮时动态刷新。

我把它包装在一个函数中,然而,这似乎不起作用。

问题是什么?如何解决?

代码:

<button onclick="updateChart('JB')">JB</button>

我从我的html文件中调用它。 例如:

month   popularity
January 24.6
February    26.2
March   28.4
April   30.9
May 32.9
June    32.4
July    30.7
August  30.1 
September   29.7
October 28.2
November    26.1
December    25

原始数据:

month   popularity
January 73
February    72
March   70
April   69
May 62
June    57
July    64
August  66
September   72
October 77
November    78
December    77

更新:

mainWindow

2 个答案:

答案 0 :(得分:1)

乍一看我可以看到2个问题:

  • 您只能在enter选择中进行转换:
// pops only contains the 'enter selection' (=new elements)
var pops= svg.selectAll(".bar")
      .data(data)
    .enter().append("rect")

// So the transition will be only on the 'enter selection'
pops.transition()...  

您应该分两步完成:

// pops now contains the 'update selection' (=existing elements)
  var pops= svg.selectAll(".bar")
      .data(data);
// 'enter().append' creates elements but also add them automatically to the 'update selection'
  pops.enter().append("rect");

// Here attributes will apply on the 'enter + update selection' (=all elements)
  pops.attr("width", x)
      .attr("fill", function(d) {
        if (d.popularity> 30) {
           return "#010";
        else  
           return "000"; 
       })
      .attr("class", "bar")
      .attr("x", function(d) { return x(d.month); })
      .attr("width", x.rangeBand())
      .attr("y", height - 1)
      .attr("height", 1);
  • 您正在每次更新时重新创建轴

您应该创建一次,并在updateChart

中更新动态值

启动时:

var x = d3.scale.ordinal()
    .rangeRoundBands([0, width], .1);

var y = d3.scale.linear()
    .range([height, 0]);

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom");

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left")
    .ticks(10)
    .tickFormat(d3.format("s"));

var gXAxis = svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis);

var gYAxis =  svg.append("g")
      .attr("class", "y axis")
      .call(yAxis);

更新时间:

// Update domains
x.domain(data.map(function(d) { return d.month; }));
y.domain([0, 45]);
// Update axis
gXAxis.call(xAxis);
gYAxis.call(yAxis);
// You could even handle it smoothly via a transition: 
// gXAxis.transition().call(xAxis);
// gYAxis.transition().call(yAxis);

答案 1 :(得分:-1)

首先,您需要在输入数据时设置ID:

var pops= svg.selectAll(".bar")
  .data(data, function(d,i){ return d.month; // this value most be an Id for each node })
pops.enter().append("rect"); // newest nodes
update(); // updates nodes 
pops.exit().remove(); // remove exits nodes

然后你需要在更新viz的所有值时创建一个函数

function update(){
   pops
    .attr("width", x)
    .attr("fill", "#010")
    .attr("class", "bar")
    .attr("x", function(d) { return x(d.month); })
    .attr("width", x.rangeBand())
    .attr("y", height - 1)
    .attr("height", 1);
}

这是了解数据输入和更新之间差异的示例。设置&#34; .data(数据,函数(d,i){return d.ID;})&#34;非常重要。给予d3期货更新的ID。