Freigeben über


Objektformatierungs-API (Vorschauversion)

Die Objektformatierung ermöglicht es Benutzern, das Format von Visuals schnell und einfach zu ändern, indem sie die Elemente direkt auswählen, die sie ändern möchten. Wenn ein Element ausgewählt ist, führt der Formatbereich die Navigation automatisch aus und erweitert die spezifische Formatierungseinstellung für das ausgewählte Element. Weitere Informationen zur direkten Formatierung von Objekten finden Sie unter Objektformatierung in Power BI Desktop.

Um Ihrem Visual diese Funktionen hinzuzufügen, muss jedes Visual eine Option für das Unterauswahlformat und eine Verknüpfung für jeden unterauswählbaren Bereich enthalten.

Hinweis

  • Visuals, die die direkte Formatierung von Objekten unterstützen, müssen die getFormattingModel-API implementieren, die ab API-Version 5.1 verfügbar ist.
  • Wenn Sie „powerbi-visuals-utils-formattingmodel“ verwenden, verwenden Sie mindestens Version 6.0.0.

Ermöglichen der direkten Objektformatierung

Verwenden Sie den Unterauswahldienst, wenn der Benutzer ein unterauswählbares Element auswählt, um die Unterauswahl an Power BI zu senden. Stellen Sie die Unterauswahlformate und Verknüpfungen mithilfe der Unterauswahl-API bereit. Die Hilfsprogramm zur Unterauswahl kann verwendet werden, um den Prozess zu vereinfachen.

Formatmodus

Der Formatmodus ist ein neuer Modus, mit dem Benutzer die onObject-Formatierung im Erstellungsmodus aktivieren oder deaktivieren können. Das Visual wird mit dem Status des Formatmodus in den Updateoptionen aktualisiert. Die Updateoptionen enthalten auch die derzeitige Unterauswahl als CustomVisualSubSelection.

Implementieren der Objektformatierungs-API

Funktionsdatei

Fügen Sie in der datei capabilites.json die folgenden Eigenschaften hinzu, um zu deklarieren, dass das Visual die direkte Formatierung von Objekten unterstützt:

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

IVisual-Schnittstelle

Das Visual muss die VisualOnObjectFormatting-Schnittstelle als Teil der IVisual-Schnittstelle implementieren.

VisualOnObjectFormatting enthält drei Methoden:

getSubSelectionStyles

Jedes Visual muss eine getSubSelectionStyles-Methode implementieren, die aufgerufen wird, wenn ein unterauswählbares Element ausgewählt wird. Die getSubSelectionStyles-Methode wird mit den aktuellen unterausgewählten Elementen als CustomVisualSubSelection-Array bereitgestellt, und es wird erwartet, dass diese ein SubSelectionStyles-Objekt oder undefined zurückgibt.

Es gibt drei Kategorien von Unterauswahlformaten, die die meisten Szenarios abdecken:

  • Text
  • Numerischer Text
  • Form

Jedes SubSelectionStyles-Objekt bietet dem Benutzer andere Möglichkeiten zum Ändern des Formats eines Elements.

getSubSelectionShortcuts

Um Benutzern weitere Optionen zu bieten, muss das Visual die getSubSelectionShortcuts-Methode implementieren. Diese Methode gibt entweder VisualSubSelectionShortcuts oder undefined zurück. Wenn SubSelectionShortcuts angegeben wird, muss darüber hinaus ein VisualNavigateSubSelectionShortcut angegeben werden, sodass der Bereich automatisch zur entsprechenden Karte scrollt, wenn ein Benutzer ein Element unterauswählt und der Formatbereich geöffnet ist.

Es gibt mehrere Unterauswahlverknüpfungen zum Ändern des Visualstatus. Jede definiert ein Menüelement im Kontextmenü mit der entsprechenden Bezeichnung.

Unterauswahlmenü zur Mehrdeutigkeitsvermeidung: Mit dem Menü zur Mehrdeutigkeitsvermeidung für Objekte können Benutzer die gewünschte Unterauswahl auswählen, wenn nicht eindeutig ist, welches Visualelement unterausgewählt wird. Das geschieht häufig, wenn der Benutzer den Hintergrund des Visuals unterauswählt. Damit das Menü zur Mehrdeutigkeitsvermeidung mehr Unterauswahlen enthält, muss das Visual alle Unterauswahlen über die getSubSelectables-Methode bereitstellen.

getSubSelectables

Um Unterauswahlen für das Menü zur Mehrdeutigkeitsvermeidung bereitzustellen, muss das Visual die getSubSelectables-Methode implementieren. Diese Methode erhält ein optionales filterType-Argument vom Typ SubSelectionStylesType und gibt ein Array mit CustomVisualSubSelection oder undefined zurück. Wenn HTMLSubSelectionHelper zum Erstellen einer Unterauswahl verwendet wird, kann die Methode HTMLSubSelectionHelper.getSubSelectables() verwendet werden, um unterauswählbare Elemente aus dem DOM zu sammeln.

Direkte Textbearbeitung der Unterauswahl: Bei der direkten Objektformatierung können Sie auf den Text eines Elements in der Unterauswahl doppelklicken, um ihn direkt zu bearbeiten. Damit die direkte Bearbeitungsfunktionen nutzbar ist, müssen Sie RectangleSubSelectionOutline mit der entsprechenden cVDirectEdit-Eigenschaft angeben, die mit einem SubSelectableDirectEdit-Objekt aufgefüllt ist. Die Gliederung kann entweder als benutzerdefinierte Gliederung bereitgestellt werden, oder, wenn Sie HTMLSubSelectionHelper verwenden, können Sie das Attribut SubSelectableDirectEdit verwenden. (Siehe die von HTMLSubSelectionHelper bereitgestellten Attribute.)

Das Hinzufügen einer direkten Bearbeitung für einen bestimmten Datenpunkt (mithilfe von Selektoren) wird noch nicht unterstützt.

FormattingId-Schnittstelle

Die folgende Schnittstelle wird verwendet, um auf die subSelection-Verknüpfungen und -Formate zu verweisen.

interface FormattingId {
            objectName: string;
            propertyName: string;
            selector?: powerbi.data.Selector;
        }
  • objectName: der Objektname, wie in „capabilities.json“ deklariert
  • propertyName: der Eigenschaftenname eines Objekts, wie in „capabilities.json“ deklariert
  • selector: Wenn der Datenpunkt über eine selectionId verfügt, verwenden Sie „selectionId.getSelector()“. Dieser Selektor muss mit dem für den Formatierungsmodellslice angegebenen identisch sein.

Beispiele

In diesem Beispiel erstellen wir ein benutzerdefiniertes Visual mit zwei Objekten, colorSelector und directEdit. Wir verwenden HTMLSubSelectionHelper aus den onobjectFormatting-Hilfsprogrammen, um den größten Teil des subSelection-Auftrags zu verarbeiten. Weitere Informationen finden Sie unter Hilfsprogramme für Objekte.

Zunächst erstellen wir Karten für den Formatierungsbereich und stellen subSelectionShortcuts und styles für jede Unterauswahl bereit.

Definieren der Objekte

Definieren Sie die Objekte, und deklarieren Sie, dass das Visual die direkte Objektformatierung in „capabilities.json“ unterstützt:

"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,

Erstellen der Formatierungskarten

Erstellen Sie die Formatierungskarten mithilfe des formattingModel-Hilfsprogramms.

Einstellungen für Farbauswahlkarten

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

Fügen Sie „formatSetting“ eine Methode hinzu, damit wir die Segmente dynamisch für das colorSelector-Objekt auffüllen können (das sind unsere Datenpunkte).

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

Wir übergeben die Auswahl des spezifischen Datenpunkts im Selektorfeld. Diese Auswahl ist diejenige, die beim Implementieren der get-APIs für OnObject verwendet wird.

Einstellungen für Karten für die direkte Bearbeitung

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

Verwenden von Hilfsattributen für die Unterauswahl

Fügen Sie die HTMLSubSelectionHelper-Attribute zu den Objekten hinzu. In der Dokumentation zu Objekthilfsprogrammen erfahren Sie, welche Attribute „HTMLSubSelectionHelper“ bereitstellt.

  • Für das directEdit-Attribut:

    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)
    

    HTMLSubSelectionHelper verwendet das SubSelectableDirectEditAttr-Attribut, um den directEdit-Verweis der directEdit-Gliederung bereitzustellen, sodass eine direkte Bearbeitung beginnt, wenn ein Benutzer auf das Element doppelklickt.

    Screenshot showing how the subselection helper works.

  • Für 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)
    
    

Definieren von Verweisen

Definieren Sie die folgende Schnittstelle, um die Beispiele zu vereinfachen:

Hinweis

Die cardUid, die Sie angeben, sollte mit der für die getFormattingModel-API angegebenen identisch sein. Wenn Sie beispielsweise „powerbi-visuals-utils-formattingmodel“ verwenden, geben Sie die cardUid als Visual-cardName-card an, wobei „cardName“ der Name ist, den Sie dieser Karte in den Formatierungsmodelleinstellungen zugewiesen haben. Geben Sie ihn andernfalls als die Visual-cardUid an, die Sie dieser Karte zugewiesen haben.

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

Erstellen Sie für dieses Beispiel eine Enumeration für die Namen der Objekte:

const enum BarChartObjectNames {
    ColorSelector = 'colorSelector',
    DirectEdit = 'directEdit'
}
  • Verweise auf das directEdit-Objekt:
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'
    }
};
  • Für colorSelector:
const colorSelectorReferences: References = {
    cardUid: 'Visual-colorSelector-card',
    groupUid: 'colorSelector-group',
    fill: {
        objectName: BarChartObjectNames.ColorSelector,
        propertyName: 'fill'
    }
};

Implementieren von APIs

Jetzt implementieren wir die get-APIs für die direkte Objektformatierung und stellen sie in „visualOnObjectFormatting“ bereit:

  1. Geben Sie im Konstruktorcode die get-Methoden in „visualOnObjectFormatting“ an:

    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. Implementieren Sie die getSubSelection-Verknüpfungen und -formate für „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'
                }
            ];
        }
    

    Die obige Verknüpfung gibt relevante Menüelemente im Kontextmenü zurück und fügt die folgenden Funktionen hinzu:

    • VisualShortcutType.Navigate: Wenn ein Benutzer auf einen der Balken (Datenpunkt) klickt und der Formatierungsbereich geöffnet ist, scrollt der Formatbereich zur Farbauswahlkarte und öffnet sie.
    • VisualShortcutType.Reset: Fügt dem Kontextmenü eine Verknüpfung zum Zurücksetzen hinzu. Sie ist aktiviert, wenn die Füllfarbe geändert wurde.
    private getColorSelectorStyles(subSelections: CustomVisualSubSelection[]): SubSelectionStyles {
            const selector = subSelections[0].customVisualObjects[0].selectionId?.getSelector();
            return {
                type: SubSelectionStylesType.Shape,
                fill: {
                    label: 'Fill',
                    reference: {
                        ...colorSelectorReferences.fill,
                     selector
                    },
                },
            };
        }
    

Wenn ein Benutzer mit der rechten Maustaste auf einen Balken klickt, wird Folgendes angezeigt:

Screenshot of user interface when a user right-clicks on a bar.

Beim Ändern der Farbe:

Screenshot of changing color.

Verknüpfungen zu Unterabschnitten

So implementieren Sie die subSelection-Verknüpfungen und -Formate für „directEdit“:

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

Die Verknüpfung fügt ein relevantes Menüelement zum Kontextmenü sowie die folgenden Funktionen hinzu:

  • VisualShortcutType.Reset: Fügt dem Kontextmenü eine Option hinzu, das Standardelement wiederherzustellen, wenn sich eine der Eigenschaften im Array „relatedResetFormattingIds“ ändert
  • VisualShortcutType.Toggle: Fügt dem Kontextmenü eine Option zum Löschen hinzu. Wenn auf diese geklickt wird, wird die Umschaltfläche für die Karte directEdit deaktiviert.
  • VisualShortcutType.Picker: Fügt eine Option im Kontextmenü hinzu, um zwischen rechts und links zu wählen, da wir den Slice in der Formatierungskarte für directEdit hinzugefügt haben.
  • VisualShortcutType.Navigate: Wenn der Formatbereich geöffnet ist und der Benutzer das directEdit-Element auswählt, scrollt der Formatbereich und öffnet die Karte directEdit.
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'
            }
        }
    }

Wir haben die relevanten Eigenschaften bereitgestellt, während wir sie „formattingSettings“ hinzugefügt haben.

So sieht die Benutzeroberfläche aus, wenn Sie mit der rechten Maustaste auf das directEdit-Element klicken:

Screenshot of the direct edit interface.

Lokalisierung

Das Visual sollte die Lokalisierung verarbeiten und lokalisierte Zeichenfolgen bereitstellen.

GitHub-Ressourcen

  • Alle Objektformatierungsschnittstellen finden Sie unter (Link folgt, wenn die API veröffentlicht wurde) in „on-object-formatting-api.d.ts“.
  • Wir empfehlen die Verwendung von [Hilfsprogrammen für Objekte], die [HTMLSubSelectionHelper](Link folgt, wenn die API veröffentlicht wurde) enthalten.
  • Sie finden ein Beispiel für ein benutzerdefiniertes Visual, SampleBarChart, das API-Version 5.8.0 verwendet und die Unterstützung für die direkte Objektformatierung mithilfe des Hilfsprogramms für Objekte unter (Link folgt, wenn die API veröffentlicht wurde) implementiert.