Add colors to your Power BI visuals
This article describes how to add colors to your custom visuals and how to handle data points for a visual that has defined colors.
IVisualHost
, the collection of properties and services that interact with the visual host, can define colors in custom visuals with the colorPalette
service. The example code in this article modifies the SampleBarChart visual. For the SampleBarChart visual source code, see barChart.ts.
To get started creating visuals, see Developing a a Power BI circle card visual.
Add color to data points
To represent each data point in a different color, add the color
variable to the BarChartDataPoint
interface, as shown in the following example:
/**
* Interface for BarChart data points.
*
* @interface
* @property {number} value - Data value for point.
* @property {string} category - Corresponding category of data value.
* @property {string} color - Color corresponding to data point.
*/
interface BarChartDataPoint {
value: number;
category: string;
color: string;
};
Use the color palette service
The colorPalette
service manages the colors used in your visual. An instance of the colorPalette
service is available on IVisualHost
.
Define the color palette in the update
method with the following code:
constructor(options: VisualConstructorOptions) {
this.host = options.host; // host: IVisualHost
...
}
public update(options: VisualUpdateOptions) {
let colorPalette: IColorPalette = host.colorPalette;
...
}
Assigning color to data points
Next, specify dataPoints
. In this example, each of the dataPoints
has a defined value, category, and color property. dataPoints
can also include other properties.
In SampleBarChart
, the visualTransform
method is a part of the Bar Chart viewmodel. Because the visualTransform
method iterates through all the dataPoints
calculations, it's the ideal place to assign colors, as in the following code:
public update(options: VisualUpdateOptions) {
....
let viewModel: BarChartViewModel = visualTransform(options, this.host);
....
}
function visualTransform(options: VisualUpdateOptions, host: IVisualHost): BarChartViewModel {
let colorPalette: IColorPalette = host.colorPalette; // host: IVisualHost
for (let i = 0, len = Math.max(category.values.length, dataValue.values.length); i < len; i++) {
barChartDataPoints.push({
category: category.values[i],
value: dataValue.values[i],
color: colorPalette.getColor(category.values[i]).value,
});
}
}
Then, apply the data from dataPoints
to the d3-selection barSelection
inside the update
method:
// This code is for d3 v5
// in d3 v5 for this case we should use merge() after enter() and apply changes on barSelectionMerged
this.barSelection = this.barContainer
.selectAll('.bar')
.data(this.barDataPoints);
const barSelectionMerged = this.barSelection
.enter()
.append('rect')
.merge(<any>this.barSelection);
barSelectionMerged.classed('bar', true);
barSelectionMerged
.attr("width", xScale.bandwidth())
.attr("height", d => height - yScale(<number>d.value))
.attr("y", d => yScale(<number>d.value))
.attr("x", d => xScale(d.category))
.style("fill", (dataPoint: BarChartDataPoint) => dataPoint.color)
.style("stroke", (dataPoint: BarChartDataPoint) => dataPoint.strokeColor)
.style("stroke-width", (dataPoint: BarChartDataPoint) => `${dataPoint.strokeWidth}px`);
this.barSelection
.exit()
.remove();