Προσθήκη υποστήριξης διερεύνησηςAdd Drill-Down support

Οι απεικονίσεις Power BI μπορούν να χρησιμοποιήσουν την άντληση του Power BI.Power BI visuals can use Power BI's drill-down.

Διαβάστε περισσότερα σχετικά με τη διερεύνηση του Power BI εδώRead more about Power BI drill-down here

Ενεργοποίηση της υποστήριξης διερεύνησης στην απεικόνισηEnable drill-down support in the visual

Για υποστήριξη διερεύνησης στην απεικόνισή σας, προσθέστε ένα νέο πεδίο στη διερεύνηση με ονομασία capabilities.json, που διαθέτει μία ιδιότητα:To support drill down in your visual, add a new field to capabilities.json named "drill-down", which has one property:

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

Σημείωση

Το dataRole διερεύνησης πρέπει να είναι τύπου Grouping.The drill-down dataRole must be of Grouping type. Η ιδιότητα max στις προϋποθέσεις dataRole πρέπει να οριστεί σε 1.max property in the dataRole conditions must be set to 1.

Όταν προσθέσετε τον ρόλο στη διερεύνηση, οι χρήστες μπορούν να μεταφέρουν πολλαπλά πεδία στον ρόλο δεδομένων.Once you add the role to drill-down, users can drag multiple fields into the data role.

παράδειγμα:example:

{
    "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"
                            }
                        }
                    ]
                }
            }
        }
    ]
}

Δημιουργία της απεικόνισης με υποστήριξη διερεύνησηςCreate the visual with drill-down support

ΕκτέλεσηRun

pbiviz new testDrillDown -t default

για τη δημιουργία ενός προεπιλεγμένου δείγματος απεικόνισης.to create a default sample visual. Και εφαρμόστε το παραπάνω δείγμα capabilities.json στην απεικόνιση που δημιουργήθηκε μόλις.And apply the above sample of capabilities.json to the newly created visual.

Δημιουργήστε την ιδιότητα για το κοντέινερ div προκειμένου να διατηρεί στοιχεία HTML της απεικόνισης:Create the property for div container to hold HTML elements of the visual:

"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);
    }
}

Ενημερώστε την κατασκευή της απεικόνισης:Update the constructor of the visual:


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);
    }
}

Ενημερώστε τη μέθοδο update της απεικόνισης για να δημιουργήσετε buttons:Update the update method of the visual to create buttons:

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);
        })

    }
    // ...

Εφαρμόστε απλά στυλ στο .\style\visual.less:Apply simple styles in .\style\visual.less:

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

Προετοιμάστε το δείγμα δεδομένων για έλεγχο της απεικόνισης:Prepare sample data to test the visual:

H1H1 H2H2 H3H3 VALUESVALUES
AA A1A1 A11A11 11
AA A1A1 A12A12 22
AA A2A2 A21A21 33
AA A2A2 A22A22 44
AA A3A3 A31A31 55
AA A3A3 A32A32 66
BB B1B1 B11B11 77
BB B1B1 B12B12 88
BB B2B2 B21B21 99
BB B2B2 B22B22 1010
BB B3B3 B31B31 1111
BB B3B3 B32B32 1212

Και δημιουργήστε Ιεραρχία στο Power BI Desktop:And create Hierarchy in Power BI Desktop:

Στιγμιότυπο οθόνης που εμφανίζει το Power BI Desktop με επιλεγμένη την εντολή "Νέα ιεραρχία" σε ένα μενού περιβάλλοντος.

Συμπεριλάβετε όλες τις στήλες κατηγοριών (H1, H2, H3) στη νέα ιεραρχία:Include all category columns (H1, H2, H3) to the new hierarchy:

Στιγμιότυπο οθόνης που εμφανίζει στήλες κατηγοριών που μπορείτε να προσθέσετε στη νέα ιεραρχία.

Ύστερα από αυτά τα βήματα θα πρέπει να λάβετε την ακόλουθη απεικόνιση:After those steps you should get following visual:

Απεικόνιση dev με κουμπιά

Προσθήκη μενού περιβάλλοντος στα οπτικά στοιχείαAdd context menu to visual elements

Σε αυτό το βήμα θα προσθέσετε μενού περιβάλλοντος στο κουμπί στην απεικόνιση:In this step you'll add context menu to the button's on the visual:

Μενού περιβάλλοντος στην απεικόνιση

Για να δημιουργήσετε μενού περιβάλλοντος, αποθηκεύστε το αντικείμενο host στις ιδιότητες της απεικόνισης και καλέστε τη μέθοδο createSelectionManager στη διαχείριση δημιουργίας επιλογών για να εμφανίσετε ένα μενού περιβάλλοντος χρησιμοποιώντας το API Απεικονίσεις Power BI.To create context menu, save host object in the properties of the visual and call createSelectionManager method to the create selection manager to display a context menu by using Power BI Visuals API.

"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
        // ...
    }

    // ...
}

Αλλάξτε το σώμα της επιστροφής κλήσης συνάρτησης forEach σε:Change the body of forEach function callback to:

    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);
    });

Εφαρμογή δεδομένων στην απεικόνιση:Apply data to the visual:

Στιγμιότυπο οθόνης που εμφανίζει την ιεραρχία με επισήμανση της Επικεφαλίδας 2.

Στο τελικό βήμα θα πρέπει να λάβετε απεικόνιση με επιλογές και μενού περιβάλλοντος:In the final step you should get visual with selections and context menu:

Κινούμενο σχέδιο που εμφανίζει λεπτομερή έρευνα και γενίκευση από το μενού περιβάλλοντος απεικόνισης.

Προσθήκη υποστήριξης διερεύνησης για αντιστοίχιση προβολής δεδομένων μήτραςAdd drill-down support for matrix data view mapping

Προετοιμάστε δείγμα δεδομένων για έλεγχο της απεικόνισης με αντιστοιχίσεις προβολής δεδομένων μήτρας:Prepare sample data to test the visual with matrix data view mappings:

Σειρά1Row1 Σειρά2Row2 Σειρά3Row3 Στήλη1Column1 Στήλη2Column2 Column3Column3 ΤιμέςValues
R1R1 R11R11 R111R111 C1C1 C11C11 C111C111 11
R1R1 R11R11 R112R112 C1C1 C11C11 C112C112 22
R1R1 R11R11 R113R113 C1C1 C11C11 C113C113 33
R1R1 R12R12 R121R121 C1C1 C12C12 C121C121 44
R1R1 R12R12 R122R122 C1C1 C12C12 C122C122 55
R1R1 R12R12 R123R123 C1C1 C12C12 C123C123 66
R1R1 R13R13 R131R131 C1C1 C13C13 C131C131 77
R1R1 R13R13 R132R132 C1C1 C13C13 C132C132 88
R1R1 R13R13 R133R133 C1C1 C13C13 C133C133 99
R2R2 R21R21 R211R211 C2C2 C21C21 C211C211 1010
R2R2 R21R21 R212R212 C2C2 C21C21 C212C212 1111
R2R2 R21R21 R213R213 C2C2 C21C21 C213C213 1212
R2R2 R22R22 R221R221 C2C2 C22C22 C221C221 1313
R2R2 R22R22 R222R222 C2C2 C22C22 C222C222 1414
R2R2 R22R22 R223R223 C2C2 C22C22 C223C223 1616
R2R2 R23R23 R231R231 C2C2 C23C23 C231C231 1717
R2R2 R23R23 R232R232 C2C2 C23C23 C232C232 1818
R2R2 R23R23 R233R233 C2C2 C23C23 C233C233 1919

Εφαρμόστε την παρακάτω αντιστοίχιση προβολής δεδομένων για την απεικόνιση:Apply following dataview mapping for the visual:

{
    "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"
                    }
                }
            }
        }
    ]
}

Εφαρμογή δεδομένων στην απεικόνιση:Apply data to the visual:

Στιγμιότυπο οθόνης που εμφανίζει το MatrixHierarchy με επιλεγμένη την ιεραρχία στηλών και γραμμών και τα μέλη τους.

Εισαγάγετε τις απαραίτητες διασυνδέσεις για επεξεργασία των αντιστοιχίσεων προβολής δεδομένων μήτρας:Import required interfaces to process matrix data view mappings:

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

Δημιουργήστε δύο ιδιότητες για δύο div στοιχείων γραμμών και στηλών:Create two properties for two divs of rows and columns elements:

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);
    }
    // ...
}

Ελέγξτε τα δεδομένα πριν την απόδοση στοιχείων και προβάλετε το τρέχον επίπεδο ιεραρχίας:Check the data before rendering elements and display the current level of hierarchy:

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();
        }
        // ...
    }
    // ...
}

Δημιουργήστε τη συνάρτηση treeWalker για να διατρέξετε την ιεραρχία:Create function treeWalker for traverse the hierarchy:

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));
    }
    // ...
}

Δημιουργήστε τις επιλογές για σημεία δεδομένων.Generate the selections for datapoints.

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));
    }
}

Δημιουργήστε ένα div για κάθε επίπεδο ιεραρχίας:Create div for each level of hierarchy:

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));
    }
}

Δημιουργία buttons για αλληλεπίδραση με την απεικόνιση και προβολή του μενού περιβάλλοντος για σημεία δεδομένων μήτρας:Create buttons to interact with visual and display context menu for matrix datapoints:

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) {
        // ...
    }
}

Πραγματοποιήστε απαλοιφή των στοιχείων div προτού αποδώσετε πάλι τα στοιχεία:Clear div elements before render elements again:

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));
}

Στο τελικό βήμα θα πρέπει να λάβετε την απεικόνιση με μενού περιβάλλοντος:At the final step you should get visual with context menu:

Κινούμενο σχέδιο που εμφανίζει ένα μενού περιβάλλοντος για την απεικόνιση με τις επιλογές για λεπτομερή έρευνα ή γενίκευση.

Επόμενα βήματαNext steps

Για περισσότερες πληροφορίες, ανατρέξτε στο θέμα Κατανόηση της αντιστοίχισης προβολής δεδομένων στις απεικονίσεις Power BI.For more information, see Understand data view mapping in Power BI visuals.