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 dasSubSelectableDirectEditAttr
-Attribut, um den directEdit-Verweis der directEdit-Gliederung bereitzustellen, sodass eine direkte Bearbeitung beginnt, wenn ein Benutzer auf das Element doppelklickt.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:
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(); } } }
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:
Beim Ändern der Farbe:
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:
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.