Hi everyone,
I'm developing a PowerBI custom visual to draw time series differentiated by a legend.
The problem I'm having is with formatting settings.
What I would like is to have a colorPicker in my formatting pane for each of my series.
Here's what I've already done:
- I created a "colorSelector" object in capabilities.json that will be a Slice for each series colorPicker
- I created a selection for each series using this documentation (Create selections for series)
- I used colorHelper to set the default color for series with colorPalette or find the color of the “colorSelector” object associated with a serie, based on this documentation
- I populated the pane formatting based as much as possible on the barChat examplegithub
I manage to get something but the behavior is bizarre:
- There's a colorPicker for each different series BUT when I change the color, it instantly reverts to its default value.
I think I'm missing some information so that I can properly assign a color to each series and then retrieve them, but I haven't been able to find a solution for several days.
Here's what I think
- The colorHelper can't find the color associated to the object but I tried to find the color in a manual way and there is the same result
- There is a problem with the selection,maybe I'm doing it wrong?
- populateColorSelector is not implemented properly?
- I'm not creating the data properly? (dataSeries)
I'd like to thank anyone who can help me understand the problem I encounter.
Here is the code:
capabilities.json
{ "dataRoles": [ { "displayName": "Categories", "name": "category", "kind": "Grouping" }, { "displayName": "Measures", "name": "measure", "kind": "Measure" }, { "displayName": "Series", "name": "series", "kind": "Grouping" } ], "objects": { "colorSelector": { "properties": { "fill": { "type": { "fill": { "solid": { "color": true } } } } } } }, "dataViewMappings": [ { "categorical": { "categories": { "for": { "in": "category" } }, "values": { "group": { "by": "series", "select": [{ "for": { "in": "measure" } } ] } } } } ], "privileges": []}
settings.ts:
"use strict";import { formattingSettings } from "powerbi-visuals-utils-formattingmodel";import { dataSerie } from "./visual";import FormattingSettingsCard = formattingSettings.SimpleCard;import FormattingSettingsSlice = formattingSettings.Slice;import FormattingSettingsModel = formattingSettings.Model;import ColorPicker = formattingSettings.ColorPicker;class ColorSelectorCardSettings extends FormattingSettingsCard { name: string = "colorSelector"; displayName: string = "Data Colors"; slices: FormattingSettingsSlice[] = [];}export class VisualFormattingSettingsModel extends FormattingSettingsModel { colorSelector = new ColorSelectorCardSettings(); cards: FormattingSettingsCard[] = [this.colorSelector]; populateColorSelector(dataPoints: dataSerie[]) { const slices: FormattingSettingsSlice[] = this.colorSelector.slices; if (dataPoints) { dataPoints.forEach(dataPoint => { slices.push(new ColorPicker({ name: "fill", displayName: dataPoint.value.toString(), value: { value: dataPoint.color }, selector: dataPoint.selection.getSelector(), })); }); } }}
visual.ts:
"use strict";import powerbi from "powerbi-visuals-api";import { FormattingSettingsService } from "powerbi-visuals-utils-formattingmodel";import { ColorHelper } from "powerbi-visuals-utils-colorutils";import "./../style/visual.less";import VisualConstructorOptions = powerbi.extensibility.visual.VisualConstructorOptions;import VisualUpdateOptions = powerbi.extensibility.visual.VisualUpdateOptions;import IVisual = powerbi.extensibility.visual.IVisual;import ISelectionId = powerbi.visuals.ISelectionId;import IVisualHost = powerbi.extensibility.visual.IVisualHost;import IColorPalette = powerbi.extensibility.IColorPalette;import DataViewValueColumns = powerbi.DataViewValueColumns;import DataViewValueColumnGroup = powerbi.DataViewValueColumnGroup;import DataViewObjectPropertyIdentifier = powerbi.DataViewObjectPropertyIdentifier;import ILocalizationManager = powerbi.extensibility.ILocalizationManager;import { VisualFormattingSettingsModel } from "./settings";export interface dataSerie { value: powerbi.PrimitiveValue; selection: ISelectionId, color: string;}export class Visual implements IVisual { private formattingSettings: VisualFormattingSettingsModel; private formattingSettingsService: FormattingSettingsService; private host: IVisualHost; private colorPalette: IColorPalette; private localizationManager: ILocalizationManager; constructor(options: VisualConstructorOptions) { this.host = options.host; this.localizationManager = this.host.createLocalizationManager(); this.formattingSettingsService = new FormattingSettingsService(this.localizationManager); this.colorPalette = options.host.colorPalette; } public update(options: VisualUpdateOptions) { this.formattingSettings = this.formattingSettingsService.populateFormattingSettingsModel(VisualFormattingSettingsModel, options.dataViews?.[0]); const dataSeries: dataSerie[] = []; const series: powerbi.DataViewValueColumnGroup[] = options.dataViews[0].categorical.values.grouped(); const valueColumns: DataViewValueColumns = options.dataViews[0].categorical.values, grouped: DataViewValueColumnGroup[] = valueColumns.grouped(), defaultDataPointColor: string = "green", fillProp: DataViewObjectPropertyIdentifier = { objectName: "objectName", propertyName: "propertyName" }; series.forEach((ser: powerbi.DataViewValueColumnGroup, index) => { // create selection id for series const seriesSelectionId = this.host.createSelectionIdBuilder() .withSeries(options.dataViews[0].categorical.values, ser) .createSelectionId(); // get the color from series const defaultDataPointColor: string = this.colorPalette.getColor(ser.name.toString()).value; let colorHelper: ColorHelper = new ColorHelper( this.colorPalette, fillProp, defaultDataPointColor); let grouping: DataViewValueColumnGroup = grouped[index]; let color = colorHelper.getColorForSeriesValue(grouping.objects, grouping.name); // create the series elements dataSeries.push({ value: ser.name, selection: seriesSelectionId, color: color }); }); // Populate the formatting pane this.formattingSettings.populateColorSelector(dataSeries); } public getFormattingModel(): powerbi.visuals.FormattingModel { return this.formattingSettingsService.buildFormattingModel(this.formattingSettings); }}
Sample of data:
X | Y | Legend |
samedi 30 décembre 2023 | 14022,91642 | C |
dimanche 31 décembre 2023 | 0,551076646 | A |
dimanche 31 décembre 2023 | 10435,26002 | C |
lundi 1 janvier 2024 | 0,689471555 | A |
lundi 1 janvier 2024 | 12759,20759 | C |
mardi 2 janvier 2024 | 0,305575341 | A |
mardi 2 janvier 2024 | 10230,89312 | C |
mercredi 3 janvier 2024 | 0,587809939 | A |
mercredi 3 janvier 2024 | 11722,69859 | C |
jeudi 4 janvier 2024 | 0,964788095 | A |
jeudi 4 janvier 2024 | 13221,84671 | C |
vendredi 5 janvier 2024 | 0,721572695 | A |
vendredi 5 janvier 2024 | 11472,99755 | C |
samedi 6 janvier 2024 | 0,394463782 | A |
samedi 6 janvier 2024 | 43840,72009 | B |
samedi 6 janvier 2024 | 11982,3041 | C |
samedi 6 janvier 2024 | 515,2744629 | D |
samedi 6 janvier 2024 | 694,6464676 | E |
dimanche 7 janvier 2024 | 0,359213967 | A |
dimanche 7 janvier 2024 | 46322,50275 | B |
dimanche 7 janvier 2024 | 14065,89778 | C |
dimanche 7 janvier 2024 | 279,9718025 | D |
dimanche 7 janvier 2024 | 653,0402894 | E |
And how I fill the data fields:
Solved!Go to Solution.