Delen via


API voor objectopmaak (preview)

on-objectopmaak stelt gebruikers in staat om de opmaak van visuals snel en eenvoudig te wijzigen door rechtstreeks de elementen te selecteren die ze willen wijzigen. Wanneer een element is geselecteerd, navigeert het opmaakvenster automatisch en wordt de specifieke opmaakinstelling voor het geselecteerde element uitgebreid. Zie Opmaken van objecten in Power BI Desktopvoor meer informatie over objectopmaak op objecten.

Als u deze functionaliteiten aan uw visual wilt toevoegen, moet elke visual een optie voor de subselectiestijl en snelkoppeling bieden voor elke subselectiebare regio.

Notitie

  • Visuals die ondersteuning bieden voor objectopmaak, moeten de getFormattingModel-API implementeren die beschikbaar is via API-versie 5.1.
  • Als u powerbi-visuals-utils-formatmodel gebruikt, gebruikt u ten minste versie 6.0.0.

Een on-object-ervaring maken

Gebruik de subselectieservice wanneer de gebruiker een subselectiebaar element selecteert om Power BI de subselectie te verzenden. Geef de subselectiestijlen en sneltoetsen op met behulp van de subselectie-API. De subselectiehulp kan worden gebruikt om het proces te vereenvoudigen.

Opmaakmodus

De indelingsmodus is een nieuwe modus waarin de gebruiker onObject opmaak kan in- en uitschakelen in de ontwerpmodus. De visual wordt bijgewerkt met de status van de indelingsmodus in de bijwerkopties. De bijwerkopties omvatten ook de momenteel subselectie subselectie als CustomVisualSubSelection.

De API voor objectopmaak implementeren

Mogelijkhedenbestand

Voeg in het bestand capabilites.json de volgende eigenschappen toe om aan te geven dat de visual ondersteuning biedt voor objectopmaak:

{
  "supportsOnObjectFormatting": true,
  "enablePointerEventsFormatMode": true,
}

IVisual interface

De visual moet de VisualOnObjectFormatting interface implementeren als onderdeel van de IVisual-interface.

VisualOnObjectFormatting bevat drie methoden:

getSubSelectionStyles

Elke visual is vereist voor het implementeren van een getSubSelectionStyles methode, die wordt aangeroepen wanneer een subselectiebaar element wordt geselecteerd. De getSubSelectionStyles methode wordt geleverd met de huidige subselected elementen als een CustomVisualSubSelection matrix en wordt verwacht dat er een SubSelectionStyles-object of undefinedwordt geretourneerd.

Er zijn drie categorieën subselectiestijlen die betrekking hebben op de meeste scenario's:

  • Sms
  • Numerieke tekst
  • Vorm

Elk SubSelectionStyles-object biedt een andere ervaring voor de gebruiker voor het wijzigen van de stijl van een element.

getSubSelectionShortcuts

Als u meer opties voor de gebruiker wilt bieden, moet de visual de methode getSubSelectionShortcuts implementeren. Met deze methode worden VisualSubSelectionShortcuts of undefinedgeretourneerd. Als SubSelectionShortcuts worden opgegeven, moet er ook een VisualNavigateSubSelectionShortcut worden opgegeven, zodat wanneer een gebruiker een element selecteert en het opmaakvenster is geopend, het deelvenster automatisch naar de juiste kaart schuift.

Er zijn verschillende subselectiesneltoetsen om de visuele status te wijzigen. Elk item definieert een menu-item in het contextmenu met het juiste label.

Sub-Selection Menu Ondubbelzinnigheid: Het menu On-Object-ondubbelzinnigheid biedt gebruikers een methode om de gewenste subselectie te selecteren wanneer het niet duidelijk is welk visueel element wordt geselecteerd. Dit gebeurt vaak wanneer de gebruiker de achtergrond van de visual selecteert. Om meer subselecties te kunnen presenteren, moet de visual alle subselecties opgeven via de methode getSubSelectables.

getSubSelectables

Als u subselecties wilt bieden aan het ondubbelzinnige menu, moet de visual de getSubSelectables-methode implementeren. Deze methode is een optioneel filterType argument, van het type SubSelectionStylesType en retourneert een matrix van CustomVisualSubSelection of undefined. Als de HTMLSubSelectionHelper wordt gebruikt om een subselectie te maken, kan de HTMLSubSelectionHelper.getSubSelectables() methode worden gebruikt om subselectiebare elementen uit de DOM te verzamelen.

Sub-Selection Direct tekst bewerken: Met de opmaak van het object op het object kunt u dubbelklikken op de tekst van een suboptiekbaar element om het rechtstreeks te bewerken. Als u direct bewerken wilt bieden, moet u een RectangleSubSelectionOutline met de juiste cVDirectEdit-eigenschap ingevuld met een SubSelectableDirectEdit-object. Het overzicht kan worden opgegeven als een aangepast overzicht of als u de HTMLSubSelectionHelper gebruikt, kunt u het kenmerk SubSelectableDirectEdit gebruiken. (Zie de kenmerken van de HTMLSubSelectionHelper)

Het toevoegen van een directe bewerking voor een specifiek gegevenspunt (met selectors) wordt nog niet ondersteund.

Opmaak-id-interface

De volgende interface wordt gebruikt om te verwijzen naar de subSelection snelkoppelingen en stijlen.

interface FormattingId {
            objectName: string;
            propertyName: string;
            selector?: powerbi.data.Selector;
        }
  • objectName: de objectnaam zoals gedeclareerd in de capabilities.json.
  • propertyName: de eigenschapsnaam van een object zoals gedeclareerd in de capabilities.json.
  • selector: als het gegevenspunt een selectionId heeft, gebruikt u selectionId.getSelector(), moet deze selector hetzelfde zijn als voor het opmaakmodelsegment.

Voorbeelden

In dit voorbeeld bouwen we een aangepaste visual met twee objecten, colorSelector en directEdit. We gebruiken de HTMLSubSelectionHelper uit de onobjectFormatting hulpprogramma's om de meeste subselectietaken af te handelen. Zie on-object utilsvoor meer informatie.

Eerst maken we kaarten voor het opmaakvenster en bieden subSelectionShortcuts en stijlen voor elke subselectie.

De objecten definiëren

Definieer de objecten en declareer dat de visual onObject-opmaak ondersteunt in de capabilities.json:

"objects": {
      "directEdit": {
      "properties": {
        "show": {
          "displayName": "Show",
          "type": {
            "bool": true
          }
        },
        "textProperty": {
          "displayName": "Text",
          "type": {
            "text": true
          }
        },
        "fontFamily": {
          "type": {
            "formatting": {
              "fontFamily": true
            }
          }
        },
        "fontSize": {
          "type": {
            "formatting": {
              "fontSize": true
            }
          }
        },
        "bold": {
          "type": {
            "bool": true
          }
        },
        "italic": {
          "type": {
            "bool": true
          }
        },
        "underline": {
          "type": {
            "bool": true
          }
        },
        "fontColor": {
          "displayName": "Font Color",
          "type": {
            "fill": {
              "solid": {
                "color": true
              }
            }
          }
        },
        "background": {
          "displayName": "Background",
          "type": {
            "fill": {
              "solid": {
                "color": true
              }
            }
          }
        },
        "position": {
          "displayName": "Position",
          "type": {
            "enumeration": [
              { "displayName": "Left", "value": "Left" }, { "displayName": "Right", "value": "Right" }
            ]
          }
        }
      }
    },
    "colorSelector": {
      "displayName": "Data Colors",
      "properties": {
        "fill": {
          "displayName": "Color",
          "type": {
            "fill": {
              "solid": {
                "color": true
              }
            }
          }
        }
      }
    },
   },
  "supportsOnObjectFormatting": true,
  "enablePointerEventsFormatMode": true,

De opmaakkaarten maken

Bouw hun opmaakkaarten met behulp van de formatModel utils.

Kaartinstellingen voor kleurenkiezer

class ColorSelectorCardSettings extends Card {
    name: string = "colorSelector";
    displayName: string = "Data Colors";
    slices = [];
}

Voeg een methode toe aan de formatSetting, zodat we de segmenten dynamisch kunnen vullen voor het object colorSelector (onze datapoints).

populateColorSelector(dataPoints: BarChartDataPoint[]) {
        let slices: formattingSettings.ColorPicker[] = this.colorSelector.slices;
        if (dataPoints) {
            dataPoints.forEach(dataPoint => {
                slices.push(new formattingSettings.ColorPicker({
                    name: "fill",
                    displayName: dataPoint.category,
                    value: { value: dataPoint.color },
                    selector: dataPoint.selectionId.getSelector(),
                }));
            });
        }
    }

We geven de selector van het specifieke gegevenspunt in het selectorveld door. Deze selector is de selector die wordt gebruikt bij het implementeren van de get-API's van het OnObject.

Kaartinstellingen voor direct bewerken

class DirectEditSettings extends Card {
    displayName = 'Direct Edit';
    name = 'directEdit';
    private minFontSize: number = 8;
    private defaultFontSize: number = 11;
    show = new formattingSettings.ToggleSwitch({
        name: "show",
        displayName: undefined,
        value: true,
    });
    topLevelSlice = this.show;
    textProperty = new formattingSettings.TextInput({
        displayName: "Text Property",
        name: "textProperty",
        value: "What is your quest?",
        placeholder: ""
    });
    position = new formattingSettings.ItemDropdown({
        name: 'position',
        items: [{ displayName: 'Left', value: 'Left' }, { displayName: 'Right', value: 'Right' }],
        value: { displayName: 'Right', value: 'Right' }
    });
    font = new formattingSettings.FontControl({
        name: "font",
        displayName: 'Font',
        fontFamily: new formattingSettings.FontPicker({
            name: "fontFamily",
            displayName: "Font Family",
            value: "Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif"
        }),
        fontSize: new formattingSettings.NumUpDown({
            name: "fontSize",
            displayName: "Font Size",
            value: this.defaultFontSize,
            options: {
                minValue: {
                    type: powerbi.visuals.ValidatorType.Min,
                    value: this.minFontSize,
                }
            }
        }),
        bold: new formattingSettings.ToggleSwitch({
            name: 'bold',
            displayName: "Font Size",
            value: true
        }),
        italic: new formattingSettings.ToggleSwitch({
            name: 'italic',
            displayName: "Font Size",
            value: true
        }),
        underline: new formattingSettings.ToggleSwitch({
            name: 'underline',
            displayName: "Font Size",
            value: true
        })
    });
    fontColor = new formattingSettings.ColorPicker({
        name: "fontColor",
        displayName: "Color",
        value: { value: "#000000" }
    });
    background = new formattingSettings.ColorPicker({
        name: "background",
        displayName: "Color",
        value: { value: "#FFFFFF" }
    });
    slices = [this.show, this.textProperty, this.font, this.fontColor, this.background, this.position];
}

Helperkenmerken voor subselectie gebruiken

Voeg de HTMLSubSelectionHelper kenmerken toe aan onze objecten. Als u wilt zien welke kenmerken de HTMLSubSelectionHelper opgeeft, controleert u de documentatie over objecthulpmiddelen.

  • Voor het kenmerk directEdit:

    import {
       HtmlSubSelectableClass, HtmlSubSelectionHelper, SubSelectableDirectEdit as SubSelectableDirectEditAttr,
       SubSelectableDisplayNameAttribute, SubSelectableObjectNameAttribute, SubSelectableTypeAttribute 
    } from 'powerbi-visuals-utils-onobjectutils';
    
    const DirectEdit: powerbi.visuals.SubSelectableDirectEdit = {
        reference: {
            objectName: 'directEdit',
            propertyName: 'textProperty'
        },
        style: SubSelectableDirectEditStyle.Outline,
    };
    private visualDirectEditSubSelection = JSON.stringify(DirectEdit);
    
    this.directEditElement
                .classed('direct-edit', true)
                .classed('hidden', !this.formattingSettings.directEditSettings.show.value)
                .classed(HtmlSubSelectableClass, options.formatMode && this.formattingSettings.directEditSettings.show.value)
                .attr(SubSelectableObjectNameAttribute, 'directEdit')
                .attr(SubSelectableDisplayNameAttribute, 'Direct Edit')
                .attr(SubSelectableDirectEditAttr, this.visualDirectEditSubSelection)
    

    De HTMLSubSelectionHelper gebruikt het kenmerk SubSelectableDirectEditAttr om de directEdit-verwijzing van het directEdit-overzicht op te geven, zodat een directe bewerking wordt gestart wanneer een gebruiker dubbelklikt op het element.

    Schermopname die laat zien hoe de helper voor subselectie werkt.

  • Voor de colorSelector:

    barSelectionMerged
              .attr(SubSelectableObjectNameAttribute, 'colorSelector')
              .attr(SubSelectableDisplayNameAttribute, (dataPoint: BarChartDataPoint) => this.formattingSettings.colorSelector.slices[dataPoint.index].displayName)
              .attr(SubSelectableTypeAttribute, powerbi.visuals.SubSelectionStylesType.Shape)
              .classed(HtmlSubSelectableClass, options.formatMode)
    
    

Verwijzingen definiëren

Definieer de volgende interface om de voorbeelden te vereenvoudigen:

Notitie

De cardUid die u opgeeft, moet hetzelfde zijn als de cardUid die is opgegeven voor de getFormattingModel-API. Als u bijvoorbeeld powerbi-visuals-utils-formatmodel gebruikt, geeft u de cardUid op als Visual-cardName-card, waarbij de cardName de naam is die u aan deze kaart hebt toegewezen in de instellingen van het opmaakmodel. Geef dit anders op als de Visual-cardUid die u aan deze kaart hebt toegewezen.

interface References {
    cardUid?: string;
    groupUid?: string;
    fill?: FormattingId;
    font?: FormattingId;
    fontColor?: FormattingId;
    show?: FormattingId;
    fontFamily?: FormattingId;
    bold?: FormattingId;
    italic?: FormattingId;
    underline?: FormattingId;
    fontSize?: FormattingId;
    position?: FormattingId;
    textProperty?: FormattingId;
}

Maak voor dit voorbeeld een opsomming voor de namen van objecten:

const enum BarChartObjectNames {
    ColorSelector = 'colorSelector',
    DirectEdit = 'directEdit'
}
  • Verwijzingen voor het directEdit-object:
const directEditReferences: References = {
    cardUid: 'Visual-directEdit-card',
    groupUid: 'directEdit-group',
    fontFamily: {
        objectName: BarChartObjectNames.DirectEdit,
        propertyName: 'fontFamily'
    },
    bold: {
        objectName: BarChartObjectNames.DirectEdit,
        propertyName: 'bold'
    },
    italic: {
        objectName: BarChartObjectNames.DirectEdit,
        propertyName: 'italic'
    },
    underline: {
        objectName: BarChartObjectNames.DirectEdit,
        propertyName: 'underline'
    },
    fontSize: {
        objectName: BarChartObjectNames.DirectEdit,
        propertyName: 'fontSize'
    },
    fontColor: {
        objectName: BarChartObjectNames.DirectEdit,
        propertyName: 'fontColor'
    },
    show: {
        objectName: BarChartObjectNames.DirectEdit,
        propertyName: 'show'
    },
    position: {
        objectName: BarChartObjectNames.DirectEdit,
        propertyName: 'position'
    },
    textProperty: {
        objectName: BarChartObjectNames.DirectEdit,
        propertyName: 'textProperty'
    }
};
  • Voor colorSelector:
const colorSelectorReferences: References = {
    cardUid: 'Visual-colorSelector-card',
    groupUid: 'colorSelector-group',
    fill: {
        objectName: BarChartObjectNames.ColorSelector,
        propertyName: 'fill'
    }
};

API's implementeren

Nu gaan we de get-API's implementeren voor de onObject-opmaak en deze opgeven in visualOnObjectFormatting:

  1. Geef in de constructorcode de get-methoden op in visualOnObjectFormatting:

    public visualOnObjectFormatting: powerbi.extensibility.visual.VisualOnObjectFormatting;
    constructor(options: VisualConstructorOptions) {
            this.subSelectionHelper = HtmlSubSelectionHelper.createHtmlSubselectionHelper({
                     hostElement: options.element,
                     subSelectionService: options.host.subSelectionService,
                     selectionIdCallback: (e) => this.selectionIdCallback(e),
                });
    
     this.visualOnObjectFormatting = {
                    getSubSelectionStyles: (subSelections) => this.getSubSelectionStyles(subSelections),
                    getSubSelectionShortcuts: (subSelections, filter) => this.getSubSelectionShortcuts(subSelections, filter),
                    getSubSelectables: (filter) => this. getSubSelectables(filter)
                }
       }
    
    private getSubSelectionStyles(subSelections: CustomVisualSubSelection[]): powerbi.visuals.SubSelectionStyles | undefined {
            const visualObject = subSelections[0]?.customVisualObjects[0];
            if (visualObject) {
                switch (visualObject.objectName) {
                    case BarChartObjectNames.ColorSelector:
                        return this.getColorSelectorStyles(subSelections);
                     case BarChartObjectNames.DirectEdit:
                        return this.getDirectEditStyles();
                }
            }
        }
    
    private getSubSelectionShortcuts(subSelections: CustomVisualSubSelection[], filter: SubSelectionShortcutsKey | undefined):    VisualSubSelectionShortcuts | undefined {
            const visualObject = subSelections[0]?.  customVisualObjects[0];
            if (visualObject) {
                switch (visualObject.objectName) {
                    case BarChartObjectNames.ColorSelector:
                        return this.getColorSelectorShortcuts(subSelections);
                    case BarChartObjectNames.DirectEdit:
                        return this.getDirectEditShortcuts();
                }
            }
        }
    
  2. Implementeer de getSubSelection-snelkoppelingen en -stijl voor de colorSelector:

    private getColorSelectorShortcuts(subSelections:  CustomVisualSubSelection[]): VisualSubSelectionShortcuts   {
            const selector = subSelections[0].customVisualObjects[0].selectionId?.getSelector();
            return [
                {
                    type: VisualShortcutType.Reset,
                    relatedResetFormattingIds: [{
                        ...colorSelectorReferences.fill,
                        selector
                    }],
                },
                {
                    type: VisualShortcutType.Navigate,
                    destinationInfo: { cardUid: colorSelectorReferences.cardUid },
                    label: 'Color'
                }
            ];
        }
    

    De bovenstaande snelkoppeling retourneert een relevant menu-item in het contextmenu en voegt de volgende functies toe:

    • VisualShortcutType.Navigate: wanneer een gebruiker op een van de balken (gegevenspunt) selecteert en het opmaakvenster is geopend, schuift het opmaakvenster naar de kleurenkiezerkaart en opent het
    • VisualShortcutType.Reset: voegt een snelkoppeling voor opnieuw instellen toe aan het snelmenu. Deze optie is ingeschakeld als de opvulkleur is gewijzigd.
    private getColorSelectorStyles(subSelections: CustomVisualSubSelection[]): SubSelectionStyles {
            const selector = subSelections[0].customVisualObjects[0].selectionId?.getSelector();
            return {
                type: SubSelectionStylesType.Shape,
                fill: {
                    label: 'Fill',
                    reference: {
                        ...colorSelectorReferences.fill,
                     selector
                    },
                },
            };
        }
    

Wanneer een gebruiker met de rechtermuisknop op een balk klikt, wordt het volgende weergegeven:

schermopname van de gebruikersinterface wanneer een gebruiker met de rechtermuisknop op een balk klikt.

Wanneer u de kleur wijzigt:

Schermopname van het wijzigen van de kleur.

Snelkoppelingen naar subsecties

De subSelectiesnelkoppelingen en -stijlen voor directEdit implementeren:

private getDirectEditShortcuts(): VisualSubSelectionShortcuts {
        return [
            {
                type: VisualShortcutType.Reset,
                relatedResetFormattingIds: [
                    directEditReferences.bold,
                    directEditReferences.fontFamily,
                    directEditReferences.fontSize,
                    directEditReferences.italic,
                    directEditReferences.underline,
                    directEditReferences.fontColor,
                    directEditReferences.textProperty
                ]
            },
            {
                type: VisualShortcutType.Toggle,
                relatedToggledFormattingIds: [{
                    ...directEditReferences.show,
                }],
                ...directEditReferences.show,
                disabledLabel: 'Delete',
            },
            {
                type: VisualShortcutType.Picker,
                ...directEditReferences.position,
                label: 'Position'
            },
            {
                type: VisualShortcutType.Navigate,
                destinationInfo: { cardUid: directEditReferences.cardUid },
                label: 'Direct edit'
            }
        ];
    }

Met deze snelkoppeling wordt een relevant menu-item toegevoegd in het contextmenu en worden de volgende functies toegevoegd:

  • VisualShortcutType.Reset: voegt een reset toe aan het standaarditem in het contextmenu wanneer een van de eigenschappen in relatedResetFormattingIds-matrix wordt gewijzigd.
  • VisualShortcutType.Toggle: hiermee voegt u een optie Verwijderen toe aan het contextmenu. Wanneer erop wordt geklikt, wordt de wisselknop voor de directEdit kaart uitgeschakeld.
  • VisualShortcutType.Picker: Hiermee voegt u een optie toe in het contextmenu om te kiezen tussen rechts en links, omdat we het positiesegment in de opmaakkaart voor de directEdit-hebben toegevoegd.
  • VisualShortcutType.Navigate: wanneer het opmaakvenster is geopend en de gebruiker het element directEdit selecteert, schuift het opmaakvenster en opent u de directEdit kaart.
private getDirectEditStyles(): SubSelectionStyles {
        return {
            type: powerbi.visuals.SubSelectionStylesType.Text,
            fontFamily: {
                reference: {
                    ...directEditReferences.fontFamily
                },
                label: 'font family'
            },
            bold: {
                reference: {
                    ...directEditReferences.bold
                },
                label: 'bold'
            },
            italic: {
                reference: {
                    ...directEditReferences.italic
                },
                label: 'italic'
            },
            underline: {
                reference: {
                    ...directEditReferences.underline
                },
                label: 'underline'
            },
            fontSize: {
                reference: {
                    ...directEditReferences.fontSize
                },
                label: 'font size'
            },
            fontColor: {
                reference: {
                    ...directEditReferences.fontColor
                },
                label: 'font color'
            },
            background: {
                reference: {
                    objectName: 'directEdit',
                    propertyName: 'background'
                },
                label: 'background'
            }
        }
    }

We hebben de relevante eigenschappen opgegeven zoals we ze hebben toegevoegd in de formatSettings.

In de volgende afbeelding ziet u hoe de gebruikersinterface eruitziet wanneer u met de rechtermuisknop op het directEdit-element klikt:

Schermopname van de interface voor direct bewerken.

Lokalisatie

De visual moet de lokalisatie verwerken en gelokaliseerde tekenreeksen opgeven.

GitHub-resources

  • Alles op objectopmaakinterfaces vindt u in (koppeling die moet worden opgegeven zodra de API is uitgebracht) in on-object-formatting-api.d.ts
  • U wordt aangeraden [on object utils] te gebruiken, waaronder de [HTMLSubSelectionHelper](koppeling die moet worden opgegeven zodra de API is uitgebracht)
  • U vindt een voorbeeld van een aangepast visueel element SampleBarChart die api-versie 5.8.0 gebruikt en de ondersteuning voor de objectopmaak implementeert met behulp van de hulpprogramma's voor objecten op (koppeling die moet worden opgegeven zodra de API is uitgebracht)