Skip to content

Commit

Permalink
Fix issues found in 1.9.0 version of visual (#9)
Browse files Browse the repository at this point in the history
* Fix x-axis title position when labels rotate to 45 degrees
* Handle null category names
* Fix color selection, when visual doesn't have series
* Update changelog.md and increase version number
* Clean up code
  • Loading branch information
zBritva authored and ignatvilesov committed Aug 10, 2017
1 parent c117e1f commit 487ad2b
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 84 deletions.
6 changes: 6 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 1.9.1

* Fix x-axis title position, when axis labels rotated to 45 degrees
* Fix color selection, when visual doesn't have series
* Displaying category with null value

## 1.9.0

* Add sorting of legend items by value
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-mekkochart",
"version": "1.9.0",
"version": "1.9.1",
"description": "A Mekko chart is a mix of a 100% stacked column chart and a 100% stacked bar chart combined into one view. Similar to a treemap, the dimensional values are represented by length and width of each rectangle. The width of a column is proportional to the total value of the column.",
"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": "MekkoChart",
"displayName": "Mekko Chart 1.9.0",
"displayName": "Mekko Chart 1.9.1",
"guid": "MekkoChart1449744733038",
"visualClassName": "MekkoChart",
"version": "1.9.0",
"version": "1.9.1",
"description": "A Mekko chart is a mix of a 100% stacked column chart and a 100% stacked bar chart combined into one view. Similar to a treemap, the dimensional values are represented by length and width of each rectangle. The width of a column is proportional to the total value of the column.",
"supportUrl": "http://community.powerbi.com",
"gitHubUrl": "https://github.com/Microsoft/powerbi-visuals-mekkochart"
Expand Down
5 changes: 3 additions & 2 deletions src/columnChart/baseColumnChart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -817,7 +817,8 @@ module powerbi.extensibility.visual.columnChart {

let color: string = BaseColumnChart.getDataPointColor(
legendItem,
categoryIndex
categoryIndex,
dataPointObjects
);

const seriesData: tooltip.TooltipSeriesDataItem[] = [];
Expand Down Expand Up @@ -1001,7 +1002,7 @@ module powerbi.extensibility.visual.columnChart {
if (series.data[0] !== undefined && series.data[0].valueAbsolute > categoryProperties[series.data[0].categoryIndex].valueAbsolute) {
categoryProperties[series.data[0].categoryIndex].valueAbsolute = series.data[0].valueAbsolute;
categoryProperties[series.data[0].categoryIndex].color = series.data[0].color;
categoryProperties[series.data[0].categoryIndex].name = series.data[0].categoryValue.toString();
categoryProperties[series.data[0].categoryIndex].name = (series.data[0].categoryValue || "").toString();
categoryProperties[series.data[0].categoryIndex].series = series;
categoryProperties[series.data[0].categoryIndex].identity = series.identity;
}
Expand Down
113 changes: 59 additions & 54 deletions src/converterStrategy/baseConverterStrategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,70 +84,75 @@ module powerbi.extensibility.visual.converterStrategy {
let categoryGradientStartBaseColorIdentities: BaseColorIdentity[] = [];
let categoryGradientEndBaseColorIdentities: BaseColorIdentity[] = [];
let categoryItemsCount: Array<IFilteredValueGroups[]> = [];
this.dataView.categories[0].values.forEach( (category: PrimitiveValue, index: number) => {
// gradiend start color
let mappedItems: IFilteredValueGroups[] = valueGroups.map( group => {
return <IFilteredValueGroups>{
gr: group,
categoryValue: group.values[0].values[index],
categoryIndex: index,
category: category,
identity: group.identity
};
}).filter(v => v.categoryValue !== null);

categoryItemsCount[index] = mappedItems;

if (colorGradient) {
categoryItemsCount[index] = _.sortBy(categoryItemsCount[index], BaseConverterStrategy.SortField);
}
if (colorGradient) {
this.dataView.categories[0].values.forEach( (category: PrimitiveValue, index: number) => {
// gradiend start color
let mappedItems: IFilteredValueGroups[] = [];
valueGroups.forEach( group => {
if (group.values[0].values[index] !== null) {
mappedItems.push(<IFilteredValueGroups>{
gr: group,
categoryValue: group.values[0].values[index],
categoryIndex: index,
category: category || "",
identity: group.identity
});
}
});
categoryItemsCount[index] = mappedItems;

let baseStartColorIdentity: IFilteredValueGroups = _.maxBy(mappedItems, BaseConverterStrategy.SortField);
if (baseStartColorIdentity === undefined) {
return;
}
if (colorGradient) {
categoryItemsCount[index] = _.sortBy(categoryItemsCount[index], BaseConverterStrategy.SortField);
}

let colorStart: string = defaultLabelLegendColor;
let baseStartColorIdentity: IFilteredValueGroups = _.maxBy(mappedItems, BaseConverterStrategy.SortField);
if (baseStartColorIdentity === undefined) {
return;
}

if (baseStartColorIdentity.gr.objects !== undefined && (<Fill>(<any>baseStartColorIdentity.gr.objects).dataPoint.fill).solid !== undefined) {
colorStart = (<Fill>(<any>baseStartColorIdentity.gr.objects).dataPoint.fill).solid.color;
}
let colorStart: string = defaultLabelLegendColor;

categoryGradientStartBaseColorIdentities[index] = {
category: baseStartColorIdentity.category.toString(),
color: colorStart,
identity: baseStartColorIdentity.gr.identity,
group: baseStartColorIdentity.gr
};
if (baseStartColorIdentity.gr.objects !== undefined && (<Fill>(<any>baseStartColorIdentity.gr.objects).dataPoint.fill).solid !== undefined) {
colorStart = (<Fill>(<any>baseStartColorIdentity.gr.objects).dataPoint.fill).solid.color;
}

// gradiend end color
let baseEndColorIdentity: IFilteredValueGroups = _.minBy(valueGroups.map( group => {
return <IFilteredValueGroups>{
gr: group,
categoryValue: group.values[0].values[index],
categoryIndex: index,
category: category,
identity: group.identity
categoryGradientStartBaseColorIdentities[index] = {
category: (baseStartColorIdentity.category || "").toString(),
color: colorStart,
identity: baseStartColorIdentity.gr.identity,
group: baseStartColorIdentity.gr
};
}), BaseConverterStrategy.SortField);

if (baseEndColorIdentity === undefined) {
return;
}
// gradiend end color
let baseEndColorIdentity: IFilteredValueGroups = _.minBy(valueGroups.map( group => {
return <IFilteredValueGroups>{
gr: group,
categoryValue: group.values[0].values[index],
categoryIndex: index,
category: category,
identity: group.identity
};
}), BaseConverterStrategy.SortField);

let colorEnd: string = defaultLabelLegendColor;
if (baseEndColorIdentity === undefined) {
return;
}

if (baseEndColorIdentity.gr.objects !== undefined && (<Fill>(<any>baseEndColorIdentity.gr.objects).dataPoint.fill).solid !== undefined) {
colorEnd = (<Fill>(<any>baseEndColorIdentity.gr.objects).dataPoint.fill).solid.color;
}
let colorEnd: string = defaultLabelLegendColor;

categoryGradientEndBaseColorIdentities[index] = {
category: baseEndColorIdentity.category.toString(),
color: colorEnd,
identity: baseEndColorIdentity.gr.identity,
group: baseEndColorIdentity.gr
};
});
if (baseEndColorIdentity.gr.objects !== undefined && (<Fill>(<any>baseEndColorIdentity.gr.objects).dataPoint.fill).solid !== undefined) {
colorEnd = (<Fill>(<any>baseEndColorIdentity.gr.objects).dataPoint.fill).solid.color;
}

categoryGradientEndBaseColorIdentities[index] = {
category: (baseEndColorIdentity.category || "").toString(),
color: colorEnd,
identity: baseEndColorIdentity.gr.identity,
group: baseEndColorIdentity.gr
};
});
}

if (this.dataView && this.dataView.values) {
const allValues: DataViewValueColumns = this.dataView.values;
Expand Down Expand Up @@ -196,7 +201,7 @@ module powerbi.extensibility.visual.converterStrategy {
let categoryIndex: number = _.findIndex(series.values, value => value);

let positionIndex: number = _.findIndex(<IFilteredValueGroups[]>categoryItemsCount[categoryIndex], ser => ser.identity === series.identity );
category = categoryMaxValues[categoryIndex].category.toString();
category = (categoryMaxValues[categoryIndex].category || "").toString();
let gradientBaseColorStart: string = colorHelper.getColorForSeriesValue(categoryGradientStartBaseColorIdentities[categoryIndex].group.objects, category);
let gradientBaseColorEnd: string = colorHelper.getColorForSeriesValue(categoryGradientEndBaseColorIdentities[categoryIndex].group.objects, category);

Expand Down
65 changes: 40 additions & 25 deletions src/visual.ts
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,37 @@ module powerbi.extensibility.visual {
true);
}

private calculateXAxisAdditionalHeight(): number {
let categories: PrimitiveValue[] = (<BaseColumnChart>this.layers[0]).getData().categories;
let sortedByLength: PrimitiveValue[] = _.sortBy(categories, "length");
let longestCategory: PrimitiveValue = sortedByLength[categories.length - 1] || "";
let shortestCategory: PrimitiveValue = sortedByLength[0] || "";

if (longestCategory instanceof Date) {
let metadataColumn: DataViewMetadataColumn = (<BaseColumnChart>this.layers[0]).getData().valuesMetadata[0];
let formatString: string = valueFormatter.getFormatStringByColumn(metadataColumn);

let formatter = valueFormatter.create({
format: formatString,
value: shortestCategory,
value2: longestCategory,
columnType: <ValueTypeDescriptor>{
dateTime: true
}
});

longestCategory = formatter.format(longestCategory);
}

const xAxisTextProperties: TextProperties = MekkoChart.getTextProperties(this.categoryAxisProperties
&& PixelConverter.fromPointToPixel(
parseFloat(<any>this.categoryAxisProperties["fontSize"])) || undefined);

let longestCategoryWidth = textMeasurementService.measureSvgTextWidth(xAxisTextProperties, longestCategory.toString());
let requiredHeight = longestCategoryWidth * Math.tan(MekkoChart.CategoryTextRotataionDegree * Math.PI / 180);
return requiredHeight;
}

private renderAxesLabels(options: MekkoAxisRenderingOptions, xFontSize: number): void {
this.axisGraphicsContext
.selectAll(MekkoChart.XAxisLabelSelector.selectorName)
Expand All @@ -430,10 +461,17 @@ module powerbi.extensibility.visual {
const xAxisYPosition: number = d3.transform(this.xAxisGraphicsContext.attr("transform")).translate[1]
- fontSize + xFontSize + MekkoChart.XAxisYPositionOffset;

const rotataionEnabled = (<BaseColumnChart>this.layers[0]).getXAxisLabelsSettings().enableRotataion;

let shiftTitle: number = 0;
if (rotataionEnabled) {
shiftTitle = this.calculateXAxisAdditionalHeight();
}

const xAxisLabel: Selection<any> = this.axisGraphicsContext.append("text")
.attr({
x: width / MekkoChart.WidthDelimiter,
y: xAxisYPosition
y: xAxisYPosition + shiftTitle
})
.style({
"fill": options.xLabelColor
Expand Down Expand Up @@ -1872,30 +1910,7 @@ module powerbi.extensibility.visual {
const rotataionEnabled = (<BaseColumnChart>this.layers[0]).getXAxisLabelsSettings().enableRotataion;

if (rotataionEnabled) {
let categories: any[] = (<BaseColumnChart>this.layers[0]).getData().categories;
let sortedByLength: any[] = _.sortBy(categories, "length");
let longestCategory: any = sortedByLength[categories.length - 1];
let shortestCategory: any = sortedByLength[0];

if (longestCategory instanceof Date) {
let metadataColumn: DataViewMetadataColumn = (<BaseColumnChart>this.layers[0]).getData().valuesMetadata[0];
let formatString: string = valueFormatter.getFormatStringByColumn(metadataColumn);

let formatter = valueFormatter.create({
format: formatString,
value: shortestCategory,
value2: longestCategory,
columnType: <ValueTypeDescriptor>{
dateTime: true
}
});

longestCategory = formatter.format(longestCategory);
}

let longestCategoryWidth = textMeasurementService.measureSvgTextWidth(xAxisTextProperties, longestCategory);
let requiredHeight = longestCategoryWidth * Math.tan(MekkoChart.CategoryTextRotataionDegree * Math.PI / 180);
xMax += requiredHeight;
xMax += this.calculateXAxisAdditionalHeight();
}

if (this.hideAxisLabels(this.legendMargins)) {
Expand Down

0 comments on commit 487ad2b

Please sign in to comment.