我正在学习视频教程(https://channel9.msdn.com/Blogs/Azure/Building-Power-BI-custom-visuals-that-meet-your-app-needs)在Power BI.中创建条形图(自定义视觉(
代码片段(在13.40的视频中(:
let bars = this.barContainer.selectAll('.bar').data(viewModel.dataPoints);
bars.enter().append('rect').classed('bar', true);
bars
.attr('width', xScale.bandwidth())
.attr('height', d => height - yScale(d.value))
.attr('y', d => yScale(d.value))
.attr('x', d => xScale(d.category));
bars.exit().remove();
以上代码是用visual.ts
文件的更新方法编写的。
根据我的理解,enter()
方法将基于viewModel.dataPoints
数据创建类为bar
的rect
元素。
问题是我无法使其在初始加载时工作,当加载视觉时,此仅在调整视觉大小后工作。在加载时,我看不到任何属性被应用到rect
元素上,但当在视觉上调整大小时,它会被应用。
如果我将代码更改为:
bars.enter().append('rect').classed('bar', true)
.attr('width', xScale.bandwidth())
.attr('height', d => height - yScale(d.value))
.attr('y', d => yScale(d.value))
.attr('x', d => xScale(d.category));
bars.transition()
.attr('width', xScale.bandwidth())
.attr('height', d => height - yScale(d.value))
.attr('y', d => yScale(d.value))
.attr('x', d => xScale(d.category));
bars.exit().remove();
上面的代码运行良好,属性被应用于初始加载和调整大小。
附加信息(构造函数代码(
let svg = this.svg = d3.select(options.element).append('svg').classed('barChart', true);
this.barContainer = svg.append('g').classed('barContainer', true);
this.xAxis = svg.append('g').classed('xAxis', true);
这是它在最新版本(D3 Js 5.0(中的工作方式吗?或者我做错了什么?
.merge()
函数可以实现此功能。
解决方案是:
let bars = this.barContainer.selectAll('.bar').data(viewModel.dataPoints);
const a = bars.enter().append('rect').merge(<any>bars); // merge before attr()
a.classed('bar', true);
a
.transition().duration(50)
.attr('width', xScale.bandwidth())
.attr('height', d => height - yScale(d.value))
.attr('y', d => yScale(d.value))
.attr('x', d => xScale(d.category)); // This code now works for initial
// load and update.
bars.exit().remove();
这将帮助您完成合并。如果您想在d3.js v5中使用新的联接方法,底部有一个链接。
https://www.codementor.io/@milesbryony/d3-js-merge-in-depth-jm2phurw
或者更复杂的用途请参见Mike Bostock的
https://observablehq.com/@d3/选择加入