Skip to content

Commit 5b58ced

Browse files
zBritvaignatvilesov
authored andcommitted
Fix drawing bugs (#27)
* 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
1 parent 05f07c0 commit 5b58ced

5 files changed

Lines changed: 79 additions & 13 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 1.4.2
2+
3+
* Fix lines scaling issue when visual size is small
4+
15
## 1.4.1
26

37
* Fix restoring settings when data set was filtered

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "powerbi-visuals-sankey",
3-
"version": "1.4.1",
3+
"version": "1.4.2",
44
"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.",
55
"repository": {
66
"type": "git",

pbiviz.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
22
"visual": {
33
"name": "SankeyDiagram",
4-
"displayName": "Sankey 1.4.1",
4+
"displayName": "Sankey 1.4.2",
55
"guid": "SankeyDiagram1446463184954",
66
"visualClassName": "SankeyDiagram",
7-
"version": "1.4.1",
7+
"version": "1.4.2",
88
"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.",
99
"supportUrl": "http://community.powerbi.com",
1010
"gitHubUrl": "https://github.com/Microsoft/powerbi-visuals-sankey"

src/visual.ts

Lines changed: 68 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ module powerbi.extensibility.visual {
165165
private static MinHeightOfNode: number = 5;
166166

167167
private static ScaleStep: number = 0.1;
168-
private static ScaleStepLimit: number = 10;
168+
private static ScaleStepLimit: number = 1;
169169

170170
private static NegativeValueRange: number = 0;
171171

@@ -881,7 +881,7 @@ module powerbi.extensibility.visual {
881881
maxWeightInData = maxWeigthLink.weigth;
882882
}
883883

884-
while (minHeight < SankeyDiagram.MinHeightOfNode && scaleStepCount < SankeyDiagram.ScaleStepLimit) {
884+
while (minHeight <= SankeyDiagram.MinHeightOfNode && scaleStepCount < SankeyDiagram.ScaleStepLimit) {
885885
let weightScale: any;
886886

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

15061510
linksSelection
@@ -1544,9 +1548,9 @@ module powerbi.extensibility.visual {
15441548
linkLabelPathsSelection
15451549
.attr({
15461550
d: (link: SankeyDiagramLink) => {
1547-
return this.getSvgPath(link);
1551+
return this.getLinkLabelSvgPath(link);
15481552
},
1549-
id: (link: SankeyDiagramLink) => `${(link.source.label.name || "").replace(/\W*/g,"")}-${(link.destination.label.name || "").replace(/\W*/g,"")}`
1553+
id: (link: SankeyDiagramLink) => `linkLabelPaths${(link.source.label.name || "").replace(/\W*/g,"")}-${(link.destination.label.name || "").replace(/\W*/g,"")}`
15501554
});
15511555

15521556
linkLabelPathsSelection
@@ -1577,7 +1581,7 @@ module powerbi.extensibility.visual {
15771581
textPathSelection
15781582
.attr({
15791583
startOffset: "50%",
1580-
href: (link: SankeyDiagramLink) => `#${(link.source.label.name || "").replace(/\W*/g,"")}-${(link.destination.label.name || "").replace(/\W*/g,"")}`
1584+
href: (link: SankeyDiagramLink) => `#linkLabelPaths${(link.source.label.name || "").replace(/\W*/g,"")}-${(link.destination.label.name || "").replace(/\W*/g,"")}`
15811585
})
15821586
.style({
15831587
"font-size": this.dataView.settings.linkLabels.fontSize,
@@ -1596,7 +1600,35 @@ module powerbi.extensibility.visual {
15961600
.remove();
15971601
}
15981602

1603+
private getLinkLabelSvgPath(link: SankeyDiagramLink): string {
1604+
let x0: number,
1605+
x1: number,
1606+
xi: (t: number) => number,
1607+
x2: number,
1608+
x3: number,
1609+
y0: number,
1610+
y1: number;
1611+
1612+
if (link.destination.x < link.source.x) {
1613+
x0 = link.source.x;
1614+
x1 = link.destination.x + link.destination.width;
1615+
} else {
1616+
x0 = link.source.x + link.source.width;
1617+
x1 = link.destination.x;
1618+
}
1619+
1620+
xi = d3.interpolateNumber(x0, x1);
1621+
x2 = xi(this.curvatureOfLinks);
1622+
x3 = xi(1 - this.curvatureOfLinks);
1623+
y0 = link.source.y + link.dySource + link.height / SankeyDiagram.MiddleFactor;
1624+
y1 = link.destination.y + link.dyDestination + link.height / SankeyDiagram.MiddleFactor;
1625+
1626+
return `M ${x0} ${y0} C ${x2} ${y0}, ${x3} ${y1}, ${x1} ${y1}`;
1627+
}
1628+
15991629
private getSvgPath(link: SankeyDiagramLink): string {
1630+
let pathParams: string = "";
1631+
16001632
let x0: number,
16011633
x1: number,
16021634
xi: (t: number) => number,
@@ -1613,13 +1645,39 @@ module powerbi.extensibility.visual {
16131645
x1 = link.destination.x;
16141646
}
16151647

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

1622-
return `M ${x0} ${y0} C ${x2} ${y0}, ${x3} ${y1}, ${x1} ${y1}`;
1656+
pathParams += ` M ${x0} ${y0} C ${x2} ${y0}, ${x3} ${y1}, ${x1} ${y1}`;
1657+
1658+
// right border of link
1659+
y0 = link.destination.y + link.dyDestination + link.height / SankeyDiagram.MiddleFactor + link.height / 2;
1660+
y1 = link.destination.y + link.dyDestination + link.height / SankeyDiagram.MiddleFactor - link.height / 2;
1661+
1662+
pathParams += ` L ${x1} ${y0}`;
1663+
1664+
// bottom border of link
1665+
xi = d3.interpolateNumber(x0, x1);
1666+
x2 = xi(this.curvatureOfLinks);
1667+
x3 = xi(1 - this.curvatureOfLinks);
1668+
y0 = link.source.y + link.dySource + link.height / SankeyDiagram.MiddleFactor + link.height / 2;
1669+
y1 = link.destination.y + link.dyDestination + link.height / SankeyDiagram.MiddleFactor + link.height / 2;
1670+
1671+
pathParams += ` L ${x1} ${y1} C ${x2} ${y1}, ${x3} ${y0}, ${x0} ${y0}`;
1672+
1673+
// left border of link
1674+
y0 = link.source.y + link.dySource + link.height / SankeyDiagram.MiddleFactor + link.height / 2;
1675+
y1 = link.source.y + link.dySource + link.height / SankeyDiagram.MiddleFactor - link.height / 2;
1676+
1677+
// close path to get closed area
1678+
pathParams += ` Z`;
1679+
1680+
return pathParams;
16231681
}
16241682

16251683
private renderTooltip(selection: Selection<SankeyDiagramNode | SankeyDiagramLink>): void {

style/visual.less

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,15 @@
5959
.link {
6060
fill: none;
6161
stroke-opacity: 0.2;
62+
fill-opacity: 0.2;
63+
stroke-width: 1;
6264
}
6365

6466
.link:hover,
6567
.link.selected {
6668
stroke-opacity: 0.7;
69+
fill-opacity: 0.7;
70+
stroke-width: 1;
6771
}
6872
}
6973
}

0 commit comments

Comments
 (0)