2017-10-14 58 views
2

我已经上传了block(固定),您可以切换排序功能。如何自动排序一个条形图与切换功能

现在我想添加的是某种if语句,当复选框打开时,当它打开时,我希望酒吧在您更改年份或类别时自动排序,并且当您再次切换时停止自动-sorting。

我想到了一个简单的

if (document.getElementsByClassName('myCheckbox').checked) { 
    change(); 
} 

update功能会工作,但没有任何反应。

任何帮助表示赞赏!

+0

由于'getElementsByClassName'返回一个列表,它必须是:'如果(document.getElementsByClassName(“myCheckbox”)[0 ] .checked){etc ...',以'[0]'作为索引。但是,我不会将此作为答案发布,因为您必须重构“更改”功能才能使其工作。 –

+0

我知道,为了使它工作,您需要更改多少代码?如果有帮助,我可以发布一个更简单的例子。 –

+0

我添加了一个答案,但我很快就会将其删除:排序工作不正常。请在删除之前复制答案的详细信息。 –

回答

1

我开始回答你的直接问题,但很快就意识到你的代码需要一点重构。你有太多的复制/粘贴冗余代码和绘制太多东西。当使用d3进行编码时,您应该尝试执行所有绘图的单个功能。

这是code running

这里是新的更新功能的片段来统治他们:

function update() { 

    file = d3.select('#year').property('value') == 'data2017' ? 'data.csv' : 'data2.csv'; 
    catInt = d3.select('#category').property('value'); 

    d3.csv(file, type, function(error,data) { 

     if(error) throw error; 

     var sortIndex = data.map(function(d){ return d.month}); 

     // Update domain 
     y.domain([0, d3.max(data, function(d) { 
       return d["Category" + catInt]; }) 
     ]).nice(); 

     // Update axis 
     g.selectAll(".axis.axis--y").transition() 
      .duration(750) 
      .call(yAxis); 
     g.selectAll(".axis.grid--y").transition() 
      .duration(750) 
      .call(yGrid); 

     // Sums and averages 
     let sumOfAll = d3.sum(data, function(d) { 
      return d["Category" + catInt]; 
     }); 
     let avgValue = d3.sum(data, function(d) { 
      return d["Category" + catInt]; 
     })/data.length; 

     //sort data 
     data.sort(d3.select("#myCheckbox").property("checked") 
      ? function(a, b) { return b["Category" + catInt] - a["Category" + catInt]; } 
      : function(a, b) { return sortIndex.indexOf(a.month) - sortIndex.indexOf(b.month);}) 

     // set x domain 
     x.domain(data.map(function(d) { return d.month; })); 

     g.selectAll(".axis.axis--x").transition() 
     .duration(750) 
     .call(xAxis); 

     // Update rectangles 
     let bars = g.selectAll(".barEnter") 
      .data(data, function(d){ 
      return d.month; 
      }); 

     bars = bars 
      .enter() 
      .append("rect") 
      .attr("class", "barEnter") // Enter data reference 
      .attr("width", x.bandwidth()) 
      .merge(bars); 

     bars.transition() 
      .duration(750) 
      .attr("height", function(d) { 
      return height - y(d["Category" + catInt]); 
      }) 
      .attr("x", function(d) { 
      return x(d.month); 
      }) 
      .attr("y", function(d) { 
      return y(d["Category" + catInt]); 
      }); 

    bars.exit().remove(); 

     // Update text on rectangles 
     let textUpdate = g.selectAll(".textEnter") 
      .data(data, function(d){ 
      return d.month; 
      }); 

     textUpdate = textUpdate.enter() 
     .append("text") 
     .style("text-shadow","1px 1px #777") 
     .attr("class", "textEnter") // Enter data reference 
     .attr("text-anchor","middle") 
     .attr("font-size",11) 
     .attr("fill","#fff") 
     .merge(textUpdate); 

     textUpdate.transition() 
      .duration(750) 
      .attr("y", function(d) { 
       return y(d["Category" + catInt]) + 15; 
       }) 
      // Update text value 
      .text(function(d) { 
       return d["Category" + catInt]; 
      }) 
      .attr("x", function(d) { 
      return x(d.month) + x.bandwidth()/2; 
     }) 

     // Update sum and avg value 
     g.selectAll("#totalValue").transition() 
      .duration(750) 
      .text(sumOfAll + " Category " + catInt) 
     g.selectAll("#avgValue").transition() 
      .duration(750) 
      .text(formatValue(avgValue)) 
    }); 
} 
+0

非常感谢!我更新了我的[Block](https://bl.ocks.org/LemoNode/73dbb9d6a144476565386f48a2df2e3b)并将条件运算符更改为if语句,这是否会使代码变得冗余?多重三元评估仍然更可取? (如果你想添加另一个csv文件) –

+1

@RobertAndersson,不,你的if语句是好的。对于更多的两个选项,我会使用一个嵌套三元组。 – Mark