Forum Discussion
Power BI Custom Visual: Customize series mechanism example
Settings.ts:
import powerbi from "powerbi-visuals-api";
import { formattingSettings, formattingSettingsCard, formattingSettingsTypes } from "powerbi-visuals-utils-formattingmodel";
// --- Dynamic Column Width Item ---
export class ColumnWidthCardItem extends formattingSettings.SimpleCard {
public width: formattingSettings.NumUpDown;
constructor(name: string, displayName: string, widthValue: number) {
super();
this.name = name; // dynamic key
this.displayName = displayName; // what shows in the formatting pane
this.width = new formattingSettings.NumUpDown({
name: "width",
displayName: "Column Width",
value: widthValue,
options: {
minValue: { type: formattingSettingsTypes.ValidatorType.Min, value: 20 },
maxValue: { type: formattingSettingsTypes.ValidatorType.Max, value: 1000 },
},
});
// Important: binds this property to the card
this.slices = [this.width];
}
}
// --- Container Card ---
export class ColumnWidthCardSetting extends formattingSettings.SimpleCard {
public container: formattingSettings.Container;
constructor() {
super();
this.name = "columnWidth";
this.displayName = "Column Width";
// Initialize empty container for dynamic items
this.container = {
displayName: "Apply settings to",
containerItems: []
};
}
}
// --- Main Visual Settings Model ---
export class VisualSettingsModel {
columnWidth: ColumnWidthCardSetting;
cards: Array<formattingSettings.SimpleCard | formattingSettings.CompositeCard>;
constructor() {
this.columnWidth = new ColumnWidthCardSetting();
this.cards = [this.columnWidth];
}
}
Visual.ts:
// Populate formatting settings
this.formattingSettings = this.formattingSettingsService.populateFormattingSettingsModel(
VisualSettingsModel,
dataView
);
// Only proceed if dataView has matrix data
if (dataView && dataView.matrix) {
const formattedColumns = formatMatrixForFGGrid(dataView.matrix).columns || [];
// Generate dynamic container items per column
const containerItems = formattedColumns.map((col: any) => {
// Default width value (can come from previous saved settings)
let widthValue = 120;
// Check if a value already exists in formattingSettings
const match = this.formattingSettings.columnWidth.container.containerItems.find(
(item: any) => item.name === col.index
);
if (match && match.width) {
widthValue = match.width.value;
}
return new ColumnWidthCardItem(col.index, col.title, widthValue);
});
// Assign dynamically generated items to the container
this.formattingSettings.columnWidth.container.containerItems = containerItems;
}
// --- OPTIONAL: log to debug ---
console.log("Dynamic ColumnWidth Settings:", this.formattingSettings);
-
Each ColumnWidthCardItem has a slices array pointing to its width property.
-
Do not replace the entire formattingSettings object after the visual has been initialized — just update containerItems.
-
populateFormattingSettingsModel must run before rendering the formatting pane, so Power BI knows about the slices.
-
The name of the card item (col.index) is used to track which column the setting belongs to.
BBF
💡 Did I answer your question? Mark my post as a solution!
👍 Kudos are appreciated
🔥 Proud to be a Super User!