我的D3可视化在数据更改或调整窗口大小时会发生转换。 x和y轴也会转换,但我总是有一些代码没有典型的短D3风格:
示例(第一个代码块并不重要,只有在理解时才可见):
var x = d3.scale.linear().range([0, width]);
var xAxis = d3.svg.axis()
.scale(x)
.ticks(20)
.orient('bottom');
var svg = d3.select(containerSelector).select('svg');
if (svg.empty()) {
svg = d3.select(containerSelector).append('svg');
svg.append('g');
}
var group = svg
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.select('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
现在这是我要优化的代码:
var xAxisSvg = group.select('.x.axis');
if (xAxisSvg.empty()) {
group.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(0,' + height + ')')
.call(xAxis);
} else {
xAxisSvg.transition()
.duration(duration)
.attr('transform', 'translate(0,' + height + ')')
.call(xAxis);
}
是否有类似enter()
的方式来创建axis-svg并应用新的逻辑轴?如何优化这些重复代码?
答案 0 :(得分:1)
你可以通过只做最小的运行来缩短它:
var xAxisSvg = group.select('.x.axis');
if (xAxisSvg.empty()) {
xAxisSvg = group.append('g')
.attr('class', 'x axis');
}
xAxisSvg.transition()
.duration(duration)
.attr('transform', 'translate(0,' + height + ')')
.call(xAxis);
或者,您可以将一些虚拟数据绑定到它并使用输入/更新模式,但在这种情况下我不会考虑特别好的设计。
var xAxisSvg = group.selectAll('.x.axis').data([0]);
xAxisSvg.enter()
.append('g')
.attr('class', 'x axis');
xAxisSvg.transition()
.duration(duration)
.attr('transform', 'translate(0,' + height + ')')
.call(xAxis);