d3分组的条形图更新模式不起作用 [英] d3 grouped bar chart update pattern not working

查看:43
本文介绍了d3分组的条形图更新模式不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想掌握这一点已经有几天了.我也一直在寻找类似的问题,但到目前为止没有任何进展.

It's been few days already while I'm trying to grasp this. I was also looking into similar questions with no progress so far.

我有一个简单的分组条形图.我能够第一次绘制它,但是更新失败.如果我尝试使图表进行自我更新,它只会添加新数据.

I have a simple grouped bar chart. I am able to draw it for the first time but no success in updating it. If I try to make the chart to update itself it just adds new data.

我认为问题出在内部选择组的数据推导中.

I imagine the issue is somewhere in data derivation for inner selection groups.

代码:

// .chart -> .group -> .bar
// each group has 2 bars: one for data 'in' and another for 'out'
var data = [
  { "in" : 0, "out" : 40 },
  { "in" : 10, "out" : 39 },
  { "in" : 20, "out" : 40 }
];

var chart = d3.select('.chart');
var groupsSelection = chart.selectAll('.group');
var xScale = d3.scaleLinear().range([0, 666]);

function draw(data) {
    // make data flat array of numbers to find max value for xScale domain
  var dataValues = data.reduce(
    (result, currentVal) => result.concat([currentVal.in, currentVal.out]), 
    []
  );
  // set x axis domain
  xScale.domain([0, d3.max(dataValues)]);

    var groupsUpdate = groupsSelection.data(data);

  // groups
  var groups = groupsUpdate.enter()
      .append('div')
        .attr('class', 'group')
      .merge(groupsUpdate);

  // derive data from parent group
  var barsUpdate = groups.selectAll('.bar')
    .data(d => [d.in, d.out]);

  var bars = barsUpdate.enter()
    .append('div')
      .attr('class', 'bar')
    .merge(barsUpdate)
      .text(d => d)
        .style('background', 'pink')
      .style('width', d => xScale(d) + 'px');

  barsUpdate.exit().remove();

  // groups exit
  groupsUpdate.exit().remove();
}

// 1st time draw
draw(data)

// delayed data update (2nd draw)
setTimeout(() => {
    var newData = [
    { "in" : 0, "out" : 40 },
    { "in" : 20, "out" : 40 }
  ];
  draw(newData);
}, 1000);

JSFiddle: https://jsfiddle.net/0d7665nc/10/

JSFiddle: https://jsfiddle.net/0d7665nc/10/

推荐答案

在您的draw函数内部,而不是:

Inside your draw function, instead of:

var groupsUpdate = groupsSelection.data(data);

应该是:

var groupsUpdate = chart.selectAll('.group').data(data);

或者,或者,移动变量分配...

Or, alternatively, move the variable assignment...

var groupsSelection = chart.selectAll('.group');

...到draw内部.

这样做的原因是groupsSelection是在附加任何组之前定义的,并且是空选择.

The reason for this is that groupsSelection was defined before any group being appended, and it is an empty selection.

这是您的代码,仅包含此更改:

Here is your code with that change only:

// .chart -> .group -> .bar
// each group has 2 bars: one for data 'in' and another for 'out'
var data = [{
  "in": 0,
  "out": 40
}, {
  "in": 10,
  "out": 39
}, {
  "in": 20,
  "out": 40
}];

var chart = d3.select('.chart');
var groupsSelection = chart.selectAll('.group');
var xScale = d3.scaleLinear().range([0, 666]);

function draw(data) {
  // make data flat array of numbers to find max value for xScale domain
  var dataValues = data.reduce(
    (result, currentVal) => result.concat([currentVal.in, currentVal.out]), []
  );
  // set x axis domain
  xScale.domain([0, d3.max(dataValues)]);

  var groupsUpdate = chart.selectAll('.group').data(data);

  // groups
  var groups = groupsUpdate.enter()
    .append('div')
    .attr('class', 'group')
    .merge(groupsUpdate);

  // derive data from parent group
  var barsUpdate = groups.selectAll('.bar')
    .data(d => [d.in, d.out]);

  var bars = barsUpdate.enter()
    .append('div')
    .attr('class', 'bar')
    .merge(barsUpdate)
    .text(d => d)
    .style('background', 'pink')
    .style('width', d => xScale(d) + 'px');

  barsUpdate.exit().remove();

  // groups exit
  groupsUpdate.exit().remove();
}

// 1st time draw
draw(data)

// delayed data update (2nd draw)
setTimeout(() => {
  var newData = [{
    "in": 0,
    "out": 40
  }, {
    "in": 20,
    "out": 40
  }];
  draw(newData);
}, 1000);

.chart {
  background: #fff;
  width: 686px;
  padding: 20px;
}

.group {
  background: grey;
  padding: 10px;
  border: solid 1px #000;
  margin: 10px 0;
}

.bar {
  background: white;
  margin: 5px 0;
  height: 20px;
  border: solid 1px yellow;
  font-size: 16px;
  line-height: 20px;
  text-indent: 10px;
  color: white;
  font-weight: bold;
  text-shadow: 0 1px 1px #000;
}

<script src="https://d3js.org/d3.v4.min.js"></script>
<div class="chart"></div>

这篇关于d3分组的条形图更新模式不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆