Skip to content

Commit

Permalink
Bug fixes and new features (#11)
Browse files Browse the repository at this point in the history
* In formatting panel, new property was added to configure the behavior of nodes near a border of visual.

* Hide overlaped labels in visual.

* CHANGELOG.md was added
  • Loading branch information
zBritva authored and ignatvilesov committed May 22, 2017
1 parent a57a73c commit 36265fb
Show file tree
Hide file tree
Showing 10 changed files with 134 additions and 7 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ typings
.api
*.log
/coverage

.idea/*
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## 1.3.8
* New property "Intersection" in "Data labels" option of "Format" panel to hide overlaped labels in visual.
* New option "Bound by box" in "Format" panel to configure the behavior of nodes near a border of visual.
12 changes: 12 additions & 0 deletions capabilities.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@
"fontSize": true
}
}
},
"allowIntersection": {
"displayName": "Intersection",
"type": {
"bool": true
}
}
}
},
Expand Down Expand Up @@ -236,6 +242,12 @@
"numeric": true
},
"displayName": "Charge"
},
"boundedByBox": {
"type": {
"bool": true
},
"displayName": "Bound by box"
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "powerbi-visuals-forcegraph",
"version": "1.3.7",
"version": "1.3.8",
"description": "This custom visual implements a D3 force layout diagram with curved path. The thickness of the path also represents the weight of the relationship between the nodes.",
"repository": {
"type": "git",
Expand Down Expand Up @@ -53,6 +53,8 @@
"powerbi-visuals-utils-tooltiputils": "^0.3.0",
"powerbi-visuals-utils-testutils": "^0.2.2",
"powerbi-visuals-utils-typeutils": "^0.2.1",
"powerbi-visuals-utils-chartutils": "0.2.3",
"powerbi-visuals-utils-interactivityutils": "0.2.1",
"tslint": "3.15.1",
"typings": "1.4.0"
}
Expand Down
6 changes: 4 additions & 2 deletions pbiviz.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"displayName": "Force-Directed Graph",
"guid": "ForceGraph1449359463895",
"visualClassName": "ForceGraph",
"version": "1.3.7",
"version": "1.3.8",
"description": "This custom visual implements a D3 force layout diagram with curved path. The thickness of the path also represents the weight of the relationship between the nodes.",
"supportUrl": "http://community.powerbi.com",
"gitHubUrl": "https://github.com/Microsoft/PowerBI-visuals-ForceGraph"
Expand All @@ -27,7 +27,9 @@
"node_modules/powerbi-visuals-utils-typeutils/lib/index.js",
"node_modules/powerbi-visuals-utils-svgutils/lib/index.js",
"node_modules/powerbi-visuals-utils-formattingutils/lib/index.js",
"node_modules/powerbi-visuals-utils-tooltiputils/lib/index.js"
"node_modules/powerbi-visuals-utils-tooltiputils/lib/index.js",
"node_modules/powerbi-visuals-utils-interactivityutils/lib/index.js",
"node_modules/powerbi-visuals-utils-chartutils/lib/index.js"
],
"style": "style/visual.less",
"capabilities": "capabilities.json"
Expand Down
12 changes: 11 additions & 1 deletion src/dataInterfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,24 @@ module powerbi.extensibility.visual {

// powerbi.extensibility.utils.tooltip
import TooltipEnabledDataPoint = powerbi.extensibility.utils.tooltip.TooltipEnabledDataPoint;
import IValueFormatter = powerbi.extensibility.utils.formatting.IValueFormatter;

export interface ForceGraphNode extends Node {
name: string;
image: string;
adj: { [i: string]: number };
adj: {[i: string]: number};
x?: number;
y?: number;
isDrag?: boolean;
isOver?: boolean;
hideLabel?: boolean;
}

export interface ITextRect {
x1: number;
y1: number;
x2: number;
y2: number;
}

export interface ForceGraphNodes {
Expand All @@ -61,6 +70,7 @@ module powerbi.extensibility.visual {
linkedByName: LinkedByName;
linkTypes: {};
settings: ForceGraphSettings;
formatter: IValueFormatter;
}

export interface LinkedByName {
Expand Down
2 changes: 2 additions & 0 deletions src/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ module powerbi.extensibility.visual {
public show: boolean = true;
public color: string = '#777777';
public fontSize: number = 9;
public allowIntersection: boolean = false;
}

export class LinksSettings {
Expand Down Expand Up @@ -67,5 +68,6 @@ module powerbi.extensibility.visual {

export class SizeSettings {
public charge: number = -15;
public boundedByBox: boolean = false;
}
}
94 changes: 91 additions & 3 deletions src/visual.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ module powerbi.extensibility.visual {
import TooltipEventArgs = powerbi.extensibility.utils.tooltip.TooltipEventArgs;
import ITooltipServiceWrapper = powerbi.extensibility.utils.tooltip.ITooltipServiceWrapper;
import createTooltipServiceWrapper = powerbi.extensibility.utils.tooltip.createTooltipServiceWrapper;
import DataLabelManager = powerbi.extensibility.utils.chart.dataLabel.DataLabelManager;
import ILabelLayout = powerbi.extensibility.utils.chart.dataLabel.ILabelLayout;
import TextProperties = powerbi.extensibility.utils.formatting.TextProperties;
import textMeasurementService = powerbi.extensibility.utils.formatting.textMeasurementService;
import IRect = powerbi.extensibility.utils.svg.IRect;

interface ValueLimitation {
(x: any): number;
Expand Down Expand Up @@ -142,6 +147,7 @@ module powerbi.extensibility.visual {
private static DefaultLinkColor: string = '#bbb';
private static DefaultLinkHighlightColor: string = '#f00';
private static DefaultLinkThickness: string = '1.5px';
private static LabelsFontFamily: string = 'sans-serif';

private static MinRangeValue: number = 1;
private static MaxRangeValue: number = 10;
Expand All @@ -166,6 +172,7 @@ module powerbi.extensibility.visual {
private static DefaultLabelText: string = '';

private static ResolutionFactor: number = 20;
private static ResolutionFactorBoundByBox: number = 0.9;

private static LinkSelector: ClassAndSelector = createClassAndSelector('link');
private static LinkLabelHolderSelector: ClassAndSelector = createClassAndSelector('linklabelholder');
Expand Down Expand Up @@ -349,6 +356,7 @@ module powerbi.extensibility.visual {
if (!nodes[tableRow.Source]) {
nodes[tableRow.Source] = {
name: sourceFormatter.format(tableRow.Source),
hideLabel: false,
image: tableRow.SourceType || ForceGraph.DefaultSourceType,
adj: {}
};
Expand All @@ -357,6 +365,7 @@ module powerbi.extensibility.visual {
if (!nodes[tableRow.Target]) {
nodes[tableRow.Target] = {
name: targetFormatter.format(tableRow.Target),
hideLabel: false,
image: tableRow.TargetType || ForceGraph.DefaultTargetType,
adj: {}
};
Expand Down Expand Up @@ -407,10 +416,13 @@ module powerbi.extensibility.visual {
maxFiles,
linkedByName,
settings,
linkTypes: linkDataPoints
linkTypes: linkDataPoints,
formatter: targetFormatter
};
}



private static parseSettings(dataView: DataView): ForceGraphSettings {
let settings: ForceGraphSettings = ForceGraphSettings.parse<ForceGraphSettings>(dataView);

Expand All @@ -426,6 +438,39 @@ module powerbi.extensibility.visual {
return settings;
}

private isIntersect(textRect1: ITextRect, textRect2: ITextRect): boolean {
let intersectY: boolean = false;
let intersectX: boolean = false;

if (textRect1.y1 <= textRect2.y1 && textRect2.y1 <= textRect1.y2) {
intersectY = true;
}
if (textRect1.y1 <= textRect2.y2 && textRect2.y2 <= textRect1.y2) {
intersectY = true;
}
if (textRect2.y2 <= textRect1.y1 && textRect1.y1 <= textRect2.y1) {
intersectY = true;
}
if (textRect2.y2 <= textRect1.y2 && textRect1.y2 <= textRect2.y1) {
intersectY = true;
}

if (textRect1.x1 <= textRect2.x1 && textRect2.x1 <= textRect1.x2) {
intersectX = true;
}
if (textRect1.x1 <= textRect2.x2 && textRect2.x2 <= textRect1.x2) {
intersectX = true;
}
if (textRect2.x2 <= textRect1.x1 && textRect1.x1 <= textRect2.x1) {
intersectX = true;
}
if (textRect2.x2 <= textRect1.x2 && textRect1.x2 <= textRect2.x1) {
intersectX = true;
}

return intersectX && intersectY;
}

public update(options: VisualUpdateOptions): void {
if (!options.dataViews || options.dataViews.length < ForceGraph.MinAmountOfDataViews) {
return;
Expand Down Expand Up @@ -639,11 +684,21 @@ module powerbi.extensibility.visual {

private tick(): () => void {
const viewport: IViewport = this.viewportIn;
let properties: TextProperties = {
fontFamily: ForceGraph.LabelsFontFamily,
fontSize: PixelConverter.fromPoint(this.settings.labels.fontSize),
text: this.data.formatter.format('')
};

let resolutionFactor: number = ForceGraph.ResolutionFactor;
if (this.settings.size.boundedByBox) {
resolutionFactor = ForceGraph.ResolutionFactorBoundByBox;
}

// limitX and limitY is necessary when you minimize the graph and then resize it to normal.
// 'width/height * 20' seems enough to move nodes freely by force layout.
let maxWidth: number = viewport.width * ForceGraph.ResolutionFactor,
maxHeight: number = viewport.height * ForceGraph.ResolutionFactor,
let maxWidth: number = viewport.width * resolutionFactor,
maxHeight: number = viewport.height * resolutionFactor,
limitX = x => Math.max((viewport.width - maxWidth) / 2, Math.min((viewport.width + maxWidth) / 2, x)),
limitY = y => Math.max((viewport.height - maxHeight) / 2, Math.min((viewport.height + maxHeight) / 2, y));

Expand All @@ -666,6 +721,39 @@ module powerbi.extensibility.visual {
this.nodes.attr('transform', (node: ForceGraphNode) => {
return translate(limitX(node.x), limitY(node.y));
});

if (!this.settings.labels.allowIntersection)
this.nodes
.classed('hiddenLabel', (node: ForceGraphNode) => {
properties.text = this.data.formatter.format(node.name);
let curNodeTextRect: ITextRect = this.getTextRect(properties, node.x, node.y);

node.hideLabel = false;
this.nodes.each((otherNode: ForceGraphNode) => {
properties.text = this.data.formatter.format(otherNode.name);
let otherNodeTextRect: ITextRect = this.getTextRect(properties, otherNode.x, otherNode.y);
if (!otherNode.hideLabel && node.name !== otherNode.name && this.isIntersect(curNodeTextRect, otherNodeTextRect)) {
node.hideLabel = true;
return;
}
});

return node.hideLabel;
});
};
}

private getTextRect(properties: TextProperties, x: number, y: number): ITextRect {
let textHeight: number = textMeasurementService.estimateSvgTextHeight(properties);
let textWidth: number = textMeasurementService.measureSvgTextWidth(properties);
let curTextUpperPointX: number = x + textWidth;
let curTextUpperPointY: number = y - textHeight;

return <ITextRect>{
x1: x,
y1: y,
x2: curTextUpperPointX,
y2: curTextUpperPointY
};
}

Expand Down
4 changes: 4 additions & 0 deletions style/visual.less
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@
z-index: 99;
}

.hiddenLabel text{
display: none;
}

.hidden {
display: none;
}
Expand Down
2 changes: 2 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
"node_modules/powerbi-visuals-utils-dataviewutils/lib/index.d.ts",
"node_modules/powerbi-visuals-utils-formattingutils/lib/index.d.ts",
"node_modules/powerbi-visuals-utils-tooltiputils/lib/index.d.ts",
"node_modules/powerbi-visuals-utils-interactivityutils/lib/index.d.ts",
"node_modules/powerbi-visuals-utils-chartutils/lib/index.d.ts",
"src/columns.ts",
"src/tooltipsFactory.ts",
"src/settings.ts",
Expand Down

0 comments on commit 36265fb

Please sign in to comment.