Opplæring: Bygge et stolpediagram

Denne opplæringen viser deg hvordan du utvikler et Power BI-visualobjekt som viser data i form av et enkelt stolpediagram. Dette visualobjektet støtter en minimal tilpasningsmengde. Andre sider i denne dokumentasjonen forklarer hvordan du legger til ytterligere tilpasninger, for eksempel hurtigmenyer, verktøytips og mer.

I denne opplæringen lærer du hvordan du kan gjøre følgende:

  • Definer funksjonene i visualobjektet
  • Forstå kildekoden som brukes til å bygge et visualobjekt
  • Gjengi visualobjektet
  • Legge til objekter i egenskapsruten
  • Pakke visualobjektet

Konfigurer miljøet ditt

Før du begynner å utvikle Power BI-visualobjektet, må du kontrollere at du har alt oppført i denne delen.

Merk

Hvis D3 JavaScript-biblioteket ikke ble installert som en del av installasjonen, må du installere det nå. Kjør fra PowerShell npm i d3@latest --save

Oppretting av et visualobjekt for stolpediagram omfatter følgende trinn:

  1. Opprett et nytt prosjekt
  2. Definer egenskapsfilen -capabilities.json
  3. Opprett visualobjekt-API-en
  4. Pakk visualobjektet ditt -pbiviz.json

Opprette et nytt prosjekt

Formålet med denne opplæringen er å hjelpe deg med å forstå hvordan et visualobjekt er strukturert og skrevet. Du kan følge disse instruksjonene for å opprette et strekkodevisualobjekt fra grunnen av, eller du kan klone kildekoderepositoriet og bruke det til å følge med uten å opprette ditt eget visualobjekt.

  1. Åpne PowerShell , og gå til mappen du vil opprette prosjektet i.

  2. Skriv inn følgende kommando:

    pbiviz new BarChart
    

    Nå skal du ha en mappe kalt BarChart som inneholder filene til visualobjektet.

  3. Åpne filen [tsconfig.json] (visual-project-structure.md#tsconfigjson) i VS Code, og endre navnet på "filer" til "src/barChart.ts".

    "files": [
    "src/barChart.ts"
    ]
    

    Objektet tsconfig.json "files" peker til filen der hovedklassen for visualobjektet er plassert.

    Den endelige tsconfig.json-filen skal se slik ut.

  4. Package.json-filen inneholder en liste over prosjektavhengigheter. Erstatt package.json-filen med denne.

Nå skal du ha en ny mappe for visualobjektet med følgende filer og mapper:

Screenshot showing the structure of visuals.

Hvis du vil ha en detaljert forklaring av funksjonen til hver av disse filene, kan du se prosjektstrukturen for VisualObjekter i Power BI.

De to filene vi fokuserer på i denne opplæringen , er capabilities.json-filen , som beskriver visualobjektet for verten, og src/barchart.ts-filen , som inneholder visualobjektets API.

Definer funksjoner

Capabilities.json-filen er der vi binder data til verten. Vi beskriver hvilken type datafelt den godtar, og hvilke funksjoner visualobjektet skal ha.

Screenshot showing how to bind data in the field bucket.

Definer dataroller

Variabler er definert og bundet i dataRoles delen av egenskapsfilen. Vi vil at stolpediagrammet skal godta to typer variabler:

  • Kategoriske data representert av de ulike stolpene i diagrammet
  • Numeriske eller målte data, som representeres av høyden på hver stolpe

I Visual Studio Code, i capabilities.json-filen , bekrefter du at følgende JSON-fragment vises i objektet kalt "dataRoles".

    "dataRoles": [
        {
            "displayName": "Category Data",
            "name": "category",
            "kind": "Grouping"
        },
        {
            "displayName": "Measure Data",
            "name": "measure",
            "kind": "Measure"
        }
    ],

Tilordne dataene

Deretter legger du til datatilordning for å fortelle verten hva de skal gjøre med disse variablene:

Erstatt innholdet i dataViewMappings-objektet med følgende kode:

"dataViewMappings": [
        {
            "conditions": [
                {
                    "category": {
                        "max": 1
                    },
                    "measure": {
                        "max": 1
                    }
                }
            ],
            "categorical": {
                "categories": {
                    "for": {
                        "in": "category"
                    }
                },
                "values": {
                    "select": [
                        {
                            "bind": {
                                "to": "measure"
                            }
                        }
                    ]
                }
            }
        }
    ],

Koden ovenfor oppretter betingelsene som hvert datarolleobjekt bare kan inneholde ett felt om gangen. Legg merke til at vi bruker datarollens interne name til å referere til hvert felt.

Den angir også den kategoriske datatilordningen slik at hvert felt tilordnes riktig variabel.

Definer objekter for egenskapsruten

Objekter-delen i egenskapsfilen er der vi definerer funksjonene som kan tilpasses, som skal vises i formatruten. Disse funksjonene påvirker ikke innholdet i diagrammet, men de kan endre utseendet og funksjonaliteten.

Hvis du vil ha mer informasjon om objekter og hvordan de fungerer, kan du se Objekter.

Følgende objekter er valgfrie. Legg dem til hvis du vil gå gjennom de valgfrie delene av denne opplæringen for å legge til farger og gjengi X-aksen.

Erstatt innholdet i objektdelen med følgende kode:

     "objects": {
        "enableAxis": {
            "properties": {
                "show": {
                    "type": {
                        "bool": true
                    }
                },
                "fill": {
                    "type": {
                        "fill": {
                            "solid": {
                                "color": true
                            }
                        }
                    }
                }
            }
        }
     },

Lagre capabilities.json-filen.

Den endelige funksjonsfilen skal se ut som den i dette eksemplet.

Visualobjekt-API

Alle visualobjekter starter med en klasse som implementerer grensesnittet IVisual . Src /visual.ts-filen er standardfilen som inneholder denne klassen.

I denne opplæringen kaller vi fillinjenChart.ts IVisual. Last ned filen og lagre den i /src-mappen hvis du ikke allerede har gjort det. I denne delen går vi gjennom denne filen i detalj og beskriver de ulike inndelingene.

Importer

Den første delen av filen importerer modulene som kreves for dette visualobjektet. Legg merke til at vi i tillegg til Power BI-visualobjektmodulene også importerer d3-biblioteket.

Følgende moduler importeres til barChart.ts-filen :

import {
    scaleBand, scaleLinear
} from "d3-scale";
import {
    select as d3Select
} from "d3-selection";
import "./../style/visual.less";

import { axisBottom } from "d3-axis";

import powerbiVisualsApi from "powerbi-visuals-api";
import powerbi = powerbiVisualsApi;

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

import DataViewCategoryColumn = powerbi.DataViewCategoryColumn;
import DataViewObjects = powerbi.DataViewObjects;
import Fill = powerbi.Fill;
import ISandboxExtendedColorPalette = powerbi.extensibility.ISandboxExtendedColorPalette;
import ISelectionId = powerbi.visuals.ISelectionId;
import IVisual = powerbi.extensibility.IVisual;
import IVisualHost = powerbi.extensibility.visual.IVisualHost;
import PrimitiveValue = powerbi.PrimitiveValue;
import VisualUpdateOptions = powerbi.extensibility.visual.VisualUpdateOptions;
import VisualConstructorOptions = powerbi.extensibility.visual.VisualConstructorOptions;

import { textMeasurementService } from "powerbi-visuals-utils-formattingutils";

import { dataViewWildcard } from "powerbi-visuals-utils-dataviewutils";
import { getCategoricalObjectValue, getValue } from "./objectEnumerationUtility";

Grensesnitt

Deretter definerer vi viewmodel-grensesnittene. Følgende tre grensesnitt brukes til å beskrive stolpediagrammet:

  • BarChartDataPoint
  • BarChartViewModel
  • BarDiagram Innstillinger

Disse grensesnittene er definert som følger:

/**
 * Interface for BarCharts viewmodel.
 *
 * @interface
 * @property {BarChartDataPoint[]} dataPoints - Set of data points the visual will render.
 * @property {number} dataMax                 - Maximum data value in the set of data points.
 */
interface BarChartViewModel {
    dataPoints: BarChartDataPoint[];
    dataMax: number;
    settings: BarChartSettings;
}

/**
 * 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.
 * @property {ISelectionId} selectionId - Id assigned to data point for cross filtering
 *                                        and visual interaction.
 */
interface BarChartDataPoint {
    value: PrimitiveValue;
    category: string;
    color: string;
    strokeColor: string;
    strokeWidth: number;
    selectionId: ISelectionId;
}

/**
 * Interface for BarChart settings.
 *
 * @interface
 * @property {{show:boolean}} enableAxis - Object property that allows axis to be enabled.
*/
interface BarChartSettings {
    enableAxis: {
        show: boolean;
        fill: string;
    };
}

let defaultSettings: BarChartSettings = {
    enableAxis: {
        show: false,
        fill: "#000000",
    }
};

Visuell transformering

Nå som datastrukturene er definert, må vi tilordne data til dem ved hjelp av visualTransform funksjonen. Denne funksjonen mottar data fra datavisningen og transformerer den til et format visualobjektet kan bruke. I dette tilfellet returnerer det grensesnittet BarChartViewModel som er beskrevet i forrige del.

Inneholder DataView dataene som skal visualiseres. Disse dataene kan være i forskjellige skjemaer, for eksempel kategorisk eller tabell. Hvis du vil bygge et kategorisk visualobjekt som et stolpediagram, bruker du den kategoriske egenskapen på DataView.

Denne funksjonen kalles når visualobjektet oppdateres.

/**
 * Function that converts queried data into a viewmodel that will be used by the visual.
 *
 * @function
 * @param {VisualUpdateOptions} options - Contains references to the size of the container
 *                                        and the dataView which contains all the data
 *                                        the visual had queried.
 * @param {IVisualHost} host            - Contains references to the host which contains services
 */
function visualTransform(options: VisualUpdateOptions, host: IVisualHost): BarChartViewModel {
    let dataViews = options.dataViews;
    let viewModel: BarChartViewModel = {
        dataPoints: [],
        dataMax: 0,
        settings: <BarChartSettings>{}
    };

    if (!dataViews
        || !dataViews[0]
        || !dataViews[0].categorical
        || !dataViews[0].categorical.categories
        || !dataViews[0].categorical.categories[0].source
        || !dataViews[0].categorical.values
    ) {
        return viewModel;
    }

    let categorical = dataViews[0].categorical;
    let category = categorical.categories[0];
    let dataValue = categorical.values[0];

    let barChartDataPoints: BarChartDataPoint[] = [];
    let dataMax: number;

    let colorPalette: ISandboxExtendedColorPalette = host.colorPalette;
    let objects = dataViews[0].metadata.objects;

    const strokeColor: string = getColumnStrokeColor(colorPalette);

    let barChartSettings: BarChartSettings = {
        enableAxis: {
            show: getValue<boolean>(objects, 'enableAxis', 'show', defaultSettings.enableAxis.show),
            fill: getAxisTextFillColor(objects, colorPalette, defaultSettings.enableAxis.fill),
        }
    };

    const strokeWidth: number = getColumnStrokeWidth(colorPalette.isHighContrast);

    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]}`,
        });
    }

    dataMax = <number>dataValue.maxLocal;

    return {
        dataPoints: barChartDataPoints,
        dataMax: dataMax,
        settings: barChartSettings,
    };
}

Merk

De neste funksjonene i barChart.ts-filen handler om farge og oppretting av X-aksen. Disse er valgfrie og diskuteres lenger ned i denne opplæringen. Denne opplæringen IVisual fortsetter fra funksjonen.

Gjengi visualobjektet

Når dataene er definert, gjengir vi visualobjektet ved hjelp av BarChart-klassen som implementerer grensesnittetIVisual . Grensesnittet IVisual er beskrevet på visualobjekt-API-siden . Den inneholder en constructor metode som oppretter visualobjektet og en update metode som kalles hver gang visualobjektet laster inn på nytt. Før vi gjengir visualobjektet, må vi erklære medlemmene av klassen:

export class BarChart implements IVisual {
    private svg: Selection<any>;
    private host: IVisualHost;
    private barContainer: Selection<SVGElement>;
    private xAxis: Selection<SVGElement>;
    private barDataPoints: BarChartDataPoint[];
    private barChartSettings: BarChartSettings;

    private barSelection: d3.Selection<d3.BaseType, any, d3.BaseType, any>;

    static Config = {
        xScalePadding: 0.1,
        solidOpacity: 1,
        transparentOpacity: 1,
        margins: {
            top: 0,
            right: 0,
            bottom: 25,
            left: 30,
        },
        xAxisFontMultiplier: 0.04,
    }
 }

Konstruere visualobjektet

Konstruktørfunksjonen kalles bare én gang, når visualobjektet gjengis for første gang. Det oppretter tomme SVG-beholdere for stolpediagrammet og X-aksen. Legg merke til at det bruker d3-biblioteket til å gjengi SVG.

/**
     * Creates instance of BarChart. This method is only called once.
     *
     * @constructor
     * @param {VisualConstructorOptions} options - Contains references to the element that will
     *                                             contain the visual and a reference to the host
     *                                             which contains services.
     */
    constructor(options: VisualConstructorOptions) {
        this.host = options.host;

        this.svg = d3Select(options.element)
            .append('svg')
            .classed('barChart', true);

        this.barContainer = this.svg
            .append('g')
            .classed('barContainer', true);

        this.xAxis = this.svg
            .append('g')
            .classed('xAxis', true);
    }

Oppdatere visualobjektet

Oppdateringsmetoden kalles hver gang størrelsen på visualobjektet eller en av verdiene endres.

Skalering

Vi må skalere visualobjektet slik at antall stolper og gjeldende verdier passer inn i de definerte bredde- og høydegrensene for visualobjektet. Dette ligner på oppdateringsmetoden i sirkelkortopplæringen.

Hvis du vil beregne skalaen, bruker scaleLinear vi metodene og scaleBand metodene som ble importert tidligere fra d3-scale biblioteket.

Verdien viewModel.datamax har den største verdien av alle gjeldende datapunkter. Denne verdien brukes til å bestemme høyden på y-aksen. Skaleringen for bredden på x-aksen bestemmes av antall kategorier som er bundet til visualobjektet i grensesnittet barchartdatapoint .

For tilfeller der X-aksen gjengis, håndterer dette visualobjektet også ordskift i tilfelle det ikke er nok plass til å skrive ut hele navnet på X-aksen.

Andre oppdateringsfunksjoner

I tillegg til skalering håndterer oppdateringsmetoden også valg og farger. Disse funksjonene er valgfrie og diskuteres senere:

   /**
     * Updates the state of the visual. Every sequential databinding and resize will call update.
     *
     * @function
     * @param {VisualUpdateOptions} options - Contains references to the size of the container
     *                                        and the dataView which contains all the data
     *                                        the visual had queried.
     */
    public update(options: VisualUpdateOptions) {
        let viewModel: BarChartViewModel = visualTransform(options, this.host);
        let settings = this.barChartSettings = viewModel.settings;
        this.barDataPoints = viewModel.dataPoints;

        let width = options.viewport.width;
        let height = options.viewport.height;

        this.svg
            .attr("width", width)
            .attr("height", height);

        if (settings.enableAxis.show) {
            let margins = BarChart.Config.margins;
            height -= margins.bottom;
        }

        this.xAxis
            .style("font-size", Math.min(height, width) * BarChart.Config.xAxisFontMultiplier)
            .style("fill", settings.enableAxis.fill);

        let yScale = scaleLinear()
            .domain([0, viewModel.dataMax])
            .range([height, 0]);

        let xScale = scaleBand()
            .domain(viewModel.dataPoints.map(d => d.category))
            .rangeRound([0, width])
            .padding(0.2);

        let xAxis = axisBottom(xScale);

        const colorObjects = options.dataViews[0] ? options.dataViews[0].metadata.objects : null;
        this.xAxis.attr('transform', 'translate(0, ' + height + ')')
            .call(xAxis)
            .attr("color", getAxisTextFillColor(
                colorObjects,
                this.host.colorPalette,
                defaultSettings.enableAxis.fill
            ));

        const textNodes = this.xAxis.selectAll("text")
        BarChart.wordBreak(textNodes, xScale.bandwidth(), height);

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

    }

    private static wordBreak(
        textNodes: Selection<any, SVGElement>,
        allowedWidth: number,
        maxHeight: number
    ) {
        textNodes.each(function () {
            textMeasurementService.wordBreak(
                this,
                allowedWidth,
                maxHeight);
        });
    }

Fylle ut egenskapsruten

Den endelige metoden i IVisual funksjonen er getFormattingModel. Denne metoden bygger og returnerer et moderne formatruteformateringsmodellobjekt som inneholder alle formatrutens komponenter og egenskaper. Deretter plasserer du objektet i Format-ruten . I vårt tilfelle oppretter vi formatkort for enableAxis og colorSelector, inkludert formateringsegenskaper for show og fill, i henhold til "objekter" i capabilities.json-filen .

Hvis du vil bygge en formateringsmodell, bør utvikleren være kjent med alle komponentene, sjekke ut komponentene i formatruten i formatruten.

Hvis du vil legge til en fargevelger for hver kategori i egenskapsruten , legger du til en for løkke på barDataPoints og legger til en ny fargevelgerformategenskap i formateringsmodellen.

    /** Gets the settings to display in the formatting pane */
    public getFormattingModel(): powerbi.visuals.FormattingModel {
        const enableAxisCard: powerbi.visuals.FormattingCard = {
            displayName: "Enable Axis",
            uid: "enableAxisCard_uid",
            topLevelToggle: {
                uid: "enableAxisCard_topLevelToggle_showToggleSwitch_uid",
                suppressDisplayName: true,
                control: {
                    type: powerbi.visuals.FormattingComponent.ToggleSwitch,
                    properties: {
                        descriptor: {
                            objectName: "enableAxis",
                            propertyName: "show"
                        },
                        value: this.barChartSettings.enableAxis.show
                    }
                }
            },
            groups: [{
                displayName: undefined,
                uid: "enableAxisCard_group1_uid",
                slices: [
                    {
                        uid: "enableAxisCard_group1_fill_uid",
                        displayName: "Color",
                        control: {
                            type: powerbi.visuals.FormattingComponent.ColorPicker,
                            properties: {
                                descriptor: {
                                    objectName: "enableAxis",
                                    propertyName: "fill"
                                },
                                value: { value: this.barChartSettings.enableAxis.fill }
                            }
                        }
                    }
                ],
            }],
            revertToDefaultDescriptors: [
                {
                    objectName: "enableAxis",
                    propertyName: "show"
                },
                {
                    objectName: "enableAxis",
                    propertyName: "fill"
                }
            ]
        };

        const colorSelectorCard: powerbi.visuals.FormattingCard = {
            displayName: "Data Colors",
            uid: "dataColorsCard_uid",
            groups: [{
                displayName: undefined,
                uid: "dataColorsCard_group_uid",

                slices: [],
            }]
        };

        if (this.barDataPoints) {
            this.barDataPoints.forEach(dataPoint => {
                (colorSelectorCard.groups[0] as powerbi.visuals.FormattingGroup).slices.push(
                    {
                        uid: `dataColorsCard_group_colorSelector${dataPoint.category}_uid`,
                        displayName: dataPoint.category,
                        control: {
                            type: powerbi.visuals.FormattingComponent.ColorPicker,
                            properties: {
                                descriptor: {
                                    objectName: "colorSelector",
                                    propertyName: "fill",
                                    selector: dataViewWildcard.createDataViewWildcardSelector(dataViewWildcard.DataViewWildcardMatchingOption.InstancesAndTotals),
                                    altConstantValueSelector: dataPoint.selectionId.getSelector(),
                                    instanceKind: powerbi.VisualEnumerationInstanceKinds.ConstantOrRule
                                },
                                value: { value: dataPoint.color }
                            }
                        }
                    });
            });

            colorSelectorCard.revertToDefaultDescriptors = [
                {
                    objectName: "colorSelector",
                    propertyName: "fill"
                }
            ]
        }
        return { cards: [enableAxisCard, colorSelectorCard] };
    } 

(Valgfritt) Fylle ut egenskapsruten ved hjelp av formateringsmodellen Utils

Fyll ut egenskapsruten ved hjelp av getFormattingModel API-en i formateringsmodellrepositoriet.

Hvis du vil ha den fullstendige koden for et eksempel på stolpediagram med formateringsmodellverktøy, kan du se liggende stolpediagramrepositorium.

Deklarer formateringsegenskaper og deres verdier i en klasse for formateringsinnstillinger:

import powerbi from "powerbi-visuals-api";
import { dataViewWildcard } from "powerbi-visuals-utils-dataviewutils";
import { formattingSettings } from "powerbi-visuals-utils-formattingmodel";
import { BarChartDataPoint } from "./barChart";

import FormattingSettingsCard = formattingSettings.SimpleCard;
import FormattingSettingsSlice = formattingSettings.Slice;
import FormattingSettingsModel = formattingSettings.Model;

/**
 * Enable Axis Formatting Card
 */
class EnableAxisCardSettings extends FormattingSettingsCard {
    // Formatting property `show` toggle switch (formatting simple slice)
    show = new formattingSettings.ToggleSwitch({
        name: "show",
        displayName: undefined,
        value: false,
        topLevelToggle: true,
        show: true
    });

    // Formatting property `fill` color picker (formatting simple slice)
    fill = new formattingSettings.ColorPicker({
        name: "fill",
        displayName: "Color",
        value: { value: "#000000" },
        show: true
    });

    name: string = "enableAxis";
    displayName: string = "Enable Axis";
    show: boolean = true;
    slices: Array<FormattingSettingsSlice> = [this.show, this.fill];
}

/**
 * Color Selector Formatting Card
 */

class ColorSelectorCardSettings extends FormattingSettingsCard {
    name: string = "colorSelector";
    displayName: string = "Data Colors";

    // slices will be populated in barChart settings model `populateColorSelector` method
    slices: Array<FormattingSettingsSlice> = [];
}

/**
* BarChart settings model class
*
*/
export class BarChartSettingsModel extends FormattingSettingsModel {

    // Create formatting settings model formatting cards
    enableAxis = new EnableAxisCardSettings();
    colorSelector = new ColorSelectorCardSettings();
    cards = [this.enableAxis, this.colorSelector];

    /**
     * populate colorSelector object categories formatting properties
     * @param dataPoints 
     */
    populateColorSelector(dataPoints: BarChartDataPoint[]) {
        let slices = this.colorSelector.slices;
        if (dataPoints) {
            dataPoints.forEach(dataPoint => {
                slices.push(new formattingSettings.ColorPicker({
                    name: "fill",
                    displayName: dataPoint.category,
                    value: { value: dataPoint.color },
                    selector: dataViewWildcard.createDataViewWildcardSelector(dataViewWildcard.DataViewWildcardMatchingOption.InstancesAndTotals),
                    altConstantSelector: dataPoint.selectionId.getSelector(),
                    instanceKind: powerbi.VisualEnumerationInstanceKinds.ConstantOrRule
                }));
            });
        }
    }
}

Bygg og opprett tjenestemodellen for formateringsinnstillinger i konstruktørmetoden for visualobjektet. Tjenesten for formateringsinnstillinger mottar formatinnstillingene for barDiagram og konverterer dem til et Formateringsmodell-objekt som returneres i getFormattingModel API-en.

Hvis du vil bruke lokaliseringsfunksjonen, legger du til lokaliseringsbehandling i tjenesten for formateringsinnstillinger.

    import { FormattingSettingsService } from "powerbi-visuals-utils-formattingmodel";
    
    // ...
    // declare utils formatting settings service
    private formattingSettingsService: FormattingSettingsService;
    //...

    constructor(options: VisualConstructorOptions) {
        this.host = options.host;
        const localizationManager = this.host.createLocalizationManager();
        this.formattingSettingsService = new FormattingSettingsService(localizationManager);
        
        // Add here rest of your custom visual constructor code
    }

Oppdater modell for formateringsinnstillinger ved hjelp av oppdaterings-API. Kall oppdaterings-API-en hver gang en formateringsegenskap i egenskapsruten endres. Opprett datapunkter for stolpediagramvelgere og fyll dem ut i modell for formateringsinnstillinger:


    // declare formatting settings model for bar chart 
    private formattingSettings: BarChartSettingsModel;

    // ...

    public update(options: VisualUpdateOptions) {
        this.formattingSettings = this.formattingSettingsService.populateFormattingSettingsModel(BarChartSettingsModel, options.dataViews[0]);
        this.barDataPoints = createSelectorDataPoints(options, this.host);
        this.formattingSettings.populateColorSelector(this.barDataPoints);

        // Add the rest of your custom visual update API code here

    }

Til slutt er den nye API-en getFormattingModel enkel kodelinje ved hjelp av tjenesten for formateringsinnstillinger og gjeldende modell for formateringsinnstillinger som ble opprettet i oppdaterings-API-en ovenfor.

    public getFormattingModel(): powerbi.visuals.FormattingModel {
        return this.formattingSettingsService.buildFormattingModel(this.formattingSettings);
    }

(Valgfritt) Gjengi X-aksen (statiske objekter)

Du kan legge til objekter i egenskapsruten for å tilpasse visualobjektet ytterligere. Disse tilpasningene kan være endringer i brukergrensesnittet eller endringer relatert til dataene som ble spurt.

Du kan aktivere eller deaktivere disse objektene i egenskapsruten .

Screenshot of objects in the Property pane.

Dette eksemplet gjengir en X-akse i stolpediagrammet som et statisk objekt.

Vi har allerede lagt til enableAxis egenskapen i egenskapsfilen og barChart Innstillinger-grensesnittet. Legg til følgende kode i barChart.ts-filen før iVisual-klassen for å tegne X-aksen:

function getAxisTextFillColor(
    objects: DataViewObjects,
    colorPalette: ISandboxExtendedColorPalette,
    defaultColor: string
): string {
    if (colorPalette.isHighContrast) {
        return colorPalette.foreground.value;
    }

    return getValue<Fill>(
        objects,
        "enableAxis",
        "fill",
        {
            solid: {
                color: defaultColor,
            }
        },
    ).solid.color;
}

(Valgfritt) Legge til farge (databundne objekter)

Databundne objekter ligner statiske objekter, men håndterer vanligvis datavalg. Du kan for eksempel bruke databundne objekter til å velge fargen som er knyttet til hvert datapunkt, interaktivt.

Screenshot of color selection on properties.

Vi har allerede definert colorSelector objektet i egenskapsfilen .

Hvert datapunkt representeres av en annen farge. Vi inkluderer farge i BarChartDataPoint-grensesnittet, og tilordner en standardfarge til hvert datapunkt når det er definert i IVisualHost.

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

function getColumnStrokeColor(colorPalette: ISandboxExtendedColorPalette): string {
    return colorPalette.isHighContrast
        ? colorPalette.foreground.value
        : null;
}

function getColumnStrokeWidth(isHighContrast: boolean): number {
    return isHighContrast
        ? 2
        : 0;
}

Tjenesten colorPalette administrerer disse fargene i visualTransform funksjonen. Siden visualTransform det går gjennom hvert av datapunktene, er det et ideelt sted å tilordne kategoriske objekter som farge.

Hvis du vil ha mer detaljerte instruksjoner om hvordan du legger til farge i stolpediagrammet, kan du gå til Legg til farger i Power BI-visualobjektet.

Merk

Kontroller at den endelige barChart.ts-filen ser ut som denne barChart.ts-kildekoden, eller last ned kildekoden barChart.ts, og bruk den til å erstatte filen.

Objektopplistingsverktøy (valgfritt)

Objektegenskapsverdier er tilgjengelige som metadata i dataView, men det finnes ingen tjeneste for å hente disse verdiene. ObjectEnumerationUtility er et valgfritt sett med statiske funksjoner som itererer gjennom dataView og henter objektverdier. Opprett en fil kalt objectEnumerationUtility.ts i mappen, og kopier følgende kode til den src :

/**
 * Gets property value for a particular object.
 *
 * @function
 * @param {DataViewObjects} objects - Map of defined objects.
 * @param {string} objectName       - Name of desired object.
 * @param {string} propertyName     - Name of desired property.
 * @param {T} defaultValue          - Default value of desired property.
 */
export function getValue<T>(objects: DataViewObjects, objectName: string, propertyName: string, defaultValue: T ): T {
    if(objects) {
        let object = objects[objectName];
        if(object) {
            let property: <T>T = object[propertyName];
            if(property !== undefined) {
                return property;
            }
        }
    }
    return defaultValue;
}

/**
 * Gets property value for a particular object in a category.
 *
 * @function
 * @param {DataViewCategoryColumn} category - List of category objects.
 * @param {number} index                    - Index of category object.
 * @param {string} objectName               - Name of desired object.
 * @param {string} propertyName             - Name of desired property.
 * @param {T} defaultValue                  - Default value of desired property.
 */
export function getCategoricalObjectValue<T>(category: DataViewCategoryColumn, index: number, objectName: string, propertyName: string, defaultValue: T): T {
    let categoryObjects = category.objects;

    if (categoryObjects) {
        let categoryObject: DataViewObject = categoryObjects[index];
        if (categoryObject) {
            let object = categoryObject[objectName];
            if (object) {
                let property: T = <T>object[propertyName];
                if (property !== undefined) {
                    return property;
                }
            }
        }
    }
    return defaultValue;
}

Funksjonen getCategoricalObjectValue gir en praktisk måte å få tilgang til egenskaper på etter kategoriindeksen. Du må angi en objectName og propertyName som samsvarer med objektet og egenskapen i capabilities.json.

Se objectEnumerationUtility.ts for kildekoden.

Test visualobjektet

Kjør visualobjektet på Power BI-serveren for å se hvordan det ser ut:

  1. til prosjektets mappe i PowerShell, og start utviklingsappen.

    pbiviz start
    

    Visualobjektet kjører nå mens det driftes på datamaskinen.

    Viktig

    Ikke lukk PowerShell-vinduet før slutten av opplæringen. Hvis du vil hindre at visualobjektet kjører, skriver du inn CTRL+C, og hvis du blir bedt om å avslutte den satsvise jobben, skriver du inn Y og deretter ENTER.

  2. Vis visualobjektet i Power Bi-tjeneste ved å velge visualobjektet utvikler fra Visualisering-ruten.

    Screenshot of developer visual.

  3. Legge til data i visualobjektet

    Screenshot of data bound to field bucket.

  4. Dra kantene på visualobjektet for å endre størrelsen og legge merke til hvordan skalaen justeres.

  5. Aktivere og deaktivere X-aksen.

    Screenshot of X-Axis on property pane.

  6. Endre fargene på de ulike kategoriene.

Legg til andre funksjoner

Du kan tilpasse visualobjektet ytterligere ved å legge til flere funksjoner. Du kan legge til funksjoner som øker funksjonaliteten til visualobjektet, forbedrer utseendet og funksjonaliteten, eller gir brukeren mer kontroll over utseendet. Du kan for eksempel gjøre følgende:

Pakke visualobjektet

Før du kan laste inn visualobjektet i Power BI Desktop eller dele det med fellesskapet i visualobjektgalleriet i Power BI, må du pakke det.

Hvis du vil klargjøre visualobjektet for deling, følger du instruksjonene i Pakke et Power BI-visualobjekt.

Merk

Hvis du vil ha den fullstendige kildekoden for et stolpediagram med flere funksjoner, inkludert verktøytips og en hurtigmeny, kan du se eksempellinjediagram for power BI-visualobjekter.