Skip to content

Commit 3e3ba32

Browse files
committed
Added percentage scaling and auto intensity.
1 parent a693467 commit 3e3ba32

8 files changed

+74
-11
lines changed

capabilities.json

+12
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,18 @@
7676
"numeric": true
7777
}
7878
},
79+
"autoIntensity":{
80+
"displayName": "Auto intensity",
81+
"type": {
82+
"bool": true
83+
}
84+
},
85+
"pctscale":{
86+
"displayName": "Percentage scale",
87+
"type": {
88+
"bool": true
89+
}
90+
},
7991
"blur": {
8092
"displayName": "Blur",
8193
"type": {

docs/auto-intensity-on.PNG

496 KB
Loading

docs/percentage-scaling-off.PNG

455 KB
Loading

docs/percentage-scaling-on.PNG

557 KB
Loading

package-lock.json

+4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pbiviz.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"displayName": "Heatmap",
55
"guid": "PBI_CV_FCF70EF9_270E_4A52_913E_345CC4A8BFBA",
66
"visualClassName": "Visual",
7-
"version": "3.0.1",
7+
"version": "4.0.0",
88
"description": "The Heatmap Visual enables users to draw a heatmap overlay from a X, Y coordinate set on to an existing image. The user specify the image, and provide a data set of X, Y coordinates and optionally an intensity for each data point. The radius and the bluriness of the heatmap bubbles can be customized as well as the max value for the intensity.",
99
"supportUrl": "http://powerbi.sjkp.dk/support",
1010
"gitHubUrl": "https://github.com/sjkp/heatmap"

src/visual.ts

+57-10
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ module powerbi.extensibility.visual {
5858
private dataPoints: any;
5959
private r: number;
6060
private grad: Uint8ClampedArray;
61+
private useAutoDetectIntensity: boolean;
62+
private usePercentageScaling: boolean;
6163

6264
public defaultRadius = 5;
6365
public defaultGradient = {
@@ -92,6 +94,18 @@ module powerbi.extensibility.visual {
9294
return this;
9395
}
9496

97+
public autoIntensity(auto)
98+
{
99+
this.useAutoDetectIntensity = auto;
100+
return this;
101+
}
102+
103+
public percentageScaling(use)
104+
{
105+
this.usePercentageScaling = use;
106+
return this;
107+
}
108+
95109
public add(point) {
96110
this.dataPoints.push(point);
97111
return this;
@@ -156,7 +170,19 @@ module powerbi.extensibility.visual {
156170
var ctx = this.ctx;
157171

158172
ctx.clearRect(0, 0, this.width, this.height);
159-
173+
if (this.useAutoDetectIntensity)
174+
{
175+
console.log('using auto detect intensity');
176+
var tmpMax = 0;
177+
for(var i=0, len=this.dataPoints.length;i<len;i++)
178+
{
179+
if (this.dataPoints[i][2]>tmpMax )
180+
{
181+
tmpMax = this.dataPoints[i][2];
182+
}
183+
}
184+
this.maxValue = tmpMax;
185+
}
160186
// draw a grayscale heatmap by putting a blurred circle at each data point
161187
for (var i = 0, len = this.dataPoints.length, p; i < len; i++) {
162188
p = this.dataPoints[i];
@@ -165,9 +191,12 @@ module powerbi.extensibility.visual {
165191
//make it so the X and Y input values are a percentage
166192
//this means that the data collected is from 0 to 1 along each axis
167193
//multiply it by the current canvas size
168-
//this should keep the data scalable with the images and resizing
169-
p[0] = p[0] * this.width;
170-
p[1] = p[1] * this.height;
194+
//this should keep the data scalable with the images and resizing
195+
if (this.usePercentageScaling)
196+
{
197+
p[0] = p[0] * this.width;
198+
p[1] = p[1] * this.height;
199+
}
171200
//end proposed change
172201

173202
ctx.globalAlpha = Math.max(p[2] / this.maxValue, minOpacity === undefined ? 0.05 : minOpacity);
@@ -227,20 +256,19 @@ module powerbi.extensibility.visual {
227256
var catDv: DataViewCategorical = dataView.categorical;
228257
var values = catDv.values;
229258
if (typeof (dataView.metadata.columns[0].roles) !== 'undefined') {
230-
for (var i = 0; i < dataView.metadata.columns.length; i++) {
231-
var colRole = Object.keys(dataView.metadata.columns[i].roles)[0];
259+
for (var i = 0; i < catDv.values.length; i++) {
260+
var colRole = values[i].source.displayName
232261
switch (colRole) {
233262
case "X":
234263
xCol = index;
235264
break;
236265
case "Y":
237266
yCol = index;
238267
break;
239-
case "I":
268+
case "Intensity":
240269
iCol = index;
241270
break;
242271
case "Category":
243-
index--;
244272
break;
245273
}
246274
index++;
@@ -294,6 +322,8 @@ module powerbi.extensibility.visual {
294322
//this.updateCanvasSize();
295323
this.updateInternal(false);
296324
this.heatMap.max(Visual.getFieldNumber(this.dataView, 'settings', 'maxValue', this.maxValue));
325+
this.heatMap.autoIntensity(Visual.getFieldBoolean(this.dataView, 'settings', 'autoIntensity', false));
326+
this.heatMap.percentageScaling(Visual.getFieldBoolean(this.dataView, 'settings', 'pctscale', false));
297327
this.heatMap.radius(Visual.getFieldNumber(this.dataView, 'settings', 'radius', 5), Visual.getFieldNumber(this.dataView, 'settings', 'blur', 5));
298328
var data = Visual.converter(this.dataView);
299329
this.heatMap.clear();
@@ -330,11 +360,13 @@ module powerbi.extensibility.visual {
330360
displayName: 'General',
331361
selector: null,
332362
properties: {
333-
backgroundUrl: Visual.getFieldText(dataView, 'settings', 'backgroundUrl', ''),
363+
backgroundUrl: Visual.getFieldText(dataView, 'settings', 'backgroundUrl', this.backgroundUrl),
334364
radius: Visual.getFieldNumber(dataView, 'settings', 'radius', 5),
335365
blur: Visual.getFieldNumber(dataView, 'settings', 'blur', 15),
336366
// maxWidth: HeatMapChart.getFieldNumber(dataView, 'settings', 'maxWidth', this.canvasWidth),
337367
// maxHeight: HeatMapChart.getFieldNumber(dataView, 'settings', 'maxHeight', this.canvasHeight),
368+
autoIntensity: Visual.getFieldBoolean(dataView, 'settings','autoIntensity', false),
369+
pctscale: Visual.getFieldBoolean(dataView, 'settings','pctscale', false),
338370
maxValue: Visual.getFieldNumber(dataView, 'settings', 'maxValue', 1)
339371
}
340372
};
@@ -400,7 +432,7 @@ module powerbi.extensibility.visual {
400432
var lineHeight = 20;
401433
var x = (this.canvasWidth - maxWidth) / 2;
402434
var y = border;
403-
wrapText(context, 'Select a background image, the width and height of the image should match the maximum x,y data points in the dataset.', x, y, maxWidth, lineHeight);
435+
wrapText(context, 'Select a background image, the width and height of the image should match the maximum x,y data points in the dataset. Alternatively you can enable percentage scale, then you x, y coordinate should be between 0 and 1 and the visual will scale their position to the size of the image', x, y, maxWidth, lineHeight);
404436
}
405437

406438
private updateBackgroundUrl() {
@@ -479,5 +511,20 @@ module powerbi.extensibility.visual {
479511
}
480512
return defaultValue;
481513
}
514+
515+
private static getFieldBoolean(dataView: DataView, field: string, property: string = 'text', defaultValue: boolean = false): boolean {
516+
if (dataView) {
517+
var objects = dataView.metadata.objects;
518+
if (objects) {
519+
var f = objects[field];
520+
if (f) {
521+
var num = <boolean>f[property];
522+
if (num)
523+
return num;
524+
}
525+
}
526+
}
527+
return defaultValue;
528+
}
482529
}
483530
}

testdata/percentage.xlsx

16 KB
Binary file not shown.

0 commit comments

Comments
 (0)