Dela via


Formaterings-API för objekt (förhandsversion)

formatering på objekt gör det möjligt för användare att snabbt och enkelt ändra formatet för visuella objekt genom att välja de element som de vill ändra direkt. När ett element har valts navigerar formatfönstret automatiskt och expanderar den specifika formateringsinställningen för det markerade elementet. Mer information om formatering på objekt finns i on-object-formatering i Power BI Desktop.

Om du vill lägga till dessa funktioner i ditt visuella objekt måste varje visuellt objekt tillhandahålla ett alternativ för undervalsformat och genväg för varje undermarkerbar region.

Not

  • Visuella objekt som stöder formatering på objekt måste implementera getFormattingModel API- som är tillgängligt från API-version 5.1.
  • Om du använder powerbi-visuals-utils-formattingmodel använder du version 6.0.0 minst.

Skapa en upplevelse på objektet

Använd undermarkeringstjänsten när användaren väljer ett delmarkerbart element för att skicka undermarkeringen till Power BI. Ange undervalsformat och genvägar med api:et undermarkering. kan användas för att förenkla processen.

Formatläge

Formatläget är ett nytt läge där användaren kan aktivera och inaktivera onObject formatering i redigeringsläge. Det visuella objektet uppdateras med status för formatläget i uppdateringsalternativen. Uppdateringsalternativen innehåller även den undermarkerade undermarkeringenSelection som CustomVisualSubSelection.

Så här implementerar du formaterings-API:et för objekt

Fil för funktioner

I filen capabilites.json lägger du till följande egenskaper för att deklarera att det visuella objektet stöder formatering på objektet:

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

IVisual-gränssnitt

Det visuella objektet måste implementera VisualOnObjectFormatting-gränssnittet som en del av IVisual-gränssnittet.

VisualOnObjectFormatting innehåller tre metoder:

getSubSelectionStyles

Varje visuellt objekt krävs för att implementera en getSubSelectionStyles-metod, som anropas när ett delväljbart element är undermarkerat. Metoden getSubSelectionStyles tillhandahålls med de aktuella undermarkerade elementen som en CustomVisualSubSelection matris och förväntas returnera antingen ett SubSelectionStyles-objekt eller undefined.

Det finns tre kategorier av undervalsformat som täcker de flesta scenarier:

  • SMS
  • Numerisk text
  • Form

Varje SubSelectionStyles-objekt ger en annan upplevelse för användaren för att ändra formatet för ett element.

getSubSelectionShortcuts

Om du vill ange fler alternativ för användaren måste det visuella objektet implementera metoden getSubSelectionShortcuts. Den här metoden returnerar antingen VisualSubSelectionShortcuts eller undefined. Om SubSelectionShortcuts anges måste dessutom en VisualNavigateSubSelectionShortcut anges så att när en användare underväljer ett element och formatfönstret är öppet rullar fönstret automatiskt till rätt kort.

Det finns flera genvägar för underval för att ändra det visuella tillståndet. Var och en definierar ett menyalternativ i snabbmenyn med lämplig etikett.

Sub-Selection Disambiguation Menu: Disambiguation-menyn på objektet innehåller en metod för användare att välja önskad undermarkering när det inte är klart vilket visuellt element som undermarkeras. Detta händer ofta när användaren underväljer bakgrunden till det visuella objektet. För att den tvetydiga menyn ska kunna visa fler undermarkeringar måste det visuella objektet ange alla undermarkeringar via metoden getSubSelectables.

getSubSelectables

För att tillhandahålla undermarkeringar till disambiguationsmenyn måste det visuella objektet implementera metoden getSubSelectables. Den här metoden är ett valfritt filterType argument av typen SubSelectionStylesType och returnerar en matris med CustomVisualSubSelection eller undefined. Om HTMLSubSelectionHelper används för att skapa ett underval kan HTMLSubSelectionHelper.getSubSelectables()-metoden användas för att samla in undermarkerbara element från DOM.

Sub-Selection Direkttextredigering: Med formatering på objekt kan du dubbelklicka på texten i ett delvalbart element för att redigera det direkt. För att tillhandahålla direktredigeringsfunktionen måste du ange en RectangleSubSelectionOutline med lämplig cVDirectEdit-egenskap ifylld med ett SubSelectableDirectEdit-objekt. Dispositionen kan antingen anges som en anpassad disposition eller, om du använder HTMLSubSelectionHelper kan du använda attributet SubSelectableDirectEdit. (Se attributen som tillhandahålls av HTMLSubSelectionHelper)

Det finns ännu inte stöd för att lägga till en direkt redigering för en specifik datapunkt (med väljare).

FormattingId-gränssnitt

Följande gränssnitt används för att referera till subSelection genvägar och formatmallar.

interface FormattingId {
            objectName: string;
            propertyName: string;
            selector?: powerbi.data.Selector;
        }
  • objectName: objektnamnet som deklarerats i capabilities.json.
  • propertyName: egenskapsnamnet för ett objekt som deklarerats i capabilities.json.
  • väljare: Om datapunkten har ett selectionId använder du selectionId.getSelector(), måste den här väljaren vara samma som för formateringsmodellsegmentet.

Exempel

I det här exemplet skapar vi ett anpassat visuellt objekt som har två objekt, colorSelector och directEdit. Vi använder HTMLSubSelectionHelper från onobjectFormatting-verktygen för att hantera det mesta av subSelection-jobbet. Mer information finns i on-object utils.

Först skapar vi kort för formateringsfönstret och tillhandahåller subSelectionShortcuts och formatmallar för varje delval.

Definiera objekten

Definiera objekten och deklarera att det visuella objektet stöder OnObject-formatering i 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,

Skapa formateringskorten

Skapa formateringskorten med hjälp av formateringModel-verktyg.

Inställningar för färgväljare

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

Lägg till en metod i formateringenInställningar så att vi kan fylla i segmenten dynamiskt för colorSelector-objektet (våra datapunkter).

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

Vi skickar väljaren för den specifika datapunkten i fältet väljare. Den här väljaren är den som används när du implementerar get-API:erna för OnObject.

Inställningar för direktredigeringskort

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

Använda underväljningshjälpattribut

Lägg till de HTMLSubSelectionHelper attributen i våra objekt. Om du vill se vilka attribut som HTMLSubSelectionHelper tillhandahåller läser du dokumentationen om objektverktyg.

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

    HTMLSubSelectionHelper använder attributet SubSelectableDirectEditAttr för att tillhandahålla directEdit-referensen för directEdit-dispositionen, så en direktredigering startar när en användare dubbelklickar på elementet.

    Skärmbild som visar hur underväljningshjälpen fungerar.

  • 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)
    
    

Definiera referenser

Definiera följande gränssnitt för att förenkla exemplen:

Not

Den cardUid du anger bör vara samma som den som anges för getFormattingModel-API:et. Om du till exempel använder powerbi-visuals-utils-formattingmodel anger du cardUid som Visual-cardName-card, där cardName är det namn som du tilldelade kortet i formateringsmodellinställningarna. Annars anger du det som Visual-cardUid du har tilldelat det här kortet.

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

I det här exemplet skapar du en uppräkning för objektnamnen:

const enum BarChartObjectNames {
    ColorSelector = 'colorSelector',
    DirectEdit = 'directEdit'
}
  • Referenser för directEdit-objektet:
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'
    }
};

Implementera API:er

Nu ska vi implementera get-API:erna för onObject-formateringen och ange dem i visualOnObjectFormatting:

  1. I konstruktorkoden anger du get-metoderna i 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. Implementera genvägarna getSubSelection och formatmallen 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'
                }
            ];
        }
    

    Genvägen ovan returnerar relevant menyalternativ i snabbmenyn och lägger till följande funktioner:

    • VisualShortcutType.Navigate: när en användare väljer på ett av staplarna (datapunkten) och formateringsfönstret är öppet rullar formatfönstret till färgväljarens kort och öppnar det
    • VisualShortcutType.Reset: lägger till en återställningsgenväg till snabbmenyn. Den aktiveras om fyllningsfärgen har ändrats.
    private getColorSelectorStyles(subSelections: CustomVisualSubSelection[]): SubSelectionStyles {
            const selector = subSelections[0].customVisualObjects[0].selectionId?.getSelector();
            return {
                type: SubSelectionStylesType.Shape,
                fill: {
                    label: 'Fill',
                    reference: {
                        ...colorSelectorReferences.fill,
                     selector
                    },
                },
            };
        }
    

När en användare högerklickar på ett fält visas följande:

Skärmbild av användargränssnittet när en användare högerklickar på ett fält.

När du ändrar färg:

Skärmbild av färgbyte.

Genvägar till underavsnitt

Så här implementerar du genvägar och formatmallar för subSelection 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'
            }
        ];
    }

Den här genvägen lägger till ett relevant menyalternativ i snabbmenyn och lägger till följande funktioner:

  • VisualShortcutType.Reset: lägger till en återställning till standardobjektet på snabbmenyn när en av egenskaperna som anges i relatedResetFormattingIds-matrisen ändras.
  • VisualShortcutType.Toggle: lägger till alternativen Ta bort i snabbmenyn. När du klickar inaktiveras växlingsknappen för directRedigera kortet.
  • VisualShortcutType.Picker: Lägger till ett alternativ i snabbmenyn för att välja mellan Höger och Vänster, eftersom vi har lagt till positionssegmentet i formateringskortet för directEdit.
  • VisualShortcutType.Navigate: När formatfönstret är öppet och användaren väljer elementet directEdit rullar formatfönstret och öppnar kortet 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'
            }
        }
    }

Vi angav relevanta egenskaper när vi lade till dem i formateringSettings.

Följande bild visar hur användargränssnittet ser ut när du högerklickar på directEdit-elementet:

Skärmbild av direktredigeringsgränssnittet.

Lokalisering

Det visuella objektet ska hantera lokaliseringen och tillhandahålla lokaliserade strängar.

GitHub-resurser

  • Alla objektformateringsgränssnitt finns i (länk som ska anges när API:et har släppts) i on-object-formatting-api.d.ts
  • Vi rekommenderar att du använder [på objektverktyg], som innehåller länken [HTMLSubSelectionHelper](som ska anges när API:et har släppts)
  • Du hittar ett exempel på ett anpassat visuellt objekt SampleBarChart- som använder API-version 5.8.0 och implementerar stöd för objektformatering med hjälp av på-objektverktygen på (länk som ska anges när API:et har släppts)