动态更新d3条形图

时间:2016-11-13 07:19:21

标签: javascript d3.js

此功能在页面加载时运行,也在表单中输入数据时运行。它会在页面加载时绘制图表,但在提交新信息时不会重绘。

当我在数据连接之后记录元素时,它会显示数据数组的更新长度和更新的元素数,但它们不会重绘。任何想法,只是扫描这段代码?我觉得它很接近,但我不了解数据更新过程的步骤。

这是基于基本条形图教程let's make a bar chart,它使用div而不是svg元素,但我认为这不重要。

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<div id="body">
    
<h3>Table 1</h3>

    <table class="myTable">
        <tr>
            <td>As You Like It</td>
            <td>Comedy</td>
            <td>1600</td>
        </tr>
        <tr>
            <td>All's Well that Ends Well</td>
            <td>Comedy</td>
            <td>1601</td>
        </tr>
        <tr>
            <td>Hamlet</td>
            <td>Tragedy</td>
            <td>1604</td>
        </tr>
        <tr>
            <td>Macbeth</td>
            <td>Tragedy</td>
            <td>1606</td>
        </tr>
        <tr>
            <td>Romeo and Juliet</td>
            <td>Tragedy</td>
            <td>1595</td>
        </tr>
    </table>
    
<h3>Table 2</h3>

    <table class="myTable">
        <tr>
            <td>Hamlet</td>
            <td>Tragedy</td>
            <td>1604</td>
        </tr>
        <tr>
            <td>Macbeth</td>
            <td>Tragedy</td>
            <td>1606</td>
        </tr>
        <tr>
            <td>Romeo and Juliet</td>
            <td>Tragedy</td>
            <td>1595</td>
        </tr>
    </table>
</div>

编辑:尝试使用.merge()和.each()来创建和更新图表。我无法弄清楚如何动态更新每个条形图是一个包含两个实际显示数据的子div的div。这仍然不能动态工作,虽然它呈现如上所示:

this.render = function(self){
  if(self.data){
    self.x = d3.scaleLinear()
               .domain([0, d3.max(self.data.map(function(d) {
                   return parseInt(d.daily_count);
                 }))
               ])
               .range([0, 500]);

    var bars = d3.select("#chart")
                 .selectAll("div")
                 .data(self.data)
                 .enter().append('div')
                   .attr('class', 'bar-container row');

    console.log('chart', d3.select("#chart").data(self.data));

    bars.append('div')
          .attr('class', 'label four columns')
          .text(function(d) {return d.date_string; });

    bars.append("div")
          .attr('class', 'bar eight columns')
          .style('background-color', function(d){
            return (d.daily_count == 0 ? 'white' : '#1EAEDB')
          })
          .style('color', function(d){
            return (d.daily_count == 0 ? 'red' : 'white')
          })
          .style("width", function(d) {
            return self.x(d.daily_count) + "px";
          })
          .text(function(d) {
            return (d.daily_count == 0 ? 'closed' : d.daily_count)
          });
  }

1 个答案:

答案 0 :(得分:1)

您的render功能需要正确的“输入”,“更新”和“退出”选项。除此之外,请记住,您链接的Bostock示例使用d3版本3.x,而您使用的是d3版本4.x.

在以下演示中,这将绑定数据:

var bars = body.selectAll("div")
    .data(data);

之后,使用merge

进行“输入”+“更新”选择
bars.enter().append("div")
    .attr("class", "row")
    .merge(bars)
    .style('background-color', function(d){
        return (d.daily_count == 0 ? 'white' : '#1EAEDB')
    })
    .style('color', function(d){
        return (d.daily_count == 0 ? 'red' : 'white')
    })
    .style("width", function(d) {
        return x(d.daily_count) + "px";
    })
    .text(function(d) {
        return (d.daily_count == 0 ? 'closed' : d.daily_count)
    });

退出选择:

bars.exit().remove();

这是一个基于你的代码的演示(仅使用daily_count,因为我不知道你如何定位其他div):

var dataset = [{daily_count: 19},
{daily_count: 29},
{daily_count: 13},
{daily_count: 45},
{daily_count: 22},
{daily_count: 42},
{daily_count: 9}];

render(dataset)

d3.select("#btn").on("click", function(){
	var newDataset = [];
	var length = Math.ceil(Math.random()*20);
	for (var i = 0; i < length; i++){
		newDataset.push({daily_count: Math.floor(Math.random()*50)})
	}
	render(newDataset);
})

function render(data){

    x = d3.scaleLinear()
               .domain([0, d3.max(data.map(function(d) {
                   return parseInt(d.daily_count);
                 }))
               ])
               .range([0, 300]);
							 
		var body = d3.select("body");

    var bars = body.selectAll("div")
                 .data(data);

    bars.enter().append("div")
		 .attr("class", "row")
          .merge(bars)
          .style('background-color', function(d){
            return (d.daily_count == 0 ? 'white' : '#1EAEDB')
          })
          .style('color', function(d){
            return (d.daily_count == 0 ? 'red' : 'white')
          })
          .style("width", function(d) {
            return x(d.daily_count) + "px";
          })
          .text(function(d) {
            return (d.daily_count == 0 ? 'closed' : d.daily_count)
          });
					
		bars.exit().remove();

}
.row {
  font: 10px sans-serif;
  text-align: right;
  padding: 3px;
  margin: 2px;
  color: white;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<button id="btn">Click</button>