Skip to content

Commit

Permalink
Draw label for links as "Source-Destination:Value" (#22)
Browse files Browse the repository at this point in the history
* Draw label for links as "Source-Destination:Value"
* UT for link data labels feature
* Increase version number. Update CHANGELOG
* Fix tslint issues
* Fix generating id for svg node
* Code refactoring
  • Loading branch information
zBritva authored and ignatvilesov committed Aug 16, 2017
1 parent 8370f5d commit 28a87a5
Show file tree
Hide file tree
Showing 7 changed files with 158 additions and 6 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.3.0

* Add link data labels displaying

## 1.2.7

* Fix scale settings text.
Expand Down
33 changes: 33 additions & 0 deletions capabilities.json
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,39 @@
}
}
},
"linkLabels": {
"displayName": "Data link labels",
"displayNameKey": "Visual_DataPointsLinkLabels",
"properties": {
"show": {
"displayName": "Show",
"displayNameKey": "Visual_Show",
"type": {
"bool": true
}
},
"fill": {
"displayName": "Color",
"displayNameKey": "Visual_LabelsFill",
"type": {
"fill": {
"solid": {
"color": true
}
}
}
},
"fontSize": {
"displayName": "Text Size",
"displayNameKey": "Visual_TextSize",
"type": {
"formatting": {
"fontSize": true
}
}
}
}
},
"links": {
"displayName": "Links",
"displayNameKey": "Visual_Links",
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.2.7",
"version": "1.3.0",
"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",
"displayName": "Sankey 1.3.0",
"guid": "SankeyDiagram1446463184954",
"visualClassName": "SankeyDiagram",
"version": "1.2.7",
"version": "1.3.0",
"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
9 changes: 9 additions & 0 deletions src/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ module powerbi.extensibility.visual {
public minHeightOfNode: number = 10;
}

export class SankeyDiagramLinkLabelsSettings {
public static DefaultFontSize: number = 12;
public show: boolean = false;
public fill: string = "black";
public fontSize: number = SankeyDiagramLabelsSettings.DefaultFontSize;
public minHeightOfNode: number = 10;
}

export class SankeyDiagramScaleSettings {
public x: number = 1;
public y: number = 1;
Expand All @@ -47,6 +55,7 @@ module powerbi.extensibility.visual {
}

export class SankeyDiagramSettings extends DataViewObjectsParser {
public linkLabels: SankeyDiagramLinkLabelsSettings = new SankeyDiagramLinkLabelsSettings();
public labels: SankeyDiagramLabelsSettings = new SankeyDiagramLabelsSettings();
public _scale: SankeyDiagramScaleSettings = new SankeyDiagramScaleSettings();
public scaleSettings: SankeyLnScaleSettings = new SankeyLnScaleSettings();
Expand Down
87 changes: 87 additions & 0 deletions src/visual.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ module powerbi.extensibility.visual {

private static LinksSelector: ClassAndSelector = createClassAndSelector("links");
private static LinkSelector: ClassAndSelector = createClassAndSelector("link");
private static LinkLabelPathsSelector: ClassAndSelector = createClassAndSelector("linkLabelPaths");
private static LinkLabelTextsSelector: ClassAndSelector = createClassAndSelector("linkLabelTexts");

private static DefaultColourOfNode: string = "rgb(62, 187, 162)";
private static DefaultColourOfLink: string = "black";
Expand Down Expand Up @@ -1115,6 +1117,7 @@ module powerbi.extensibility.visual {
linksSelection: Selection<SankeyDiagramLink>;

linksSelection = this.renderLinks(sankeyDiagramDataView);
this.renderLinkLabels(sankeyDiagramDataView);

this.renderTooltip(linksSelection);

Expand Down Expand Up @@ -1281,6 +1284,90 @@ module powerbi.extensibility.visual {
return linksSelection;
}

private renderLinkLabels(sankeyDiagramDataView: SankeyDiagramDataView): void {
// create labels on link as A - B : Value
let linkTextData: SankeyDiagramLink[] = sankeyDiagramDataView.links.filter((link: SankeyDiagramLink) => {
return link.height > SankeyDiagram.MinSize && this.dataView.settings.linkLabels.show;
});

// add defs element to svg
let svgDefs: Selection<any> = this.root
.selectAll("defs");

let svgDefsSelection: UpdateSelection<Number> = svgDefs.data([1]);
svgDefsSelection
.enter()
.append("defs");

svgDefsSelection
.exit()
.remove();

let singleDefsElement: Selection<any> = d3.select(svgDefsSelection.node());

// add text path for lables
let linkLabelPaths: Selection<any> = singleDefsElement.selectAll(SankeyDiagram.LinkLabelPathsSelector.selector);

let linkLabelPathsSelection: UpdateSelection<SankeyDiagramLink> = linkLabelPaths.data(linkTextData);

linkLabelPathsSelection
.enter()
.append("path")
.classed(SankeyDiagram.LinkLabelPathsSelector.class, true);

linkLabelPathsSelection
.attr({
d: (link: SankeyDiagramLink) => {
return this.getSvgPath(link);
},
id: (link: SankeyDiagramLink) => `${(link.source.label.internalName || "").replace(/\W*/g,"")}-${(link.destination.label.internalName || "").replace(/\W*/g,"")}`
});

linkLabelPathsSelection
.exit()
.remove();

// add text by using paths from defs
let linkLabelTexts: Selection<any> = this.main
.select(SankeyDiagram.LinksSelector.selector)
.selectAll(SankeyDiagram.LinkLabelTextsSelector.selector);

let linkLabelTextSelection: UpdateSelection<SankeyDiagramLink> = linkLabelTexts.data(linkTextData);

linkLabelTextSelection
.enter()
.append("text")
.attr({
"text-anchor": "middle"
})
.classed(SankeyDiagram.LinkLabelTextsSelector.class, true);

let textPathSelection: UpdateSelection<SankeyDiagramLink> = linkLabelTextSelection.selectAll("textPath").data( data => [data]);

textPathSelection
.enter()
.append("textPath")
.attr({
startOffset: "50%",
href: (link: SankeyDiagramLink) => `#${(link.source.label.internalName || "").replace(/\W*/g,"")}-${(link.destination.label.internalName || "").replace(/\W*/g,"")}`
})
.style({
"font-size": this.dataView.settings.linkLabels.fontSize,
"fill": this.dataView.settings.linkLabels.fill
})
.text((link: SankeyDiagramLink) =>
`${link.source.label.name || ""}-${link.destination.label.name || ""}:${(link.tooltipInfo[2] || {value: ""}).value}`
);

textPathSelection
.exit()
.remove();

linkLabelTextSelection
.exit()
.remove();
}

private getSvgPath(link: SankeyDiagramLink): string {
let x0: number,
x1: number,
Expand Down
25 changes: 22 additions & 3 deletions test/visualTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ module powerbi.extensibility.visual.test {
formattedName: "",
width: 0,
height: 0,
color: ""
color: "",
internalName: ""
},
inputWeight: 0,
outputWeight: 0,
Expand Down Expand Up @@ -164,13 +165,14 @@ module powerbi.extensibility.visual.test {

function createNodes(testNodes: SankeyDiagramTestsNode[]): SankeyDiagramNode[] {
return testNodes.map((testNode: SankeyDiagramTestsNode) => {
return {
return <SankeyDiagramNode>{
label: {
name: "",
formattedName: "",
width: 0,
height: 0,
color: ""
color: "",
internalName: ""
},
inputWeight: testNode.inputWeight,
outputWeight: testNode.outputWeight,
Expand Down Expand Up @@ -482,6 +484,23 @@ module powerbi.extensibility.visual.test {
});
});
});

describe("datalabels", () => {
it("must be rendered", done => {
let dataView: DataView = defaultDataViewBuilder.getDataViewWithLowValue();

dataView.metadata.objects = {
linkLabels: {
show: true
}
};

visualBuilder.updateRenderTimeout([dataView], () => {
expect($(visualBuilder.mainElement.find(".linkLabelTexts"))).toBeInDOM();
done();
});
});
});
});
});
}

0 comments on commit 28a87a5

Please sign in to comment.