{"library":"powerbi-visuals-api","title":"Power BI Custom Visuals API","description":"The `powerbi-visuals-api` package provides the official TypeScript type definitions, interfaces, and enums necessary for developing custom visuals for Microsoft Power BI. It defines the comprehensive contract between a custom visual and the Power BI host environment, enabling developers to interact with data, leverage host services (like tooltips, selections, and authentication), and manage visual capabilities such as on-object formatting and local storage. The current stable version is 5.11.0. Microsoft maintains a relatively active release cadence, frequently introducing new features, deprecating old ones, and addressing bugs or security concerns. This API is the authoritative source for types and definitions, essential for any developer creating or maintaining custom visualization components for the Power BI platform, ensuring type safety and compatibility with the Power BI ecosystem.","language":"javascript","status":"active","last_verified":"Tue Apr 21","install":{"commands":["npm install powerbi-visuals-api"],"cli":null},"imports":["import { IVisual } from 'powerbi-visuals-api';","import { VisualUpdateOptions } from 'powerbi-visuals-api';","import { IVisualHost } from 'powerbi-visuals-api';"],"auth":{"required":false,"env_vars":[]},"quickstart":{"code":"import {\n  IVisual, IVisualHost, VisualUpdateOptions, VisualConstructorOptions,\n  VisualUpdateType, VisualDataView, DataViewValueColumnGroup\n} from 'powerbi-visuals-api';\n\n// A minimal example of a custom visual structure, demonstrating lifecycle and data handling.\nclass MyCustomVisual implements IVisual {\n    private targetDiv: HTMLElement;\n    private host: IVisualHost;\n\n    constructor(options: VisualConstructorOptions) {\n        this.targetDiv = options.element;\n        this.host = options.host;\n        const initialText = document.createElement('p');\n        initialText.textContent = 'Custom Visual Initialized';\n        this.targetDiv.appendChild(initialText);\n    }\n\n    public update(options: VisualUpdateOptions): void {\n        console.log('Visual updated with options:', options);\n        this.targetDiv.innerHTML = ''; // Clear previous content\n\n        const dataView: VisualDataView | undefined = options.dataViews && options.dataViews[0];\n\n        if (dataView && dataView.categorical && dataView.categorical.categories) {\n            const categories = dataView.categorical.categories[0];\n            const values = dataView.categorical.values && dataView.categorical.values[0];\n\n            if (categories && categories.values) {\n                const ul = document.createElement('ul');\n                categories.values.forEach((category, index) => {\n                    const li = document.createElement('li');\n                    const value = values && values.values && values.values[index] !== undefined ? values.values[index] : 'N/A';\n                    li.textContent = `${category}: ${value}`;\n                    ul.appendChild(li);\n                });\n                this.targetDiv.appendChild(ul);\n            } else {\n                const noCategoryText = document.createElement('p');\n                noCategoryText.textContent = 'No categories found in data.';\n                this.targetDiv.appendChild(noCategoryText);\n            }\n        } else {\n            const noDataText = document.createElement('p');\n            noDataText.textContent = 'No data available or data view structure is not categorical.';\n            this.targetDiv.appendChild(noDataText);\n        }\n\n        // Example of host interaction\n        this.host.displayMessage('Visual update processed.', 3000);\n    }\n\n    public destroy(): void {\n        // Perform any cleanup here when the visual is removed from the canvas\n        console.log('Visual destroyed');\n    }\n}\n\n// --- Mocking environment for demonstration purposes ---\n// In a real Power BI environment, this would be handled by the host application.\nconst mockElement = document.createElement('div');\nmockElement.style.width = '300px';\nmockElement.style.height = '200px';\nmockElement.style.border = '1px solid #ccc';\ndocument.body.appendChild(mockElement);\n\nconst mockHost: IVisualHost = {\n    // Minimal mock for common host services used in visuals\n    createSelectionIdBuilder: () => ({ withCategory: () => ({ createSelectionId: () => ({}) }) }),\n    createSelectionManager: () => ({ select: () => Promise.resolve([]) }),\n    displayMessage: (message, duration?) => console.log(`Host Message: ${message}`),\n    locale: 'en-US',\n    authenticationService: {\n        get ; () => Promise.resolve(null),\n        acquireAADToken: () => Promise.resolve(null)\n    },\n    storageV2Service: {\n        get: (key: string) => Promise.resolve(null),\n        set: (key: string, data: string) => Promise.resolve()\n    },\n    // More host services would be mocked here in a complete testing setup\n    eventService: { register: () => {}, unregister: () => {} },\n    hostServices: { get: () => undefined, set: () => {}, overrideSelectionMode: () => {}, onVisualCommand: () => {} },\n    securityService: { isCustomVisualEnabled: () => true },\n    applyAdvancedFilter: () => {}, tooltipService: { show: () => {}, hide: () => {} },\n    launchUrl: (url) => console.log(`Launching URL: ${url}`),\n    downloadService: { exportVisualsContent: () => Promise.resolve({success: true, status:''}), exportVisualsContentExtended: () => Promise.resolve({success: true, status:'', extendedResult:{}}) },\n    createOpaqueUtils: () => ({ areHierarchicallyRelated: (a,b) => false }),\n    subSelectionService: { setSubSelections: () => {}, removeSubSelections: () => {}, showCustomTooltip: () => {}, hideCustomTooltip: () => {} },\n    fetchDataByProperty: () => Promise.resolve(null),\n    setTelemetryLog: () => {}\n};\n\nconst mockVisualConstructorOptions: VisualConstructorOptions = {\n    element: mockElement,\n    host: mockHost,\n    visuals: {}\n};\n\nconst visual = new MyCustomVisual(mockVisualConstructorOptions);\n\nconst mockUpdateOptions: VisualUpdateOptions = {\n    viewport: { width: 300, height: 200 },\n    type: VisualUpdateType.Data,\n    dataViews: [{\n        metadata: {\n            columns: [\n                { displayName: 'Category', queryName: 'Category', roles: { Category: true }, type: { text: true } },\n                { displayName: 'Value', queryName: 'Value', roles: { Value: true }, type: { numeric: true } }\n            ]\n        },\n        categorical: {\n            categories: [{\n                source: { displayName: 'Category', queryName: 'Category', roles: { Category: true }, type: { text: true } },\n                values: ['Product A', 'Product B', 'Product C', 'Product D']\n            }],\n            values: [{\n                source: { displayName: 'Value', queryName: 'Value', roles: { Value: true }, type: { numeric: true } },\n                values: [150, 220, 90, 310]\n            }] as DataViewValueColumnGroup[]\n        }\n    }],\n    viewMode: 0, // ViewMode.View\n    editMode: 0, // EditMode.Default\n    operationKind: 0, // VisualDataChangeOperationKind.Create\n    duration: 0,\n    isInFocus: false\n};\n\nvisual.update(mockUpdateOptions);\n","lang":"typescript","description":"This quickstart demonstrates a basic Power BI custom visual lifecycle, including initialization, processing data updates, and interacting minimally with the host environment. It shows how to implement `IVisual` and mock `IVisualHost` for testing.","tag":null,"tag_description":null,"last_tested":null,"results":[]},"compatibility":null}