diff --git a/capabilities.json b/capabilities.json index 96e35c7..f740152 100644 --- a/capabilities.json +++ b/capabilities.json @@ -428,6 +428,40 @@ } } } + }, + "categoryColorStart": { + "displayName": "Categoty data colors start", + "displayNameKey": "Visual_CategoryDataColorsStart", + "properties": { + "categoryGradient": { + "displayName": "Start color", + "displayNameKey": "Visual_GradientStartColor", + "type": { + "fill": { + "solid": { + "color": true + } + } + } + } + } + }, + "categoryColorEnd": { + "displayName": "Categoty data colors end", + "displayNameKey": "Visual_CategoryDataColorsEnd", + "properties": { + "categoryGradient": { + "displayName": "End color", + "displayNameKey": "Visual_GradientEndColor", + "type": { + "fill": { + "solid": { + "color": true + } + } + } + } + } } }, "dataViewMappings": [ diff --git a/changelog.md b/changelog.md index ebb33d7..6b6ac04 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,6 @@ +## 1.9.3 + +* Displaying the legend with specific dataset breaks the visual - fixed ## 1.9.2 diff --git a/package.json b/package.json index 173e4ce..b29c18c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "powerbi-visuals-mekkochart", - "version": "1.9.2", + "version": "1.9.3", "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", diff --git a/pbiviz.json b/pbiviz.json index 710388e..4990575 100644 --- a/pbiviz.json +++ b/pbiviz.json @@ -1,15 +1,15 @@ { "visual": { "name": "MekkoChart", - "displayName": "Mekko Chart 1.9.2", + "displayName": "Mekko Chart 1.9.3", "guid": "MekkoChart1449744733038", "visualClassName": "MekkoChart", - "version": "1.9.2", + "version": "1.9.3", "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" }, - "apiVersion": "1.6.0", + "apiVersion": "1.7.0", "author": { "name": "Microsoft", "email": "pbicvsupport@microsoft.com" diff --git a/src/columnChart/baseColumnChart.ts b/src/columnChart/baseColumnChart.ts index 5d12b25..f7887d7 100644 --- a/src/columnChart/baseColumnChart.ts +++ b/src/columnChart/baseColumnChart.ts @@ -307,6 +307,7 @@ module powerbi.extensibility.visual.columnChart { // Allocate colors let legendAndSeriesInfo: LegendSeriesInfo = converterStrategy.getLegend(colors, defaultDataPointColor, "", dataPointSettings.categoryGradient, dataPointSettings.colorGradientEndColor.solid.color); let legend: MekkoLegendDataPoint[] = legendAndSeriesInfo.legend.dataPoints; + let seriesSources: DataViewMetadataColumn[] = legendAndSeriesInfo.seriesSources; // Determine data points @@ -1199,13 +1200,38 @@ module powerbi.extensibility.visual.columnChart { this.enumerateSortLegend(enumeration); break; } - case "sortSeries": { - this.enumerateSortSeries(enumeration); + case "categoryColorStart": { + this.enumerateCategoryColors(enumeration, "categoryColorStart", "Start color"); + break; + } + case "categoryColorEnd": { + this.enumerateCategoryColors(enumeration, "categoryColorEnd", "End color"); break; } } } + private enumerateCategoryColors(instances: VisualObjectInstance[], objectName: string, label: string) { + if (this.data.dataPointSettings && this.data.dataPointSettings.categoryGradient) { + this.data.categories.forEach( (category, index ) => { + let categoryLegends: MekkoLegendDataPoint[] = this.data.legendData.dataPoints.filter( legend => legend.category === category); + + instances.push({ + objectName: objectName, + displayName: `${label} -${category}`, + selector: ColorHelper.normalizeSelector((categoryLegends[0].categoryIdentity as ISelectionId).getSelector(), true), + properties: { + categoryGradient: { + solid: { + color: objectName === "categoryColorStart" ? categoryLegends[0].categoryStartColor : categoryLegends[0].categoryEndColor + } + } + }, + }); + }); + } + } + private enumerateXAxisLabels(instances: VisualObjectInstance[]): void { instances[0] = { objectName: "xAxisLabels", @@ -1221,12 +1247,9 @@ module powerbi.extensibility.visual.columnChart { }; instances[0].properties["enabled"] = this.data.sortlegend.enabled; instances[0].properties["direction"] = this.data.sortlegend.direction; - let allowedGroupByCategory = this.checkDataToFeatures(); - if (allowedGroupByCategory) { - instances[0].properties["groupByCategory"] = this.data.sortlegend.groupByCategory; - instances[0].properties["groupByCategoryDirection"] = this.data.sortlegend.groupByCategoryDirection; - } + instances[0].properties["groupByCategory"] = this.data.sortlegend.groupByCategory; + instances[0].properties["groupByCategoryDirection"] = this.data.sortlegend.groupByCategoryDirection; } private enumerateSortSeries(instances: VisualObjectInstance[]): void { @@ -1315,18 +1338,14 @@ module powerbi.extensibility.visual.columnChart { return; } - let allowedCategoryGradient = this.checkDataToFeatures(); - - if (allowedCategoryGradient) { - let properties: any = {}; - properties["categoryGradient"] = this.data.dataPointSettings.categoryGradient; + let properties: any = {}; + properties["categoryGradient"] = this.data.dataPointSettings.categoryGradient; - instances.push({ - objectName: "dataPoint", - selector: null, - properties: properties - }); - } + instances.push({ + objectName: "dataPoint", + selector: null, + properties: properties + }); if (data.hasDynamicSeries || seriesCount > 1 || !data.categoryMetadata) { if (!this.data.dataPointSettings.categoryGradient) { @@ -1341,37 +1360,6 @@ module powerbi.extensibility.visual.columnChart { }); } } - else { - this.data.categories.forEach( (category, index ) => { - let categoryLegends: MekkoLegendDataPoint[] = this.data.legendData.dataPoints.filter( legend => legend.category === category); - let maxValueDataPoint = _.maxBy(categoryLegends, "valueSum"); - if (maxValueDataPoint === undefined) { - return; - } - let minValueDataPoint = _.minBy(categoryLegends, "valueSum"); - if (minValueDataPoint === undefined) { - return; - } - - instances.push({ - objectName: "dataPoint", - displayName: "Start color -" + category, - selector: ColorHelper.normalizeSelector((maxValueDataPoint.identity as ISelectionId).getSelector(), true), - properties: { - fill: { solid: { color: maxValueDataPoint.color } } - }, - }); - - instances.push({ - objectName: "dataPoint", - displayName: "End color -" + category, - selector: ColorHelper.normalizeSelector((minValueDataPoint.identity as ISelectionId).getSelector(), true), - properties: { - fill: { solid: { color: minValueDataPoint.color } } - }, - }); - }); - } } else { // For single-category, single-measure column charts, the user can color the individual bars. diff --git a/src/converterStrategy/baseConverterStrategy.ts b/src/converterStrategy/baseConverterStrategy.ts index f56fbba..7568cd2 100644 --- a/src/converterStrategy/baseConverterStrategy.ts +++ b/src/converterStrategy/baseConverterStrategy.ts @@ -68,8 +68,9 @@ module powerbi.extensibility.visual.converterStrategy { defaultLabelLegendColor ); - let categoryMaxValues: ICategotyValuesStatsCollection = { }; - this.dataView.categories[0].values.forEach( (category, index) => { + const categoryFieldIndex: number = 0; + let categoryMaxValues: ICategotyValuesStatsCollection = {}; + this.dataView.categories[categoryFieldIndex].values.forEach((category, index) => { categoryMaxValues[index] = { category: category, maxValueOfCategory: d3.max(this.dataView.values.map(v => v.values[index])), @@ -81,78 +82,101 @@ module powerbi.extensibility.visual.converterStrategy { // find base color identity // todo handle color change of let valueGroups: DataViewValueColumnGroup[] = this.dataView.values.grouped(); - let categoryGradientStartBaseColorIdentities: BaseColorIdentity[] = []; + let categoryGradientBaseColorIdentities: BaseColorIdentity[] = []; let categoryGradientEndBaseColorIdentities: BaseColorIdentity[] = []; let categoryItemsCount: Array = []; - 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({ - gr: group, - categoryValue: group.values[0].values[index], - categoryIndex: index, - category: category || "", - identity: group.identity - }); - } - }); - categoryItemsCount[index] = mappedItems; + let restoredColors: any; + this.dataView.categories[categoryFieldIndex].values.forEach((category: PrimitiveValue, index: number) => { - if (colorGradient) { - categoryItemsCount[index] = _.sortBy(categoryItemsCount[index], BaseConverterStrategy.SortField); - } + const categorySelectionId: ISelectionId = this.visualHost.createSelectionIdBuilder() + .withCategory(this.dataView.categories[categoryFieldIndex], index) + .createSelectionId(); - let baseStartColorIdentity: IFilteredValueGroups = _.maxBy(mappedItems, BaseConverterStrategy.SortField); - if (baseStartColorIdentity === undefined) { - return; + // gradiend start color + let mappedItems: IFilteredValueGroups[] = []; + valueGroups.forEach(group => { + if (group.values[0].values[index] !== null) { + mappedItems.push({ + gr: group, + categoryValue: group.values[0].values[index], + categoryIndex: index, + category: category || "", + identity: group.identity + }); } + }); + categoryItemsCount[index] = mappedItems; - let colorStart: string = defaultLabelLegendColor; + if (colorGradient) { + categoryItemsCount[index] = _.sortBy(categoryItemsCount[index], BaseConverterStrategy.SortField); + } - if (baseStartColorIdentity.gr.objects !== undefined && ((baseStartColorIdentity.gr.objects).dataPoint.fill).solid !== undefined) { - colorStart = ((baseStartColorIdentity.gr.objects).dataPoint.fill).solid.color; - } + let baseStartColorIdentity: IFilteredValueGroups = _.maxBy(mappedItems, BaseConverterStrategy.SortField); + if (baseStartColorIdentity === undefined) { + return; + } - categoryGradientStartBaseColorIdentities[index] = { - category: (baseStartColorIdentity.category || "").toString(), - color: colorStart, - identity: baseStartColorIdentity.gr.identity, - group: baseStartColorIdentity.gr - }; + let colorStart: string = defaultLabelLegendColor; - // gradiend end color - let baseEndColorIdentity: IFilteredValueGroups = _.minBy(valueGroups.map( group => { - return { - gr: group, - categoryValue: group.values[0].values[index], - categoryIndex: index, - category: category, - identity: group.identity - }; - }), BaseConverterStrategy.SortField); + if (baseStartColorIdentity.gr.objects !== undefined && ((baseStartColorIdentity.gr.objects).dataPoint.fill).solid !== undefined) { + colorStart = ((baseStartColorIdentity.gr.objects).dataPoint.fill).solid.color; + } + if (colorStart === undefined) { + colorStart = colorHelper.getColorForSeriesValue(baseStartColorIdentity.gr.objects, baseStartColorIdentity.categoryValue); + } - if (baseEndColorIdentity === undefined) { - return; - } + // gradiend end color + let baseEndColorIdentity: IFilteredValueGroups = _.minBy(mappedItems, BaseConverterStrategy.SortField); - let colorEnd: string = defaultLabelLegendColor; + if (baseEndColorIdentity === undefined) { + return; + } - if (baseEndColorIdentity.gr.objects !== undefined && ((baseEndColorIdentity.gr.objects).dataPoint.fill).solid !== undefined) { - colorEnd = ((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 && ((baseEndColorIdentity.gr.objects).dataPoint.fill).solid !== undefined) { + colorEnd = ((baseEndColorIdentity.gr.objects).dataPoint.fill).solid.color; + } + + if (colorEnd === undefined) { + colorEnd = colorHelper.getColorForSeriesValue(baseEndColorIdentity.gr.objects, baseEndColorIdentity.categoryValue); + } + + let categoryStartColor: string = (( + this.dataView.categories[categoryFieldIndex].objects && + this.dataView.categories[categoryFieldIndex].objects[index] && + this.dataView.categories[categoryFieldIndex].objects[index]["categoryColorStart"] || + { + categoryGradient: { + solid: { + color: colorStart + } + } + }) as MekkoGradientSettings).categoryGradient.solid.color; + + let categoryEndColor: string = (( + this.dataView.categories[categoryFieldIndex].objects && + this.dataView.categories[categoryFieldIndex].objects[index] && + this.dataView.categories[categoryFieldIndex].objects[index]["categoryColorEnd"] || + { + categoryGradient: { + solid: { + color: colorEnd + } + } + }) as MekkoGradientSettings).categoryGradient.solid.color; + + categoryGradientBaseColorIdentities[index] = { + category: (baseStartColorIdentity.category || "").toString(), + color: colorStart, + identity: baseStartColorIdentity.gr.identity, + group: baseStartColorIdentity.gr, + categorySelectionId: categorySelectionId, + categoryStartColor: categoryStartColor, + categoryEndColor: categoryEndColor + }; + }); if (this.dataView && this.dataView.values) { const allValues: DataViewValueColumns = this.dataView.values; @@ -193,17 +217,18 @@ module powerbi.extensibility.visual.converterStrategy { let category: string; let color: string; + let categoryIndex: number = _.findIndex(series.values, value => value); + if (!colorGradient) { color = hasDynamicSeries ? colorHelper.getColorForSeriesValue(valueGroupObjects || source.objects, source.groupName) : colorHelper.getColorForMeasure(valueGroupObjects || source.objects, source.queryName); } else { - let categoryIndex: number = _.findIndex(series.values, value => value); - let positionIndex: number = _.findIndex(categoryItemsCount[categoryIndex], ser => ser.identity === series.identity ); + let positionIndex: number = _.findIndex(categoryItemsCount[categoryIndex], ser => ser.identity === series.identity); 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); + let gradientBaseColorStart: string = categoryGradientBaseColorIdentities[categoryIndex].categoryStartColor; + let gradientBaseColorEnd: string = categoryGradientBaseColorIdentities[categoryIndex].categoryEndColor; color = createLinearColorScale( [0, categoryItemsCount[categoryIndex].length], @@ -219,7 +244,10 @@ module powerbi.extensibility.visual.converterStrategy { selected: false, valueSum: d3.sum(series.values), categoryValues: series.values, - category: category + category: category, + categoryStartColor: categoryGradientBaseColorIdentities[categoryIndex].categoryStartColor, + categoryEndColor: categoryGradientBaseColorIdentities[categoryIndex].categoryEndColor, + categoryIdentity: categoryGradientBaseColorIdentities[categoryIndex].categorySelectionId }); if (series.identity && source.groupName !== undefined) { diff --git a/src/converterStrategy/converterStrategy.ts b/src/converterStrategy/converterStrategy.ts index 05f52a4..56c9119 100644 --- a/src/converterStrategy/converterStrategy.ts +++ b/src/converterStrategy/converterStrategy.ts @@ -31,7 +31,8 @@ module powerbi.extensibility.visual.converterStrategy { defaultLegendLabelColor: string, defaultColor?: string, colorGradient?: boolean, - colorGradientEndColor?: string): LegendSeriesInfo; + colorGradientEndColor?: string + ): LegendSeriesInfo; getValueBySeriesAndCategory(series: number, category: number): number; getMeasureNameByIndex(series: number, category: number): string; hasHighlightValues(series: number): boolean; diff --git a/src/dataIntrefaces.ts b/src/dataIntrefaces.ts index 0022403..4fa35a6 100644 --- a/src/dataIntrefaces.ts +++ b/src/dataIntrefaces.ts @@ -75,6 +75,18 @@ module powerbi.extensibility.visual { seriesObjects: IDataViewObjects[][]; } + export interface IGrouppedLegendData { + category: string; + index: number; + data: MekkoLegendDataPoint[]; + dataValues: number; + } + + export interface ILegendGroup extends ILegend { + element: HTMLElement; + position: number; + } + export interface IMekkoChartVisualHost { updateLegend(data: ILegendData): void; getSharedColors(): IColorPalette; @@ -305,6 +317,10 @@ module powerbi.extensibility.visual { colorDistribution: boolean; } + export interface MekkoGradientSettings { + categoryGradient: Fill; + } + export interface MekkoSeriesSortSettings { enabled: boolean; direction: any; @@ -378,6 +394,9 @@ module powerbi.extensibility.visual { fontSize?: number; valueSum?: number; categoryValues?: PrimitiveValue[]; + categoryIdentity?: powerbi.data.Selector; + categoryStartColor?: string; + categoryEndColor?: string; } export interface MekkoCreateAxisOptions extends CreateAxisOptionsBase { @@ -454,6 +473,9 @@ module powerbi.extensibility.visual { category: string; color: string; group: DataViewValueColumnGroup; + categorySelectionId: powerbi.extensibility.ISelectionId; + categoryStartColor?: string; + categoryEndColor?: string; } export interface ICategotyValuesStatsCollection { diff --git a/src/visual.ts b/src/visual.ts index 0bf1a97..3544516 100644 --- a/src/visual.ts +++ b/src/visual.ts @@ -184,8 +184,15 @@ module powerbi.extensibility.visual { private static ShowAxisTitlePropertyName: string = "showAxisTitle"; private static SecondShowAxisTitlePropertyName: string = "secShowAxisTitle"; + private static SortDirectionDescending: string = "des"; + private static SortDirectionAscending: string = "asc"; + private static CategoryTextRotataionDegree: number = 45.0; + private static LegendBarHeightMargin: number = 5; + + private static LegendBarTextFont: string = "helvetica, arial, sans-serif;"; + private static getTextProperties(fontSize: number = MekkoChart.FontSize): TextProperties { return { fontFamily: "helvetica, arial, sans-serif", @@ -242,12 +249,12 @@ module powerbi.extensibility.visual { sortLegend: { enabled: false, groupByCategory: false, - direction: "asc", - groupByCategoryDirection: "asc" + direction: SortDirection.Ascending, + groupByCategoryDirection: SortDirection.Ascending }, sortSeries: { enabled: false, - direction: "asc", + direction: SortDirection.Ascending, displayPercents: "category" }, xAxisLabels: { @@ -1477,13 +1484,13 @@ module powerbi.extensibility.visual { legendData.dataPoints = []; } - let reducedLegends = []; + let reducedLegends: IGrouppedLegendData[] = []; let legendSortSettings: MekkoLegendSortSettings = (this.layers[0]).getLegendSortSettings(); if (legendSortSettings.enabled) { if (legendSortSettings.groupByCategory) { - let mappedLegends = legendData.dataPoints.map( (dataPoint: any) => { - let maxVal = d3.max(dataPoint.categoryValues); - let index = dataPoint.categoryValues.indexOf(maxVal); + let mappedLegends = legendData.dataPoints.map( (dataPoint: MekkoLegendDataPoint) => { + let maxVal = d3.max(dataPoint.categoryValues as Number[]); + let index = dataPoint.categoryValues.indexOf(maxVal as PrimitiveValue); return { categoryIndex: index, data: dataPoint, @@ -1505,22 +1512,22 @@ module powerbi.extensibility.visual { element.dataValues = d3.sum(element.data.map((d) => d.valueSum)); }); - reducedLegends = _.sortBy(reducedLegends, "dataValues"); - - if (legendSortSettings.direction === "des") - reducedLegends = reducedLegends.reverse(); - reducedLegends.forEach(legend => { if (legend === undefined) { return; } - legend.data = _.sortBy( legend.data, "valueSum"); - if (legendSortSettings.groupByCategoryDirection === "des") { + if (legendSortSettings.groupByCategoryDirection === MekkoChart.SortDirectionDescending) { legend.data = legend.data.reverse(); } }); + reducedLegends = _.sortBy(reducedLegends, "dataValues"); + + if (legendSortSettings.direction === MekkoChart.SortDirectionDescending) { + reducedLegends = reducedLegends.reverse(); + } + legendData.dataPoints = []; reducedLegends.forEach(legend => { if (legend === undefined) { @@ -1531,19 +1538,30 @@ module powerbi.extensibility.visual { } else { legendData.dataPoints = _.sortBy(legendData.dataPoints, "valueSum"); - if (legendSortSettings.direction === "des") { + if (legendSortSettings.direction === MekkoChart.SortDirectionDescending) { legendData.dataPoints = legendData.dataPoints.reverse(); } } } + let svgHeight: number = textMeasurementService.estimateSvgTextHeight({ + fontFamily: MekkoChart.LegendBarTextFont, + fontSize: PixelConverter.toString(+legendProperties["fontSize"] + MekkoChart.LegendBarHeightMargin), + text: "AZ" + }); + + d3.select(this.rootElement.node()).selectAll("div.legendParent").remove(); + this.categoryLegends = []; let legendParents = d3.select(this.rootElement.node()).selectAll("div.legendParent"); - let legendParentsWithData = legendParents.data(reducedLegends); + let legendParentsWithData = legendParents.data(reducedLegends.filter((l: IGrouppedLegendData) => l !== undefined)); let legendParentsWithChilds = legendParentsWithData.enter().append("div"); let legendParentsWithChildsAttr = legendParentsWithChilds.classed("legendParent", true) .style({ - position: "absolute" + position: "absolute", + top: function (data) { + return PixelConverter.toString(svgHeight * data.index); + } }); let mekko = this; @@ -1557,13 +1575,15 @@ module powerbi.extensibility.visual { mekko.interactivityService, true); - mekko.categoryLegends[index] = legend; + mekko.categoryLegends[index] = legend; } }); - legendParentsWithData.exit().remove(); - let svgHeight: number = 26; if (reducedLegends.length > 0) { + this.categoryLegends.forEach((legend: ILegend, index: number) => { + (legend).position = +d3.select((legend).element).style("top").replace("px", ""); + } ); + this.categoryLegends = _.sortBy( this.categoryLegends, "position").reverse(); this.categoryLegends.forEach( (legend, index) => { if (reducedLegends[index] === undefined) { LegendData.update({ @@ -1576,6 +1596,7 @@ module powerbi.extensibility.visual { return; } + let legendData: ILegendData = { title: reducedLegends[index].category, dataPoints: reducedLegends[index].data @@ -1592,12 +1613,8 @@ module powerbi.extensibility.visual { } } }); - - legendParentsWithData.style({ - top: function (data) { return PixelConverter.toString(svgHeight * data.index); }, - position: "absolute" - }); } + legendParentsWithData.exit().remove(); if (legendProperties["show"] === false) { legendData.dataPoints = []; @@ -1744,6 +1761,7 @@ module powerbi.extensibility.visual { if (this.categoryLegends.length > 0 && this.categoryLegends[0].isVisible()) { this.legendMargins = this.categoryLegends[0].getMargins(); + this.legendMargins.height = this.legendMargins.height - MekkoChart.LegendBarHeightMargin; this.legendMargins.height = this.legendMargins.height * this.dataViews[0].categorical.categories[0].values.length; } if (this.legend.isVisible()) { diff --git a/stringResources/en-US/resources.resjson b/stringResources/en-US/resources.resjson index 3143ab2..0429eeb 100644 --- a/stringResources/en-US/resources.resjson +++ b/stringResources/en-US/resources.resjson @@ -45,5 +45,7 @@ "Visual_ColorDistibution": "Color distibution by value", "Visual_ColorGradientEndColor": "End color of gradient", "Visual_Default_Color": "Default color", - "Visual_Fill": "Fill" + "Visual_Fill": "Fill", + "Visual_GradientStartColor": "Start color", + "Visual_GradientEndColor": "End color" } \ No newline at end of file diff --git a/test/_references.ts b/test/_references.ts index 6494e09..9c72edc 100644 --- a/test/_references.ts +++ b/test/_references.ts @@ -32,7 +32,7 @@ /// // Power BI API -/// +/// // Power BI Extensibility /// diff --git a/test/visualTest.ts b/test/visualTest.ts index 3061967..7bd061c 100644 --- a/test/visualTest.ts +++ b/test/visualTest.ts @@ -644,23 +644,29 @@ module powerbi.extensibility.visual.test { let data = dataView.categorical.values.grouped(); let catigoried = data.map( d => { return {name: d.name, values: d.values[0].values, category: _.findIndex(d.values[0].values, i => i !== null) }; }); + catigoried = _.sortBy(catigoried, "values"); + + interface CategoryLegendDom { + position: string; + dom: Element; + } visualBuilder.updateRenderTimeout(dataView, () => { expect(visualBuilder.categoryLegendGroup).toBeInDOM(); expect(visualBuilder.categoryLegendGroup.length).toEqual(dataView.categorical.categories[0].values.length); - let mappedCategoryLegendGroup = visualBuilder.categoryLegendGroup.map( (index, clg) => { - return { + let mappedCategoryLegendGroup: JQuery = visualBuilder.categoryLegendGroup.map( (index, clg) => { + return { position: clg.parentElement.parentElement.style.top.replace("px", ""), dom: clg }; }); - let sortedCategoryLegendGroup = _.sortBy(mappedCategoryLegendGroup, "position").map( d => d.dom ); dataView.categorical.categories[0].values.forEach( (category, index) => { let filteredByCategory = catigoried.filter(cat => cat.category === index); filteredByCategory = _.sortBy(filteredByCategory, "values"); - let legentItem = $(sortedCategoryLegendGroup[index]).children("g").children("text"); + let categoryDOM: any = mappedCategoryLegendGroup.filter( (val: any) => { return $((mappedCategoryLegendGroup[val]).dom).children("text.legendTitle").children("title").text() === category; }); + let legentItem = $((categoryDOM[0].dom)).children("g").children("text"); expect(filteredByCategory.length).toEqual(legentItem.length); filteredByCategory.forEach((categoryItem, index) => { expect(legentItem[index].textContent).toEqual(categoryItem.name); diff --git a/tsconfig.json b/tsconfig.json index 800d4e8..b23a6fe 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,7 +13,7 @@ "node_modules/@types/d3/index.d.ts", "node_modules/@types/jquery/index.d.ts", "node_modules/@types/lodash/index.d.ts", - ".api/v1.6.0/PowerBI-visuals.d.ts", + ".api/v1.7.0/PowerBI-visuals.d.ts", "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-interactivityutils/lib/index.d.ts",