I'm currently working on developing a horizontal hierarchical tree Power BI custom visual using TypeScript and D3. I am utilizing d3's treeLayout for this purpose, and my task is to create a link generator that can plot bezier, step, and diagonal links based on the user's choice.
The challenge I face is related to the nodes being rectangles with specific widths, which require the links to go from (source.x + width/2, y) to (target.x - width/2, y). While I have successfully implemented this for diagonal and step options using the d3.line() function, I have encountered difficulties with the bezier option and the linkHorizontal function. Despite reading through the documentation and examining the d3 code extensively, I haven't been able to utilize the source, target, and context functions effectively.
Below is a simplified version of my current code:
- this.settings.links.style determines the selected link style: "bezier", "curve", or "step"
- this.settings.nodes.width specifies the node width
- this.orientation.x maps x and y functions as demonstrated in Bostock's https://bl.ocks.org/mbostock/3184089
const linkH = d3.linkHorizontal().x(d => this.orientation.x(d)).y(d => this.orientation.y(d));
let linkGenerator = this.settings.links.style == "bezier" ? linkH
:
(this.settings.links.style == "step" ?
d => d3.line().curve(d3.curveStep)([[this.orientation.x(d.source) + this.settings.nodes.width / 2, this.orientation.y(d.source)],
[this.orientation.x(d.target) - this.settings.nodes.width / 2, this.orientation.y(d.target)]])
:
d => d3.line()([[this.orientation.x(d.source) + this.settings.nodes.width / 2, this.orientation.y(d.source)],
[this.orientation.x(d.target) - this.settings.nodes.width, this.orientation.y(d.target)]])
)
var links = linkGroup.selectAll("path")
.data(this.viewModel.hierarchy.links())
.enter()
.append("path")
.attr("d", linkGenerator);