Skip to content

Commit

Permalink
Fix drawing bugs (#27)
Browse files Browse the repository at this point in the history
* Fix bug of scaling of lines height when visual has small height
* Redesign drawing of lines between nodes by using 4 lines in one path element to create 'fillable' area
* Fix drawing link labels
  • Loading branch information
zBritva authored and ignatvilesov committed Sep 11, 2017
1 parent 05f07c0 commit 5b58ced
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 13 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.4.2

* Fix lines scaling issue when visual size is small

## 1.4.1

* Fix restoring settings when data set was filtered
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "powerbi-visuals-sankey",
"version": "1.4.1",
"version": "1.4.2",
"description": "Sankey is a type of flow diagram in which the width of the series is in proportion to the quantity of the flow. Use it to find major contributions to an overall flow.",
"repository": {
"type": "git",
Expand Down
4 changes: 2 additions & 2 deletions pbiviz.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"visual": {
"name": "SankeyDiagram",
"displayName": "Sankey 1.4.1",
"displayName": "Sankey 1.4.2",
"guid": "SankeyDiagram1446463184954",
"visualClassName": "SankeyDiagram",
"version": "1.4.1",
"version": "1.4.2",
"description": "Sankey is a type of flow diagram in which the width of the series is in proportion to the quantity of the flow. Use it to find major contributions to an overall flow.",
"supportUrl": "http://community.powerbi.com",
"gitHubUrl": "https://github.com/Microsoft/powerbi-visuals-sankey"
Expand Down
78 changes: 68 additions & 10 deletions src/visual.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ module powerbi.extensibility.visual {
private static MinHeightOfNode: number = 5;

private static ScaleStep: number = 0.1;
private static ScaleStepLimit: number = 10;
private static ScaleStepLimit: number = 1;

private static NegativeValueRange: number = 0;

Expand Down Expand Up @@ -881,7 +881,7 @@ module powerbi.extensibility.visual {
maxWeightInData = maxWeigthLink.weigth;
}

while (minHeight < SankeyDiagram.MinHeightOfNode && scaleStepCount < SankeyDiagram.ScaleStepLimit) {
while (minHeight <= SankeyDiagram.MinHeightOfNode && scaleStepCount < SankeyDiagram.ScaleStepLimit) {
let weightScale: any;

if (sankeyDiagramDataView.settings.scaleSettings.show) {
Expand Down Expand Up @@ -1375,6 +1375,10 @@ module powerbi.extensibility.visual {
// Update each link related with this node
node.links.forEach( (link: SankeyDiagramLink) => {
// select link svg element by ID generated in link creation as Source-Destination
d3.select(`#linkLabelPaths${(link.source.label.name || "").replace(/\W*/g,"")}-${(link.destination.label.name || "").replace(/\W*/g,"")}`).attr({
// get updated path params based on actual positions of node
d: sankeyVisual.getLinkLabelSvgPath(link)
});
d3.select(`#${(link.source.label.name || "").replace(/\W*/g,"")}-${(link.destination.label.name || "").replace(/\W*/g,"")}`).attr({
// get updated path params based on actual positions of node
d: sankeyVisual.getSvgPath(link)
Expand Down Expand Up @@ -1499,8 +1503,8 @@ module powerbi.extensibility.visual {
id: (link: SankeyDiagramLink) => `${(link.source.label.name || "").replace(/\W*/g,"")}-${(link.destination.label.name || "").replace(/\W*/g,"")}`
})
.style({
"stroke-width": (link: SankeyDiagramLink) => link.height < SankeyDiagram.MinWidthOfLink ? SankeyDiagram.MinWidthOfLink : link.height,
"stroke": (link: SankeyDiagramLink) => link.color
"stroke": (link: SankeyDiagramLink) => link.color,
"fill": (link: SankeyDiagramLink) => link.color
});

linksSelection
Expand Down Expand Up @@ -1544,9 +1548,9 @@ module powerbi.extensibility.visual {
linkLabelPathsSelection
.attr({
d: (link: SankeyDiagramLink) => {
return this.getSvgPath(link);
return this.getLinkLabelSvgPath(link);
},
id: (link: SankeyDiagramLink) => `${(link.source.label.name || "").replace(/\W*/g,"")}-${(link.destination.label.name || "").replace(/\W*/g,"")}`
id: (link: SankeyDiagramLink) => `linkLabelPaths${(link.source.label.name || "").replace(/\W*/g,"")}-${(link.destination.label.name || "").replace(/\W*/g,"")}`
});

linkLabelPathsSelection
Expand Down Expand Up @@ -1577,7 +1581,7 @@ module powerbi.extensibility.visual {
textPathSelection
.attr({
startOffset: "50%",
href: (link: SankeyDiagramLink) => `#${(link.source.label.name || "").replace(/\W*/g,"")}-${(link.destination.label.name || "").replace(/\W*/g,"")}`
href: (link: SankeyDiagramLink) => `#linkLabelPaths${(link.source.label.name || "").replace(/\W*/g,"")}-${(link.destination.label.name || "").replace(/\W*/g,"")}`
})
.style({
"font-size": this.dataView.settings.linkLabels.fontSize,
Expand All @@ -1596,7 +1600,35 @@ module powerbi.extensibility.visual {
.remove();
}

private getLinkLabelSvgPath(link: SankeyDiagramLink): string {
let x0: number,
x1: number,
xi: (t: number) => number,
x2: number,
x3: number,
y0: number,
y1: number;

if (link.destination.x < link.source.x) {
x0 = link.source.x;
x1 = link.destination.x + link.destination.width;
} else {
x0 = link.source.x + link.source.width;
x1 = link.destination.x;
}

xi = d3.interpolateNumber(x0, x1);
x2 = xi(this.curvatureOfLinks);
x3 = xi(1 - this.curvatureOfLinks);
y0 = link.source.y + link.dySource + link.height / SankeyDiagram.MiddleFactor;
y1 = link.destination.y + link.dyDestination + link.height / SankeyDiagram.MiddleFactor;

return `M ${x0} ${y0} C ${x2} ${y0}, ${x3} ${y1}, ${x1} ${y1}`;
}

private getSvgPath(link: SankeyDiagramLink): string {
let pathParams: string = "";

let x0: number,
x1: number,
xi: (t: number) => number,
Expand All @@ -1613,13 +1645,39 @@ module powerbi.extensibility.visual {
x1 = link.destination.x;
}

// drawing area as combination of 4 lines in one path element of svg to fill this area with required color
// upper border of link
xi = d3.interpolateNumber(x0, x1);
x2 = xi(this.curvatureOfLinks);
x3 = xi(1 - this.curvatureOfLinks);
y0 = link.source.y + link.dySource + link.height / SankeyDiagram.MiddleFactor;
y1 = link.destination.y + link.dyDestination + link.height / SankeyDiagram.MiddleFactor;
y0 = link.source.y + link.dySource + link.height / SankeyDiagram.MiddleFactor - link.height / 2;
y1 = link.destination.y + link.dyDestination + link.height / SankeyDiagram.MiddleFactor - link.height / 2;

return `M ${x0} ${y0} C ${x2} ${y0}, ${x3} ${y1}, ${x1} ${y1}`;
pathParams += ` M ${x0} ${y0} C ${x2} ${y0}, ${x3} ${y1}, ${x1} ${y1}`;

// right border of link
y0 = link.destination.y + link.dyDestination + link.height / SankeyDiagram.MiddleFactor + link.height / 2;
y1 = link.destination.y + link.dyDestination + link.height / SankeyDiagram.MiddleFactor - link.height / 2;

pathParams += ` L ${x1} ${y0}`;

// bottom border of link
xi = d3.interpolateNumber(x0, x1);
x2 = xi(this.curvatureOfLinks);
x3 = xi(1 - this.curvatureOfLinks);
y0 = link.source.y + link.dySource + link.height / SankeyDiagram.MiddleFactor + link.height / 2;
y1 = link.destination.y + link.dyDestination + link.height / SankeyDiagram.MiddleFactor + link.height / 2;

pathParams += ` L ${x1} ${y1} C ${x2} ${y1}, ${x3} ${y0}, ${x0} ${y0}`;

// left border of link
y0 = link.source.y + link.dySource + link.height / SankeyDiagram.MiddleFactor + link.height / 2;
y1 = link.source.y + link.dySource + link.height / SankeyDiagram.MiddleFactor - link.height / 2;

// close path to get closed area
pathParams += ` Z`;

return pathParams;
}

private renderTooltip(selection: Selection<SankeyDiagramNode | SankeyDiagramLink>): void {
Expand Down
4 changes: 4 additions & 0 deletions style/visual.less
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,15 @@
.link {
fill: none;
stroke-opacity: 0.2;
fill-opacity: 0.2;
stroke-width: 1;
}

.link:hover,
.link.selected {
stroke-opacity: 0.7;
fill-opacity: 0.7;
stroke-width: 1;
}
}
}

0 comments on commit 5b58ced

Please sign in to comment.