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.

Color is one of the services offered in IVisualHost. The example code in this article modifies the SampleBarChart visual. For 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 service is available on IVisualHost.

Define the color palette in the update method.

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. Since it 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 actual 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();

Next steps