Skip to content

Commit

Permalink
Bunch of new features (#16)
Browse files Browse the repository at this point in the history
* Bunch of new features

* Changing of algoritm and repairing offsets for labels

* Cosmetic

* Optimization
  • Loading branch information
EugeneElkin authored and uve committed Sep 11, 2017
1 parent 36ec4dd commit d5e498b
Show file tree
Hide file tree
Showing 9 changed files with 405 additions and 20 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
## 1.1.0
* ADD: Support of 10000 records
* ADD: Max number of bins was increased from 100 to 5000
* ADD: New option for setting of start and end points for X axis

## 1.0.2
* Fixed console errors when chart contains only 1 bar
22 changes: 21 additions & 1 deletion capabilities.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@
"to": "Values"
},
"dataReductionAlgorithm": {
"top": {}
"top": {
"count": 10000
}
}
},
"values": {
Expand Down Expand Up @@ -159,6 +161,24 @@
}
]
}
},
"start": {
"displayName": "Start",
"displayNameKey": "Visual_XAxis_Start",
"type": {
"numeric": true
},
"placeHolderText": "Start",
"suppressFormatPainterCopy": true
},
"end": {
"displayName": "End",
"displayNameKey": "Visual_XAxis_End",
"type": {
"numeric": true
},
"placeHolderText": "End",
"suppressFormatPainterCopy": true
}
}
},
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-histogram",
"version": "1.0.2",
"version": "1.1.0",
"description": "A histogram chart plots data ranges into intervals. Useful for estimating density.",
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion pbiviz.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"displayName": "Histogram",
"guid": "Histogram1445664487616",
"visualClassName": "Histogram",
"version": "1.0.2",
"version": "1.1.0",
"description": "A histogram chart plots data ranges into intervals. Useful for estimating density.",
"supportUrl": "http://community.powerbi.com",
"gitHubUrl": "https://github.com/Microsoft/PowerBI-visuals-histogram"
Expand Down
3 changes: 3 additions & 0 deletions src/dataInterfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ module powerbi.extensibility.visual {
xLegendSize: number;
yLegendSize: number;

xCorrectedMax: number;
xCorrectedMin: number;

xScale?: d3.scale.Linear<any, any>;
yScale?: d3.scale.Linear<any, any>;

Expand Down
7 changes: 5 additions & 2 deletions src/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ module powerbi.extensibility.visual {
export class HistogramGeneralSettings {
public static DefaultBins: number = null;
public static MinNumberOfBins: number = 0;
public static MaxNumberOfBins: number = 100;
public static MaxNumberOfBins: number = 5000;

/**
* Please note that this property isn't enumerated in capabilities.json.
Expand Down Expand Up @@ -70,7 +70,10 @@ module powerbi.extensibility.visual {
public style: HistogramAxisStyle = HistogramAxisStyle.showTitleOnly;
}

export class HistogramXAxisSettings extends HistogramAxisSettings { }
export class HistogramXAxisSettings extends HistogramAxisSettings {
public start: number = null;
public end: number = null;
}

export class HistogramYAxisSettings extends HistogramAxisSettings {
public start: number = 0;
Expand Down
145 changes: 130 additions & 15 deletions src/visual.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,12 @@ module powerbi.extensibility.visual {
right: string;
}

enum UpdateColumnsWidthMode {
markOnly = "markOnly" as any,
calculatePointsDiff = "calculatePointsDiff" as any,
standardCalculation = "standardCalculation" as any
}

export class Histogram implements IVisual {
private static ClassName: string = "histogram";
private static FrequencyText: string = "Frequency";
Expand Down Expand Up @@ -321,6 +327,7 @@ module powerbi.extensibility.visual {
yLegendSize: number,
borderValues: HistogramBorderValues,
yAxisSettings: HistogramYAxisSettings,
xAxisSettings: HistogramXAxisSettings,
sourceValues: number[] = categoryColumn.values as number[];

settings = Histogram.parseSettings(dataView);
Expand Down Expand Up @@ -381,19 +388,28 @@ module powerbi.extensibility.visual {

borderValues = Histogram.getBorderValues(bins);

// min-max for Y axis
yAxisSettings = settings.yAxis;

let maxYvalue: number = (yAxisSettings.end !== null) && (yAxisSettings.end > yAxisSettings.start)
? yAxisSettings.end
: borderValues.maxY;

let minYValue: number = yAxisSettings.start < maxYvalue
? yAxisSettings.start
: 0;

settings.yAxis.start = Histogram.getCorrectXAxisValue(minYValue);
settings.yAxis.end = Histogram.getCorrectXAxisValue(maxYvalue);

// min-max for X axis
xAxisSettings = settings.xAxis;
let maxXvalue: number = (xAxisSettings.end !== null) && (xAxisSettings.end > borderValues.minX)
? xAxisSettings.end
: borderValues.maxX;
let minXValue: number = (xAxisSettings.start !== null) && xAxisSettings.start < maxXvalue
? xAxisSettings.start
: borderValues.minX;
settings.xAxis.start = Histogram.getCorrectXAxisValue(minXValue);
settings.xAxis.end = Histogram.getCorrectXAxisValue(maxXvalue);

if (values.length >= Histogram.MinAmountOfValues) {
valueFormatter = ValueFormatter.create({
format: ValueFormatter.getFormatStringByColumn(dataView.categorical.categories[0].source),
Expand Down Expand Up @@ -431,7 +447,9 @@ module powerbi.extensibility.visual {
yLabelFormatter,
xLegendSize,
yLegendSize,
formatter: valueFormatter
formatter: valueFormatter,
xCorrectedMin: null,
xCorrectedMax: null
};
}

Expand Down Expand Up @@ -706,6 +724,9 @@ module powerbi.extensibility.visual {
}

public update(options: VisualUpdateOptions): void {
let borderValues: HistogramBorderValues,
xAxisSettings: HistogramXAxisSettings;

if (!options
|| !options.dataViews
|| !options.dataViews[0]) {
Expand All @@ -721,6 +742,9 @@ module powerbi.extensibility.visual {
dataView,
this.visualHost);

borderValues = this.dataView.borderValues;
xAxisSettings = this.dataView.settings.xAxis;

if (!this.isDataValid(this.dataView)) {
this.clear();

Expand All @@ -733,8 +757,6 @@ module powerbi.extensibility.visual {

this.columsAndAxesTransform(maxWidthOfVerticalAxisLabel);

this.updateWidthOfColumn();

this.createScales();

this.applySelectionStateToData();
Expand Down Expand Up @@ -798,12 +820,13 @@ module powerbi.extensibility.visual {

private createScales(): void {
const yAxisSettings: HistogramYAxisSettings = this.dataView.settings.yAxis,
xAxisSettings: HistogramXAxisSettings = this.dataView.settings.xAxis,
borderValues: HistogramBorderValues = this.dataView.borderValues;

this.dataView.xScale = d3.scale.linear()
.domain([
borderValues.minX,
borderValues.maxX
this.dataView.xCorrectedMin !== null ? this.dataView.xCorrectedMin : xAxisSettings.start,
this.dataView.xCorrectedMax !== null ? this.dataView.xCorrectedMax : xAxisSettings.end
])
.range([
0,
Expand Down Expand Up @@ -837,13 +860,13 @@ module powerbi.extensibility.visual {
};
}

private updateWidthOfColumn(): void {
private updateWidthOfColumn(updateMode: UpdateColumnsWidthMode): void {
let countOfValues: number = this.dataView.dataPoints.length,
widthOfColumn: number;
widthOfColumn: number,
borderValues: HistogramBorderValues = this.dataView.borderValues,
firstDataPoint: number = this.dataView.xCorrectedMin ? this.dataView.xCorrectedMin : borderValues.minX;

widthOfColumn = countOfValues
? this.viewportIn.width / countOfValues - Histogram.ColumnPadding
: Histogram.MinViewportInSize;
widthOfColumn = countOfValues ? this.dataView.xScale(firstDataPoint + this.dataView.dataPoints[0].dx) - Histogram.ColumnPadding : Histogram.MinViewportInSize;

this.widthOfColumn = Math.max(widthOfColumn, Histogram.MinViewportInSize);
}
Expand Down Expand Up @@ -1002,6 +1025,9 @@ module powerbi.extensibility.visual {
.append("svg:rect")
.classed(Histogram.Column.class, true);

// We can operate by xScale inside this function only when scale was created
this.updateWidthOfColumn(UpdateColumnsWidthMode.standardCalculation);

updateColumnsSelection
.attr({
"x": (dataPoint: HistogramDataPoint) => {
Expand Down Expand Up @@ -1362,17 +1388,106 @@ module powerbi.extensibility.visual {
this.root = null;
}

/// Using in case when xAxis end (set in options) is lesser than calculated border max.
/// This function detect the closest point to xAxis end (set in options).
/// Each iteration tries to shift border limit left corresponding to interval
/// and be closer to xAxis end at the same time.
private findBorderMaxCloserToXAxisEnd(
currentBorderMax: number,
xAxisEnd: number,
interval: number
): number {
while (currentBorderMax > xAxisEnd && xAxisEnd <= currentBorderMax - interval) {
currentBorderMax -= interval;
}

return this.formatXlabelsForFiltering(currentBorderMax);
}

/// Using in case when xAxis start (set in options) is greater than calculated border min.
/// This function detect the closest point to xAxis start (set in options).
/// Each iteration tries to shift border limit right corresponding to interval
/// and be closer to xAxis start at the same time.
private findBorderMinCloserToXAxisStart(
currentBorderMin: number,
xAxisStart: number,
interval: number
): number {
while (currentBorderMin < xAxisStart && xAxisStart >= currentBorderMin + interval) {
currentBorderMin += interval;
}

return this.formatXlabelsForFiltering(currentBorderMin);
}

private formatXlabelsForFiltering(
nonFormattedPoint: number
): number {
let formattedPoint: string = this.dataView.xLabelFormatter.format(nonFormattedPoint);
return parseFloat(formattedPoint);
}

private calculateXAxes(
source: DataViewMetadataColumn,
textProperties: TextProperties,
widthOfLabel: number,
scrollbarVisible: boolean): IAxisProperties {

let axes: IAxisProperties,
width: number = this.viewportIn.width;
width: number = this.viewportIn.width,
xAxisSettings: HistogramXAxisSettings = this.dataView.settings.xAxis,
xPoints: number[],
interval: number,
borderValues: HistogramBorderValues = this.dataView.borderValues,
tmpStart: number,
tmpEnd: number,
tmpArr: number[],
closerLimit: number;

xPoints = Histogram.rangesToArray(this.dataView.dataPoints);

// It is necessary to find out interval to calculate all necessary points before and after offset (if start and end for X axis was changed by user)
if ((borderValues.maxX !== xAxisSettings.end || borderValues.minX !== xAxisSettings.start) && xPoints.length > 1) {
interval = this.dataView.dataPoints[0].dx;

// If start point is greater than min border, it is necessary to remove non-using data points
if (xAxisSettings.start > borderValues.minX) {
closerLimit = this.findBorderMinCloserToXAxisStart(borderValues.minX, xAxisSettings.start, interval);
xPoints = xPoints.filter(dpv => this.formatXlabelsForFiltering(dpv) >= closerLimit);
this.dataView.xCorrectedMin = xPoints && xPoints.length > 0 ? xPoints[0] : null;
}
else {
// Add points before
tmpArr = [];
tmpStart = borderValues.minX;
while (xAxisSettings.start < tmpStart) {
tmpStart = tmpStart - interval;
tmpArr.push(tmpStart);
this.dataView.xCorrectedMin = tmpStart;
}
tmpArr.reverse();
xPoints = tmpArr.concat(xPoints);
}

// If end point is lesser than max border, it is necessary to remove non-using data points
if (xAxisSettings.end < borderValues.maxX) {
closerLimit = this.findBorderMaxCloserToXAxisEnd(borderValues.maxX, xAxisSettings.end, interval);
xPoints = xPoints.filter(dpv => this.formatXlabelsForFiltering(dpv) <= closerLimit);
this.dataView.xCorrectedMax = xPoints && xPoints.length > 0 ? xPoints[xPoints.length - 1] : null;
}
else {
// Add points after
tmpEnd = borderValues.maxX;
while (xAxisSettings.end > tmpEnd) {
tmpEnd = tmpEnd + interval;
xPoints.push(tmpEnd);
this.dataView.xCorrectedMax = tmpEnd;
}
}
}

axes = this.calculateXAxesProperties(
Histogram.rangesToArray(this.dataView.dataPoints),
xPoints,
axisScale.linear,
source,
Histogram.InnerPaddingRatio,
Expand Down
2 changes: 2 additions & 0 deletions stringResources/en-US/resources.resjson
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
"Visual_YAxis": "Y-Axis",
"Visual_YAxis_Start": "Start",
"Visual_YAxis_End": "End",
"Visual_XAxis_Start": "Start",
"Visual_XAxis_End": "End",
"Visual_Position": "Position",
"Visual_Position_Left": "Left",
"Visual_Position_Right": "Right",
Expand Down
Loading

0 comments on commit d5e498b

Please sign in to comment.