Pridanie podpory pre prechod na detaily

Vizuály služby Power BI môžu používať funkciu prechodu na detaily služby Power BI.

Ďalšie informácie o funkcii prechodu na detaily služby Power BI nájdete tu

Povolenie podpory prechodu na detaily vo vizuáli

Ak chcete podporiť akcie prechodu na detaily vo vizuáli, pridajte nové pole capabilities.json s názvom Prechod na detaily, ktoré má jednu vlastnosť:

*roles - the name of the dataRole you want to enable drill-down actions on.

Poznámka

Rola drill-down dataRole musí byť typu Grouping. Vlastnosť max v podmienkach roly dataRole musí byť nastavená na hodnotu 1.

Po pridaní roly do poľa prechodu na detaily môžu používatelia presunúť viacero polí do roly údajov.

Príklad:

{
    "dataRoles": [
        {
            "displayName": "Category",
            "name": "category",
            "kind": "Grouping"
        },
        {
            "displayName": "Value",
            "name": "value",
            "kind": "Measure"
        }
    ],
    "drilldown": {
        "roles": [
            "category"
        ]
    },
    "dataViewMappings": [
        {
            "categorical": {
                "categories": {
                    "for": {
                        "in": "category"
                    }
                },
                "values": {
                    "select": [
                        {
                            "bind": {
                                "to": "value"
                            }
                        }
                    ]
                }
            }
        }
    ]
}

Vytvorenie vizuálu s podporou prechodu na detaily

Spustiť

pbiviz new testDrillDown -t default

vytvorte predvolený vzorový vizuál. Použite vyššie uvedený vzorový súbor capabilities.json na novovytvorený vizuál.

Vytvorte vlastnosť pre kontajner div na uchovanie prvkov HTML vizuálu:

"use strict";

import "core-js/stable";
import "./../style/visual.less";
// imports

export class Visual implements IVisual {
    // visual properties
    // ...
    private div: HTMLDivElement; // <== NEW PROPERTY

    constructor(options: VisualConstructorOptions) {
        // constructor body
        // ...
    }

    public update(options: VisualUpdateOptions) {
        // update method body
        // ...
    }

    private static parseSettings(dataView: DataView): VisualSettings {
        return <VisualSettings>VisualSettings.parse(dataView);
    }

    public enumerateObjectInstances(options: EnumerateVisualObjectInstancesOptions): VisualObjectInstance[] | VisualObjectInstanceEnumerationObject {
        return VisualSettings.enumerateObjectInstances(this.settings || VisualSettings.getDefault(), options);
    }
}

Aktualizujte konštruktor vizuálu:


export class Visual implements IVisual {
    // visual properties
    // ...
    private div: HTMLDivElement;

    constructor(options: VisualConstructorOptions) {
        console.log('Visual constructor', options);
        this.target = options.element;
        this.updateCount = 0;

        const new_p: HTMLElement = document.createElement("p");
        new_p.appendChild(document.createTextNode("Hierarchy level:"));
        const new_em: HTMLElement = document.createElement("em");
        this.textNode = document.createTextNode(this.updateCount.toString());
        new_em.appendChild(this.textNode);
        new_p.appendChild(new_em);
        this.target.appendChild(new_p);

        this.div = document.createElement("div"); // <== CREATE DIV ELEMENT
        this.target.appendChild(this.div);
    }
}

Aktualizujte metódu update vizuálu na vytvorenie tlačidiel button:

export class Visual implements IVisual {
    // ...

    public update(options: VisualUpdateOptions) {
        this.settings = Visual.parseSettings(options && options.dataViews && options.dataViews[0]);
        console.log('Visual update', options);

        const dataView: DataView = options.dataViews[0];
        const categoricalDataView: DataViewCategorical = dataView.categorical;

        // don't create elements if no data
        if (!options.dataViews[0].categorical ||
            !options.dataViews[0].categorical.categories) {
            return
        }

        // to display current level of hierarchy
        if (typeof this.textNode !== undefined) {
            this.textNode.textContent = categoricalDataView.categories[categoricalDataView.categories.length - 1].source.displayName.toString();
        }

        // remove old elements
        // for better performance use D3js pattern:
        // https://d3js.org/#enter-exit
        while (this.div.firstChild) {
            this.div.removeChild(this.div.firstChild);
        }

        // create buttons for each category value
        categoricalDataView.categories[categoricalDataView.categories.length - 1].values.forEach( (category: powerbi.PrimitiveValue, index: number) => {
            let button = document.createElement("button");
            button.innerText = category.toString();

            this.div.appendChild(button);
        })

    }
    // ...

Použite jednoduché štýly v časti .\style\visual.less:

button {
    margin: 5px;
    min-width: 50px;
    min-height: 50px;
}

Pripravte vzorové údaje na testovanie vizuálu:

H1 H2 H3 HODNOTY
A A1 A11 1
A A1 A12 2
A A2 A21 3
A A2 A22 4
A A3 A31 5
A A3 A32 6
B B1 B11 7
B B1 B12 8
B B2 B21 9
B B2 B22 10
B B3 B31 11
B B3 B32 12

Vytvorte hierarchiu v aplikácii Power BI Desktop:

Snímka obrazovky zobrazuje Power B I Desktop s novou hierarchiou vybratou v kontextovej ponuke.

Zahrňte do novej hierarchie všetky stĺpce kategórií (H1, H2, H3):

Snímka obrazovky zobrazuje stĺpce kategórií, ktoré môžete pridať do novej hierarchie.

Po týchto krokoch by ste mali získať nasledujúci vizuál:

Vizuál dev s tlačidlami

Pridanie kontextovej ponuky do prvkov vizuálu

V tomto kroku pridáte kontextovú ponuku do tlačidla vo vizuáli:

Kontextová ponuka vo vizuáli

Ak chcete vytvoriť kontextovú ponuku, uložte objekt host vo vlastnostiach vizuálu a zavolaním metódy createSelectionManager vytvorte funkciu Selection Manager, ktorá zobrazí kontextovú ponuku pomocou rozhrania API vizuálov služby Power BI.

"use strict";

import "core-js/stable";
import "./../style/visual.less";
// imports

import powerbiVisualsApi from "powerbi-visuals-api";
import ISelectionManager = powerbiVisualsApi.extensibility.ISelectionManager;
import ISelectionId = powerbiVisualsApi.visuals.ISelectionId;
import ISelectionIdBuilder = powerbiVisualsApi.visuals.ISelectionIdBuilder;

export class Visual implements IVisual {
    // visual properties
    // ...
    private div: HTMLDivElement;
    private host: IVisualHost; // <== NEW PROPERTY
    private selectionManager: ISelectionManager; // <== NEW PROPERTY

    constructor(options: VisualConstructorOptions) {
        // constructor body
        // save the host in the visuals properties
        this.host = options.host;
        // create selection manager
        this.selectionManager = this.host.createSelectionManager();
        // ...
    }

    public update(options: VisualUpdateOptions) {
        // update method body
        // ...
    }

    // ...
}

Zmeňte telo spätného volania funkcie forEach na:

    categoricalDataView.categories[categoricalDataView.categories.length - 1].values.forEach( (category: powerbi.PrimitiveValue, index: number) => {
        // create selectionID for each category value
        let selectionID: ISelectionID = this.host.createSelectionIdBuilder()
            .withCategory(categoricalDataView.categories[0], index)
            .createSelectionId();

        let button = document.createElement("button");
        button.innerText = category.toString();

        // add event listener to click event
        button.addEventListener("click", (event) => {
            // call select method in the selection manager
            this.selectionManager.select(selectionID);
        });

        button.addEventListener("contextmenu", (event) => {
            // call showContextMenu method to display context menu on the visual
            this.selectionManager.showContextMenu(selectionID, {
                x: event.clientX,
                y: event.clientY
            });
            event.preventDefault();
        });

        this.div.appendChild(button);
    });

Použite údaje na vizuál:

Snímka obrazovky zobrazuje hierarchiu používajúcu stĺpec kategórií H2.

V poslednom kroku by ste mali získať vizuál s výbermi a kontextovou ponukou:

Animácia zobrazuje výber prechodu na detaily a prechod na súhrn v kontextovej ponuke vizuálu.

Pridanie podpory prechodu na detaily pre priradenie zobrazenia maticových údajov

Pripravte vzorové údaje na testovanie vizuálu s priradeniami zobrazenia maticových údajov:

Riadok1 Riadok2 Riadok3 Stĺpec1 Stĺpec2 Stĺpec3 Hodnoty
R1 R11 R111 S1 S11 S111 1
R1 R11 R112 S1 S11 S112 2
R1 R11 R113 S1 S11 S113 3
R1 R12 R121 S1 S12 S121 4
R1 R12 R122 S1 S12 S122 5
R1 R12 R123 S1 S12 S123 6
R1 R13 R131 S1 S13 S131 7
R1 R13 R132 S1 S13 S132 8
R1 R13 R133 S1 S13 S133 9
R2 R21 R211 S2 S21 S211 10
R2 R21 R212 S2 S21 S212 11
R2 R21 R213 S2 S21 S213 12
R2 R22 R221 S2 S22 S221 13
R2 R22 R222 S2 S22 S222 14
R2 R22 R223 S2 S22 S223 16
R2 R23 R231 S2 S23 S231 17
R2 R23 R232 S2 S23 S232 18
R2 R23 R233 S2 S23 S233 19

Použite nasledujúce priradenie zobrazenia údajov pre vizuál:

{
    "dataRoles": [
        {
            "displayName": "Columns",
            "name": "columns",
            "kind": "Grouping"
        },
        {
            "displayName": "Rows",
            "name": "rows",
            "kind": "Grouping"
        },
        {
            "displayName": "Value",
            "name": "value",
            "kind": "Measure"
        }
    ],
    "drilldown": {
        "roles": [
            "columns",
            "rows"
        ]
    },
    "dataViewMappings": [
        {
            "matrix": {
                "columns": {
                    "for": {
                        "in": "columns"
                    }
                },
                "rows": {
                    "for": {
                        "in": "rows"
                    }
                },
                "values": {
                    "for": {
                        "in": "value"
                    }
                }
            }
        }
    ]
}

Použite údaje na vizuál:

Snímka obrazovky zobrazuje hierarchiu MatrixHierarchy s vybratou hierarchiou stĺpcov a riadkov a ich členmi.

Importujte požadované rozhrania na spracovanie priradení zobrazenia maticových údajov:

// ...
import DataViewMatrix = powerbi.DataViewMatrix;
import DataViewMatrixNode = powerbi.DataViewMatrixNode;
import DataViewHierarchyLevel = powerbi.DataViewHierarchyLevel;
// ...

Vytvorte dve vlastnosti pre dva prvky riadkov a stĺpcov div:

export class Visual implements IVisual {
    // ...
    private rowsDiv: HTMLDivElement;
    private colsDiv: HTMLDivElement;
    // ...
    constructor(options: VisualConstructorOptions) {
        // constructor body
        // ...
        // Create div elements and append to main div of the visual
        this.rowsDiv = document.createElement("div");
        this.target.appendChild(this.rowsDiv);

        this.colsDiv = document.createElement("div");
        this.target.appendChild(this.colsDiv);
    }
    // ...
}

Pred vykreslením prvkov skontrolujte údaje a zobrazte aktuálnu úroveň hierarchie:

export class Visual implements IVisual {
    // ...
    constructor(options: VisualConstructorOptions) {
        // constructor body
    }

    public update(options: VisualUpdateOptions) {
        this.settings = Visual.parseSettings(options && options.dataViews && options.dataViews[0]);
        console.log('Visual update', options);

        const dataView: DataView = options.dataViews[0];
        const matrixDataView: DataViewMatrix = dataView.matrix;

        // if the visual doesn't receive the data no reason to continue rendering
        if (!matrixDataView ||
            !matrixDataView.columns ||
            !matrixDataView.rows ) {
            return
        }

        // to display current level of hierarchy
        if (typeof this.textNode !== undefined) {
            this.textNode.textContent = categoricalDataView.categories[categoricalDataView.categories.length - 1].source.displayName.toString();
        }
        // ...
    }
    // ...
}

Vytvorte funkciu treeWalker na prechádzanie hierarchiou:

export class Visual implements IVisual {
    // ...
    public update(options: VisualUpdateOptions) {
        // ...

        // if the visual doesn't receive the data no reason to continue rendering
        if (!matrixDataView ||
            !matrixDataView.columns ||
            !matrixDataView.rows ) {
            return
        }

        const treeWalker = (matrixNode: DataViewMatrixNode, index: number, levels: DataViewHierarchyLevel[], div: HTMLDivElement)  => {
            // ...
            if (matrixNode.children) {
                // ...
                // traversing child nodes
                matrixNode.children.forEach((node, index) => treeWalker(node, index, levels, childDiv));
            }
        }

        // traversing rows
        const rowRoot: DataViewMatrixNode = matrixDataView.rows.root;
        rowRoot.children.forEach((node, index) => treeWalker(node, index, matrixDataView.rows.levels, this.rowsDiv));

        // traversing columns
        const colRoot = matrixDataView.columns.root;
        colRoot.children.forEach((node, index) => treeWalker(node, index, matrixDataView.columns.levels, this.colsDiv));
    }
    // ...
}

Vygenerujte výbery pre údajové body.

const treeWalker = (matrixNode: DataViewMatrixNode, index: number, levels: DataViewHierarchyLevel[], div: HTMLDivElement)  => {
    // generate selectionID for each node of matrix
    const selectionID: ISelectionID = this.host.createSelectionIdBuilder()
        .withMatrixNode(matrixNode, levels)
        .createSelectionId();
    // ...
    if (matrixNode.children) {
        // ...
        // traversing child nodes
        matrixNode.children.forEach((node, index) => treeWalker(node, index, levels, childDiv));
    }
}

Vytvorte prvok div pre každú úroveň hierarchie:

const treeWalker = (matrixNode: DataViewMatrixNode, index: number, levels: DataViewHierarchyLevel[], div: HTMLDivElement)  => {
    // generate selectionID for each node of matrix
    const selectionID: ISelectionID = this.host.createSelectionIdBuilder()
        .withMatrixNode(matrixNode, levels)
        .createSelectionId();
    // ...
    if (matrixNode.children) {
        // create div element for level
        const childDiv = document.createElement("div");
        // add to current div
        div.appendChild(childDiv);
        // create paragraph element to display next
        const p = document.createElement("p");
        // display level name on paragraph element
        const level = levels[matrixNode.level];
        p.innerText = level.sources[level.sources.length - 1].displayName;
        // add paragraph element to created child div
        childDiv.appendChild(p);
        // traversing child nodes
        matrixNode.children.forEach((node, index) => treeWalker(node, index, levels, childDiv));
    }
}

Vytvorte tlačidlá buttons na interakciu s vizuálom a zobrazenie kontextovej ponuky pre údajové body matice:

const treeWalker = (matrixNode: DataViewMatrixNode, index: number, levels: DataViewHierarchyLevel[], div: HTMLDivElement)  => {
    // generate selectionID for each node of matrix
    const selectionID: ISelectionID = this.host.createSelectionIdBuilder()
        .withMatrixNode(matrixNode, levels)
        .createSelectionId();

    // create button element
    let button = document.createElement("button");
    // display node value/name of the button's text
    button.innerText = matrixNode.value.toString();

    // add event listener on click
    button.addEventListener("click", (event) => {
        // call select method in the selection manager
        this.selectionManager.select(selectionID);
    });

    // display context menu on click
    button.addEventListener("contextmenu", (event) => {
        // call showContextMenu method to display context menu on the visual
        this.selectionManager.showContextMenu(selectionID, {
            x: event.clientX,
            y: event.clientY
        });
        event.preventDefault();
    });

    div.appendChild(button);

    if (matrixNode.children) {
        // ...
    }
}

Znova vymažte prvky div pred prvkami vykreslenia:

public update(options: VisualUpdateOptions) {
    // ...
    const treeWalker = (matrixNode: DataViewMatrixNode, index: number, levels: DataViewHierarchyLevel[], div: HTMLDivElement)  => {
        // ...
    }

    // remove old elements
    // to better performance use D3js pattern:
    // https://d3js.org/#enter-exit
    while (this.rowsDiv.firstChild) {
        this.rowsDiv.removeChild(this.rowsDiv.firstChild);
    }
    // create label for row elements
    const prow = document.createElement("p");
    prow.innerText = "Rows";
    this.rowsDiv.appendChild(prow);

    while (this.colsDiv.firstChild) {
        this.colsDiv.removeChild(this.colsDiv.firstChild);
    }
    // create label for columns elements
    const pcol = document.createElement("p");
    pcol.innerText = "Columns";
    this.colsDiv.appendChild(pcol);

    // render elements for rows
    const rowRoot: DataViewMatrixNode = matrixDataView.rows.root;
    rowRoot.children.forEach((node, index) => treeWalker(node, index, matrixDataView.rows.levels, this.rowsDiv));

    // render elements for columns
    const colRoot = matrixDataView.columns.root;
    colRoot.children.forEach((node, index) => treeWalker(node, index, matrixDataView.columns.levels, this.colsDiv));
}

V poslednom kroku by ste mali získať vizuál s kontextovou ponukou:

Animácia zobrazuje kontextovú ponuku vizuálu s možnosťami prechod na detaily alebo na prechod na súhrn.

Ďalšie kroky

Ďalšie informácie nájdete v téme Vysvetlenie priradenia zobrazenia údajov vo vizuáloch služby Power BI.