Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Earn the coveted Fabric Analytics Engineer certification. 100% off your exam for a limited time only!

Reply
paul-maessen
Resolver I
Resolver I

Trying to implement highlighting in Matrix Dataview

Hi,

 

I am trying to implement highlighting in a custom visual I am developing. This visual is using the Matrix dataViewMapping.

I am able to use selections in my Visual and  when enabling visual interactions I can select the highlight options in my visual (see image)

Screenshot 2020-07-24 at 15.41.46.png

 

 

 

 

 

 

But when I now select a value in another visual the selected point is not highlighted in my visual, which it should so if highlighting would work.

Because I am not sure what I am missing, I will add as much as information to this post. So it might get a bit long 🙂

 

I hope someone can help me to get this to work.

 

Thanks in advance!

 

Paul.

 

Below you will find the information:

 

The dataViewMappings-part of my capabilities.json:

 

"dataRoles": [
        {
            "name": "category",
            "kind": "Grouping",
            "displayName": "Category"
        },
        {
            "name": "value",
            "kind": "GroupingOrMeasure",
            "displayName": "Value"
        }
    ],
    "dataViewMappings": [
        {
            "conditions": [
                {
                    "value": {
                        "max": 1
                    },
                    "category": {
                        "max": 1
                    }
                }
            ],
            "matrix": {
                "rows": {
                    "for": {
                        "in": "category"
                    }
                },
                "values": {
                    "select": [
                        {
                            "for": {
                                "in": "value"
                            }
                        }
                    ]
                }
            }
        }
    ],
    "supportsHighlight": true,

 

 

I am using the GroupingOrMeasure-kind for 'value' so I can select Don't summarize for the measures that are selected for this value.

 

My dataViewModel looks like this:

 

export interface StripPlotViewModel {
    dataView: DataView;
    settings: StripPlotSettings;
    dataPoints: StripPlotPoint[];
    hasHighlights: boolean;
    isCategoryFilled: boolean;
    isValueFilled: boolean;
}

 

 

The StripPlotPoint-interface :

 

export interface StripPlotPoint extends SelectableDataPoint {
    category: PrimitiveValue;
    value: PrimitiveValue;
    opacity: number;
    highlight?: boolean;
    hasHighlights: boolean;
}

 

 

I am using a seperate file to define my behavior:

 

import * as d3 from "d3";

type Selection<T1, T2 = T1> = d3.Selection<any, T1, any, T2>;

import { interactivityBaseService as interactivityService } from "powerbi-visuals-utils-interactivityutils";
import IInteractiveBehavior = interactivityService.IInteractiveBehavior;
import IInteractivityService = interactivityService.IInteractivityService;
import ISelectionHandler = interactivityService.ISelectionHandler;

import { StripPlotPoint } from "./dataInterfaces";
import { IBehaviorOptions } from "powerbi-visuals-utils-interactivityutils/lib/interactivityBaseService";
import { StripPlotSettings } from "./settings";

export const DimmedOpacity: number = 0.2;
export const DefaultOpacity: number = 1.0;

const getEvent = () => d3.event;

export function getFillOpacity(
    selected: boolean,
    highlight: boolean,
    hasSelection: boolean,
    hasPartialHighlights: boolean
): number {
    if ((hasPartialHighlights && !highlight) || (hasSelection && !selected)) {
        return DimmedOpacity;
    }
    return DefaultOpacity;
}

export interface BehaviorOptions extends IBehaviorOptions<StripPlotPoint> {
    clearCatcher: Selection<any>;
    pointSelection: Selection<StripPlotPoint>;
    interactivityService: IInteractivityService<StripPlotPoint>;
    settings: StripPlotSettings;
}

export class Behavior implements IInteractiveBehavior {
    private options: BehaviorOptions;

    public bindEvents(options: BehaviorOptions, selectionHandler: ISelectionHandler) {
        this.options = options;
        let clearCatcher = options.clearCatcher;


        options.pointSelection.on("click", (dataPoint: StripPlotPoint) => {
            const event: MouseEvent = d3.event;
            console.log("clicked: ");
            console.log(event);
            selectionHandler.handleSelection(dataPoint, event.ctrlKey || event.metaKey);

            event.stopPropagation();
        });

        clearCatcher.on("click", () => {
            selectionHandler.handleClearSelection();
        });
    }

    public renderSelection(hasSelection: boolean) {
        const {
            pointSelection,
            interactivityService,
        } = this.options;

        const hasHighlights: boolean = interactivityService.hasSelection();

        pointSelection.style("opacity", (dataPoint: StripPlotPoint) => {
            return getFillOpacity(
                dataPoint.selected,
                dataPoint.highlight,
                !dataPoint.highlight && hasSelection,
                !dataPoint.selected && hasHighlights,
            );
        });
    }
}

 

 

During the update of the Visual I am converting the dataView to my dataViewModel and adding the selectionIds:

 

 

           let dataPoints: StripPlotPoint[] = [];
            for (let n = 0; n < dataView.matrix.rows.root.children.length; n++) {


                const selector: ISelectionId = host.createSelectionIdBuilder()
                .withMatrixNode(dataView.matrix.rows.root.children[n],dataView.matrix.rows.levels )   
                    .createSelectionId();
                let dataPoint: StripPlotPoint = {
                    category: dataView.matrix.rows.root.children[n].levelValues[categoryIndex].value,
                    value: dataView.matrix.rows.root.children[n].levelValues[valueIndex].value,
                    selected: false,
                    highlight: false,
                    identity: selector,
                    opacity: 1,
                    hasHighlights: false
                }
                dataPoints.push(dataPoint)

            }

 

 When checking the datapoints I can see that there are values added for the identity (see screenshot of my console.log)

Screenshot 2020-07-24 at 15.49.59.png

 

 

In the development-visual the data the dataview looks like (i removed a lot of children to limit the size)

 

[
	{
		"metadata":{
			"columns":[
				{
					"roles":{"category":true},
					"type":{"underlyingType":1,"category":{},"primitiveType":1,"extendedType":1,"categoryString":{},"text":true,"numeric":false,"integer":false,"bool":false,"dateTime":false,"duration":false,"binary":false,"none":false},
					"displayName":"gender",
					"queryName":"strip-plot-test.gender",
					"expr":{"_kind":2,"source":{"_kind":0,"entity":"strip-plot-test","variable":"s","kind":0},"ref":"gender","kind":2},
					"rolesIndex":{"category":[0]},
					"index":0,
					"identityExprs":[{"_kind":2,"source":{"_kind":0,"entity":"strip-plot-test","kind":0},"ref":"gender","kind":2}]
				},{
					"roles":{"value":true},
					"type":{"underlyingType":259,"category":{},"primitiveType":3,"extendedType":259,"categoryString":{},"text":false,"numeric":true,"integer":false,"bool":false,"dateTime":false,"duration":false,"binary":false,"none":false},
					"displayName":"height",
					"queryName":"strip-plot-test.height",
					"expr":{"_kind":2,"source":{"_kind":0,"entity":"strip-plot-test","variable":"s","kind":0},"ref":"height","kind":2},
					"rolesIndex":{"value":[0]},
					"index":1,
					"identityExprs":[{"_kind":2,"source":{"_kind":0,"entity":"strip-plot-test","kind":0},"ref":"height","kind":2}]}],
			"objects":{
				"chart":{"dataPointShape":"bar","showGridLines":true},
				"yAxis":{"textSize":19},
				"triangle":{"strokeWidth":0,"size":12},
				"license":{"show":true},
				"bar":{"strokeWidth":8,"size":9,"percentile":72}
			},
			"dataReduction":{
				"matrix":{"rows":{}}
			}
		},
		"matrix":{
			"rows":{
				"levels":[
					{
						"sources":[
							{
								"roles":{"category":true},
								"type":{"underlyingType":1,"category":{},"primitiveType":1,"extendedType":1,"categoryString":{},"text":true,"numeric":false,"integer":false,"bool":false,"dateTime":false,"duration":false,"binary":false,"none":false},
								"displayName":"gender",
								"queryName":"strip-plot-test.gender",
								"expr":{"_kind":2,"source":{"_kind":0,"entity":"strip-plot-test","variable":"s","kind":0},"ref":"gender","kind":2},
								"rolesIndex":{"category":[0]},
								"index":0,
								"identityExprs":[{"_kind":2,"source":{"_kind":0,"entity":"strip-plot-test","kind":0},"ref":"gender","kind":2}]
							},
							{
								"roles":{"value":true},
								"type":{"underlyingType":259,"category":{},"primitiveType":3,"extendedType":259,"categoryString":{},"text":false,"numeric":true,"integer":false,"bool":false,"dateTime":false,"duration":false,"binary":false,"none":false},
								"displayName":"height",
								"queryName":"strip-plot-test.height",
								"expr":{"_kind":2,"source":{"_kind":0,"entity":"strip-plot-test","variable":"s","kind":0},"ref":"height","kind":2},
								"rolesIndex":{"value":[0]},
								"index":1,
								"identityExprs":[{"_kind":2,"source":{"_kind":0,"entity":"strip-plot-test","kind":0},"ref":"height","kind":2}]
							}
							]
					}
					],
				"root":{
					"children":[
						{
							"levelValues":[
								{
									"levelSourceIndex":0,
									"value":"female"
								},
								{
									"levelSourceIndex":1,
									"value":57.50321861
								}
							],
							"value":57.50321861,
							"levelSourceIndex":1,
							"level":0,
							"identity":{
								"kind":1,
								"_expr":{"_kind":8,"left":{"_kind":13,"comparison":0,"left":{"_kind":2,"source":{"_kind":0,"entity":"strip-plot-test","kind":0},"ref":"gender","kind":2},"right":{"_kind":17,"type":{"underlyingType":1,"category":{},"primitiveType":1,"extendedType":1,"categoryString":{},"text":true,"numeric":false,"integer":false,"bool":false,"dateTime":false,"duration":false,"binary":false,"none":false},"value":"female","typeEncodedValue":"'female'","valueEncoded":"'female'","kind":17},"kind":13},"right":{"_kind":13,"comparison":0,"left":{"_kind":2,"source":{"_kind":0,"entity":"strip-plot-test","kind":0},"ref":"height","kind":2},"right":{"_kind":17,"type":{"underlyingType":259,"category":{},"primitiveType":3,"extendedType":259,"categoryString":{},"text":false,"numeric":true,"integer":false,"bool":false,"dateTime":false,"duration":false,"binary":false,"none":false},"value":57.50321861,"typeEncodedValue":"57.50321861D","valueEncoded":"57.50321861D","kind":17},"kind":13},"kind":8},
								"_key":{"factoryMethod":{},"value":"{\"and\":{\"l\":{\"comp\":{\"k\":0,\"l\":{\"col\":{\"s\":{\"e\":\"strip-plot-test\"},\"r\":\"gender\"}},\"r\":{\"const\":{\"t\":1,\"v\":\"female\"}}}},\"r\":{\"comp\":{\"k\":0,\"l\":{\"col\":{\"s\":{\"e\":\"strip-plot-test\"},\"r\":\"height\"}},\"r\":{\"const\":{\"t\":3,\"v\":57.50321861}}}}}}"},
								"expr":{"_kind":8,"left":{"_kind":13,"comparison":0,"left":{"_kind":2,"source":{"_kind":0,"entity":"strip-plot-test","kind":0},"ref":"gender","kind":2},"right":{"_kind":17,"type":{"underlyingType":1,"category":{},"primitiveType":1,"extendedType":1,"categoryString":{},"text":true,"numeric":false,"integer":false,"bool":false,"dateTime":false,"duration":false,"binary":false,"none":false},"value":"female","typeEncodedValue":"'female'","valueEncoded":"'female'","kind":17},"kind":13},"right":{"_kind":13,"comparison":0,"left":{"_kind":2,"source":{"_kind":0,"entity":"strip-plot-test","kind":0},"ref":"height","kind":2},"right":{"_kind":17,"type":{"underlyingType":259,"category":{},"primitiveType":3,"extendedType":259,"categoryString":{},"text":false,"numeric":true,"integer":false,"bool":false,"dateTime":false,"duration":false,"binary":false,"none":false},"value":57.50321861,"typeEncodedValue":"57.50321861D","valueEncoded":"57.50321861D","kind":17},"kind":13},"kind":8},"key":"{\"and\":{\"l\":{\"comp\":{\"k\":0,\"l\":{\"col\":{\"s\":{\"e\":\"strip-plot-test\"},\"r\":\"gender\"}},\"r\":{\"const\":{\"t\":1,\"v\":\"female\"}}}},\"r\":{\"comp\":{\"k\":0,\"l\":{\"col\":{\"s\":{\"e\":\"strip-plot-test\"},\"r\":\"height\"}},\"r\":{\"const\":{\"t\":3,\"v\":57.50321861}}}}}}"}
						},
						{
							"levelValues":[
								{
									"levelSourceIndex":0,
									"value":"female"
								},
								{
									"levelSourceIndex":1,
									"value":57.97290083
								}
							]
						},...
					]
				},
				"columns":{
					"levels":[],
					"root":{
						"children":[]
					}
				},
				"valueSources":[]
			},
		"categorical":{},
		"table":{},
		"tree":{},
		"single":{}
	}
]

 

 

 

1 ACCEPTED SOLUTION
paul-maessen
Resolver I
Resolver I

Hi All,

 

It looks like this only works when you are not selecting Don't Summarize for the GroupingOrMeasure-datafield.

When you select an aggregation (it will behave like a measure) then the highlights do appear.

 

Unfortunately this is not going to work for this visual because of the granularity of the values. I need all values and not the aggregates.  So the hightlighting will work for the matrix-dataViewMapping when you select an aggregation for the measure

 

Regards

Paul

View solution in original post

1 REPLY 1
paul-maessen
Resolver I
Resolver I

Hi All,

 

It looks like this only works when you are not selecting Don't Summarize for the GroupingOrMeasure-datafield.

When you select an aggregation (it will behave like a measure) then the highlights do appear.

 

Unfortunately this is not going to work for this visual because of the granularity of the values. I need all values and not the aggregates.  So the hightlighting will work for the matrix-dataViewMapping when you select an aggregation for the measure

 

Regards

Paul

Helpful resources

Announcements
April AMA free

Microsoft Fabric AMA Livestream

Join us Tuesday, April 09, 9:00 – 10:00 AM PST for a live, expert-led Q&A session on all things Microsoft Fabric!

March Fabric Community Update

Fabric Community Update - March 2024

Find out what's new and trending in the Fabric Community.

Top Solution Authors