Skip to content

Commit

Permalink
High contrast documentation (#42)
Browse files Browse the repository at this point in the history
* Added documentation for *high-contrast* support

* New files:
* Tutorial/HighContrastSupport.md
* Tutorial/images/HC_sampleBarChart_dark2.png
* Tutorial/images/HC_sampleBarChart_standard.png
* Tutorial/images/HC_sampleBarChart_white.png

* Added links to commit and relevant files of Sample Bar Chart high-contrast support implementation
  • Loading branch information
Guy-Moses committed Jul 2, 2018
1 parent 61011c8 commit c44da50
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 1 deletion.
3 changes: 2 additions & 1 deletion README.md
Expand Up @@ -32,6 +32,7 @@ pbiviz start
7. [Adding Powerbi Extensibility Utils](Tutorial/ExtensibilityUtils.md)
8. [Adding URL Launcher element to the Bar Chart](Tutorial/LaunchURL.md)
9. [Adding Report Page tooltips support to the Bar Chart](Tutorial/ReportPageTooltips.md)
10. [Finally Package for Distribution ... Done](https://github.com/Microsoft/PowerBI-visuals/blob/master/tools/usage.md#packaging-your-visual-for-distribution)
10. [Accessibility: Adding High-Contrast Mode Support](Tutorial/HighContrastSupport.md)
11. [Finally Package for Distribution ... Done](https://github.com/Microsoft/PowerBI-visuals/blob/master/tools/usage.md#packaging-your-visual-for-distribution)


133 changes: 133 additions & 0 deletions Tutorial/HighContrastSupport.md
@@ -0,0 +1,133 @@
# Accessibility: Adding High-Contrast Mode Support
Windows *High-Contrast* setting makes text and apps easier to see by using more distinct colors.
Read more about [high-contrast support in Power BI](https://powerbi.microsoft.com/en-us/blog/power-bi-desktop-june-2018-feature-summary/#highContrast).

Adding high-contrast support to your visual requires the following:
1. On init: Detect whether Power BI is in high-contrast mode and if so, get current high-contrast colors.
2. Every update: Change the way the visual renders to make it easier to see.

See this [commit](https://github.com/Microsoft/PowerBI-visuals-sampleBarChart/commit/61011c82b66ca0d3321868f1d089c65101ca42e6) to learn how high-contrast was implemented in Sample Bar Chart, the files [src/barChart.ts](https://github.com/Microsoft/PowerBI-visuals-sampleBarChart/commit/61011c82b66ca0d3321868f1d089c65101ca42e6#diff-433142f7814fee940a0ffc98dc75bfcb) and [capabilities.json](https://github.com/Microsoft/PowerBI-visuals-sampleBarChart/commit/61011c82b66ca0d3321868f1d089c65101ca42e6#diff-290828b604cfa62f1cb310f2e90c52fd) contain the main changes.

## On Init
The [colorPalette](./ColorPalette.md) member of `options.host` has several properties for high-contrast mode. Use these properties to determine whether high-contrast mode is active, and if so, what colors to use.

### Detect that Power BI is in high-contrast mode
If `host.colorPalette.isHighContrast` is `true`, high-contrast mode is active and the visual should draw itself accordingly.

### Get high-contrast colors
In high-contrast mode, your visual should limit itself to the following colors:
* **Foreground** color is used to draw any lines, icons, text and outline or fill of shapes.
* **Background** color is used for background, and as the fill color of outlined shapes.
* **Foreground - selected** color is used to indicate a selected or active element.
* **Hyperlink** color is used only for hyperlink text.

Note: If a secondary color is needed, foreground color may be used with some opacity (Power BI native visuals use 40% opacity). Use this sparingly to keep the visual details easy to see.

You can store these values during initialization:

```typescript
private isHighContrast: boolean;

private foregroundColor: string;
private backgroundColor: string;
private foregroundSelectedColor: string;
private hyperlinkColor: string;
//...

constructor(options: VisualConstructorOptions) {
this.host = options.host;
let colorPalette: ISandboxExtendedColorPalette = host.colorPalette;
//...
this.isHighContrast = colorPalette.isHighContrast;
if (this.isHighContrast) {
this.foregroundColor = colorPalette.foreground.value;
this.backgroundColor = colorPalette.background.value;
this.foregroundSelectedColor = colorPalette.foregroundSelected.value;
this.hyperlinkColor = colorPalette.hyperlink.value;
}
```
Alternatively, you can store the `host` object during initialization and access the relevant `colorPalette` properties during update.
## On Update
The specific implementation of high-contrast support vary from visual to visual and depend on the details of the graphic design. Typically, high-contrast mode requires a slightly different design than the default, in order to keep the important details easy to distinguish with the limited colors.
Here are some guidelines followed by Power BI native visuals:
* All data points use the same color (foreground).
* All text, axes, arrows, lines etc. use foreground color.
* Thick shapes are drawn as outlines, with thick strokes (at least 2 pixels) and background color fill.
* When relevant, data points are distinguished by different marker shapes, data lines are distinguished by different dashing.
* When a data element is highlighted, all other elements change their opacity to 40%.
* For slicers, active filter elements use foreground-selected color.
In Sample Bar Chart, for example, all bars are drawn with 2 pixels thick foreground outline and background fill. Compare the way it looks with default colors and with a couple of high-contrast themes:
![Sample Bar Chart using standard colors](images/HC_sampleBarChart_standard.png)
![Sample Bar Chart using *Dark #2* color theme](images/HC_sampleBarChart_dark2.png)
![Sample Bar Chart using *White* color theme](images/HC_sampleBarChart_white.png)
Here is one place in the `visualTransform` function that was changed to support high-contrast, it is called as part of rendering during `update`:
**before**
```typescript
for (let i = 0, len = Math.max(category.values.length, dataValue.values.length); i < len; i++) {
let defaultColor: Fill = {
solid: {
color: colorPalette.getColor(category.values[i] + '').value
}
};

barChartDataPoints.push({
category: category.values[i] + '',
value: dataValue.values[i],
color: getCategoricalObjectValue<Fill>(category, i, 'colorSelector', 'fill', defaultColor).solid.color,
selectionId: host.createSelectionIdBuilder()
.withCategory(category, i)
.createSelectionId()
});
}
```
**after**
```typescript
for (let i = 0, len = Math.max(category.values.length, dataValue.values.length); i < len; i++) {
const color: string = getColumnColorByIndex(category, i, colorPalette);

const selectionId: ISelectionId = host.createSelectionIdBuilder()
.withCategory(category, i)
.createSelectionId();

barChartDataPoints.push({
color,
strokeColor,
strokeWidth,
selectionId,
value: dataValue.values[i],
category: `${category.values[i]}`,
});
}

//...

function getColumnColorByIndex(
category: DataViewCategoryColumn,
index: number,
colorPalette: ISandboxExtendedColorPalette,
): string {
if (colorPalette.isHighContrast) {
return colorPalette.background.value;
}

const defaultColor: Fill = {
solid: {
color: colorPalette.getColor(`${category.values[index]}`).value,
}
};

return getCategoricalObjectValue<Fill>(category, index, 'colorSelector', 'fill', defaultColor).solid.color;
}
```
Binary file added Tutorial/images/HC_sampleBarChart_dark2.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Tutorial/images/HC_sampleBarChart_standard.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Tutorial/images/HC_sampleBarChart_white.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

1 comment on commit c44da50

@h000ng
Copy link

@h000ng h000ng commented on c44da50 Jul 28, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Please sign in to comment.