子图d3 v4的更新模式

时间:2018-07-18 16:07:49

标签: d3.js

我正在一个d3项目中,该项目具有多个具有更新数据的子图。我在下面有一个可行的示例,但我认为我可能会使update()模式复杂化了。我之所以没有加入exit()是因为数据是一致的(总是有相同数量的部门,团队和价值观)。

d3专家:这对您来说合适吗?您将进行哪些修改以使其性能更高/更易于维护?我应该为图表的每个组件调用一个函数吗?例如创建分部图的功能,组图的功能,条形图的功能等。

我有兴趣学习如何编写干净的可维护d3代码,因此,请尽可能传递任何资源。

谢谢!

const dataset1 = [
 {"division": "division 1", "team": "team 1", "value": 5},
 {"division": "division 1", "team": "team 1", "value": 7},
 {"division": "division 1", "team": "team 1", "value": 9},
 {"division": "division 1", "team": "team 2", "value": 2},
 {"division": "division 1", "team": "team 2", "value": 1},
 {"division": "division 1", "team": "team 2", "value": 1},
 {"division": "division 1", "team": "team 3", "value": 3},
 {"division": "division 1", "team": "team 3", "value": 1},
 {"division": "division 1", "team": "team 3", "value": 7},
 {"division": "division 2", "team": "team 1", "value": 2},
 {"division": "division 2", "team": "team 1", "value": 7},
 {"division": "division 2", "team": "team 1", "value": 3},
 {"division": "division 2", "team": "team 2", "value": 6},
 {"division": "division 2", "team": "team 2", "value": 3},
 {"division": "division 2", "team": "team 2", "value": 2},
 {"division": "division 2", "team": "team 3", "value": 3},
 {"division": "division 2", "team": "team 3", "value": 9},
 {"division": "division 2", "team": "team 3", "value": 5},
]

const dataset2 = [
 {"division": "division 1", "team": "team 1", "value": 1},
 {"division": "division 1", "team": "team 1", "value": 4},
 {"division": "division 1", "team": "team 1", "value": 3},
 {"division": "division 1", "team": "team 2", "value": 6},
 {"division": "division 1", "team": "team 2", "value": 2},
 {"division": "division 1", "team": "team 2", "value": 9},
 {"division": "division 1", "team": "team 3", "value": 5},
 {"division": "division 1", "team": "team 3", "value": 2},
 {"division": "division 1", "team": "team 3", "value": 3},
 {"division": "division 2", "team": "team 1", "value": 8},
 {"division": "division 2", "team": "team 1", "value": 1},
 {"division": "division 2", "team": "team 1", "value": 2},
 {"division": "division 2", "team": "team 2", "value": 5},
 {"division": "division 2", "team": "team 2", "value": 3},
 {"division": "division 2", "team": "team 2", "value": 7},
 {"division": "division 2", "team": "team 3", "value": 4},
 {"division": "division 2", "team": "team 3", "value": 3},
 {"division": "division 2", "team": "team 3", "value": 8},
]

function updateChart(data) {
  
  // Divisions
  var divisions = d3.nest().key(d=>d.division).entries(data); 
  var divisionCharts = d3.select("body").selectAll("svg").data(divisions, d=>d.key);
  var divisionChartsEnter = divisionCharts.enter().append("svg").attr("width", 200).attr("height", 75);
  
  // Teams
  var teamCharts = divisionCharts.merge(divisionChartsEnter).selectAll("svg")
    .data(d => d3.nest().key(d=>d.team).entries(d.values), d=>d.key)
  var teamChartsEnter = teamCharts.enter().append("svg").attr("x", (d,i) => i*50);
  
  // Values for each team
  var bars = teamCharts.merge(teamChartsEnter).selectAll("rect").data(d => d.values);
  var barsEnter = bars.enter()
    .append("rect")
    .attr("x", (d,i)=>i*12)
    .attr("width", 10)
  bars.merge(barsEnter)
    .transition()
    .attr("height", d=>d.value*10)
  
  // Toggle dataset
  currDataset = data == dataset1 ? dataset2 : dataset1;
}

let currDataset = dataset1;
updateChart(currDataset);

d3.select("#updateData").on("click", () => updateChart(currDataset))
<p><button id="updateData">Update Data</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>

0 个答案:

没有答案