首页 > 解决方案 > 子图 d3 v4 的更新模式

问题描述

我正在开发一个 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>

标签: d3.js

解决方案


推荐阅读