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 undefined
wordt 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 undefined
geretourneerd. 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 kenmerkSubSelectableDirectEditAttr
om de directEdit-verwijzing van het directEdit-overzicht op te geven, zodat een directe bewerking wordt gestart wanneer een gebruiker dubbelklikt op het element.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:
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(); } } }
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:
Wanneer u de kleur wijzigt:
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:
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)