如何重新绘制D3条形图

时间:2017-07-18 22:52:45

标签: javascript d3.js

我想通过单选按钮选择值时更新条形图。此值作为查询的参数传递,以获取相应的JSON数据。

代码工作正常,不包括一个方面。当我通过单击任何单选按钮选择值时,条形图将绘制在现有条形图的顶部。我希望每次选择新选项时都重新绘制图表。

// set the dimensions of the canvas
var margin = {top: 20, right: 20, bottom: 70, left: 40},
    width = 600 - margin.left - margin.right,
    height = 300 - margin.top - margin.bottom;

// set the ranges
var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);

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

// define the axis
var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom")

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

var compSvg = d3.select(".company");

var companies = [];
d3.json("http://localhost:8983/solr/techproducts/select?q=popularity:[10%20TO%20*]&wt=json&fl=cat&facet=true&facet.field=cat", function(error, resp) {

    var results = resp.facet_counts.facet_fields.cat;
    for (var i = 0; i < 5; i++) {
        var value = results[i*2];
        companies.push(value);
    }
});


//functions for toggling between data
function change(value){
    update(value);
}

function update(comp){
    var query = 'cat:"' + comp + '"';

    var url = "http://localhost:8983/solr/techproducts/select?q=" + encodeURIComponent(query) + "&rows=10&fl=manu,price&wt=json"


    // load the data
    d3.json(url, function(error, resp) {

          if (error) return console.error(error);

          resp.response.docs.forEach(function(d) {
                d.manu = d.manu;
                d.price = +d.price;
          });

          // scale the range of the data
          x.domain(resp.response.docs.map(function(d) { return d.manu; }));
          y.domain([0, d3.max(resp.response.docs, function(d) { return d.price; })]);

          // add axis
          compSvg.append("g")
              .attr("class", "x axis")
              .attr("transform", "translate(0," + height + ")")
              .call(xAxis)
            .selectAll("text")
              .style("text-anchor", "end")
              .attr("dx", "-.8em")
              .attr("dy", "-.55em")
              .attr("transform", "rotate(-90)" );

          compSvg.append("g")
              .attr("class", "y axis")
              .call(yAxis)
            .append("text")
              .attr("transform", "rotate(-90)")
              .attr("y", 5)
              .attr("dy", ".71em")
              .style("text-anchor", "end")
              .text("Price");


          // Add bar chart
          compSvg.selectAll("bar")
              .data(resp.response.docs)
            .enter().append("rect")
              .attr("class", "bar")
              .attr("x", function(d) { return x(d.manu); })
              .attr("width", x.rangeBand())
              .attr("y", function(d) { return y(d.price); })
              .attr("height", function(d) { return height - y(d.price); });

    });

}

2 个答案:

答案 0 :(得分:2)

第一次加载图表时,一切都按预期工作:您有一个空选择,输入选择为数据数组中的每个项创建一个元素。你也追加轴。

使用change功能第二次加载图表时,首先重复您创建图表所做的操作:您有一个空选择,因为selectAll("bar")将为空,并且输入选择为数据数组中的每个项创建一个新元素。你也追加轴。

您需要使用更新和退出选择才能正常运行:

添加初始数据后,您需要使用更新选择来修改条形图,输入以引入新条形图(如果一个数据集使用的条形图比另一个更多),以及退出选择以退出不需要的条形图形(如果有数据集比另一个使用更少的条形图。在输入,更新,退出过程中有大量的在线信息;请记住,v4和v3之间存在差异。

这看起来像:

&#13;
&#13;
var data = [
  [1,2,3,4,5],
  [6,4,3],
  [5,10,1,7,1,3]
];

var i = 0;

var width = 500;
var height = 500;

var svg = d3.select("body")
  .append("svg")
  .attr("width",width)
  .attr("height",height);
  
var y = d3.scale.linear().range([height, 0]);
var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);


update(data[0]);
timer();

function update(dataset) {

  // update scales
  y.domain([0,d3.max(dataset, function(d) { return d; })] );
  x.domain(dataset.map(function(d,i) { return i; }) );
  
  // Bind Data
  var bars = svg.selectAll(".bars")
    .data(dataset);
    
  // Update existing bars:
  bars.transition()
    .attr("x",function(d,i) { return x(i); })
    .attr("y",function(d) { return y(d); })
    .attr("width", x.rangeBand() )
    .attr("height", function(d) { return height - y(d); })
    .duration(1000);
    
    
   // New Bars 
   bars.enter()
    .append("rect")
    .attr("class","bars")
    .attr("x",function(d,i) { return x(i); })
    .attr("width", x.rangeBand() )
    .attr("y",height)
    .attr("height",0)
    .transition() 
    .attr("y",function(d) { return y(d); })
    .attr("height", function(d) { return height - y(d); })
    .duration(1000);;
    
   // Un-needed Bars:
   bars.exit()
    .transition()
    .attr("height", 0)
    .duration(1000)
    .remove();
   
}

function timer() {
  setTimeout(function() { update(data[i++%3]); timer() } , 1500);
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:-1)

稍作修改可能会满足您的需求:

function change(value){
    // erase all contents before update
    compSvg.html("");
    update(value);
}