@microsoft/fabric-visuals
v1.1.0
Published
Vega-Lite visualization component for Fabric Apps - Analytics
Readme
@microsoft/fabric-visuals
Vega-Lite visualization component for Fabric Apps - Analytics
Quick Reference
Package:
@microsoft/fabric-visualsPurpose: React component for rendering Vega-Lite visualizations in Fabric Apps. Use when: You need to render charts (bar, line, area, scatter, etc.) from aDataTableusing Vega-Lite specs. Do NOT use when: You need a data grid/table (use@microsoft/fabric-datagrid), or you only need shared types/tokens (use@microsoft/fabric-visuals-core). Key exports:VegaVisual,VegaVisualProps,VegaVisualHandle,useCssThemePeer dependencies:@microsoft/fabric-visuals-coreInstall:npm install @microsoft/fabric-visuals @microsoft/fabric-visuals-core
Ecosystem Context
@microsoft/fabric-visualsdepends on@microsoft/fabric-visuals-corefor sharedDataTable,ColumnDef, andVisualThemecontracts, plus design-token-backed theme values.- It is the charting sibling to
@microsoft/fabric-datagrid, which renders the sameDataTableshape as a table/grid instead of a chart. - In Fabric Apps - Analytics, the data passed to
VegaVisualtypically comes from@microsoft/fabric-app-dataqueries, then gets mapped into aDataTable.
Installation
npm install @microsoft/fabric-visuals @microsoft/fabric-visuals-core@microsoft/fabric-visuals-core is required alongside this package because the public API uses its DataTable and VisualTheme types.
Public API
The package entry point exports only the symbols below.
React exports
export interface VegaVisualProps {
spec: VisualizationSpec | string;
theme: VisualTheme;
data?: DataTable | null;
configVegaLite?: VegaLiteConfig;
capabilities?: VegaVisualCapabilities;
onEvent?: VegaVisualEventCallback;
className?: string;
style?: CSSProperties;
}
export interface VegaVisualHandle {
readonly view: View | null;
}
export const VegaVisual: React.ForwardRefExoticComponent<
VegaVisualProps & React.RefAttributes<VegaVisualHandle>
>;| Export | Signature | Notes |
| --- | --- | --- |
| VegaVisual | React.ForwardRefExoticComponent<VegaVisualProps & React.RefAttributes<VegaVisualHandle>> | Responsive SVG Vega/Vega-Lite renderer. Injects DataTable data, compiles Vega-Lite, and exposes the underlying Vega View through a ref. |
| VegaVisualProps | interface above | spec accepts a parsed Vega-Lite object or a JSON string. configVegaLite merges on top of the built-in base theme. |
| VegaVisualHandle | interface above | ref.current?.view gives direct access to the current Vega View. |
Theme hook
export function useCssTheme(): VisualTheme;Reads the current CSS custom properties via @microsoft/fabric-visuals-core and returns a live VisualTheme that updates when the app theme changes.
Types and constants
export type VisualizationSpec = VegaLiteSpec;
export type VegaLiteConfig = VlConfig;
export type LogLevelName = 'error' | 'warn' | 'info' | 'debug' | 'none';
export const LOG_LEVEL_MAP: Record<LogLevelName, number>;
export type VegaVisualEventType = 'render' | 'error' | 'vega' | 'specUpdate';
export type VegaVisualEventLevel = Exclude<LogLevelName, 'none'>;
export interface VegaVisualEventDetail {
readonly type: VegaVisualEventType;
readonly level: VegaVisualEventLevel;
readonly message: string;
readonly spec?: string;
readonly args?: readonly unknown[];
}
export type VegaVisualEventCallback =
(event: CustomEvent<VegaVisualEventDetail>) => void;| Export | Signature | Notes |
| --- | --- | --- |
| VisualizationSpec | VegaLiteSpec | Alias for Vega-Lite top-level specs. |
| VegaLiteConfig | VlConfig | Alias for Vega-Lite config objects. |
| LogLevelName | 'error' \| 'warn' \| 'info' \| 'debug' \| 'none' | Friendly log-level names. |
| LOG_LEVEL_MAP | Record<LogLevelName, number> | Maps friendly names to Vega numeric log levels. |
| VegaVisualEventType | 'render' \| 'error' \| 'vega' \| 'specUpdate' | Unified event subtypes. |
| VegaVisualEventLevel | Exclude<LogLevelName, 'none'> | Event levels emitted by VegaVisual. |
| VegaVisualEventDetail | interface above | Payload for all onEvent callbacks. |
| VegaVisualEventCallback | (event: CustomEvent<VegaVisualEventDetail>) => void | Single callback shape for render, error, and Vega log events. |
Internal theme/color utilities
vegaLiteBaseTheme, themeToVegaConfig, compileSpec, applyColumnFormats, and generateColorPalette(baseColors: readonly string[], sectors = 12): string[] exist in src/, but they are not exported from the package entry point.
Capabilities
VegaVisual applies a set of optimistic transforms during spec compilation. The optional capabilities prop lets consumers selectively disable these behaviors by passing a partial VegaVisualCapabilities object. All flags default to false (behavior enabled); set a flag to true to disable it.
Interface
import type { VegaVisualCapabilities } from '@microsoft/fabric-visuals';
interface VegaVisualCapabilities {
disableStackedDataLabels?: boolean;
disableNiceAxisBounds?: boolean;
disableLineChartCrosshairTooltip?: boolean;
disableTextTruncation?: boolean;
disableLegendTruncation?: boolean;
disableCategoricalScroll?: boolean;
disableMinBarSize?: boolean;
disableDynamicAxisLabelOverlap?: boolean;
disableNonZeroQuantitativeBaseline?: boolean;
}Capability flags
| Flag | Default | Effect when true |
|------|---------|-------------------|
| disableStackedDataLabels | false | Skips adding centered white text labels on eligible stacked bar charts. |
| disableNiceAxisBounds | false | Skips setting scale.nice = 5 on quantitative axes for cleaner tick values. |
| disableLineChartCrosshairTooltip | false | Skips adding the vertical rule + highlighted points on line/area charts. |
| disableTextTruncation | false | Skips truncating long text marks to prevent overflow. |
| disableLegendTruncation | false | Skips capping legend entry count based on chart dimensions. |
| disableCategoricalScroll | false | Skips making bar/column charts scrollable when categories overflow. |
| disableMinBarSize | false | Skips enforcing a minimum bar thickness for small values. |
| disableDynamicAxisLabelOverlap | false | Skips rotation-aware labelOverlap assignment (rotated → no removal, horizontal → parity). |
| disableNonZeroQuantitativeBaseline | false | Skips allowing non-zero baselines for non-stacked, quantitative measures. |
Usage
import { VegaVisual, useCssTheme } from '@microsoft/fabric-visuals';
import type { VegaVisualCapabilities } from '@microsoft/fabric-visuals';
const capabilities: VegaVisualCapabilities = {
disableCategoricalScroll: true,
disableMinBarSize: true,
};
export function Example() {
const theme = useCssTheme();
return (
<VegaVisual
spec={spec}
data={data}
theme={theme}
capabilities={capabilities}
/>
);
}Omitted keys keep their default behavior. The capabilities object is shallowly merged with the defaults at render time — you only need to specify the flags you want to change.
Key Constraints & Gotchas
DO NOT put config in Vega-Lite spec JSON files
VegaVisual always applies its built-in theme. Custom config in the spec is overridden.
// ✅ DO: Pass overrides via configVegaLite prop
<VegaVisual spec={spec} theme={theme} configVegaLite={{ axis: { labelAngle: -45 } }} />
// ❌ DON'T: Put config inside the Vega-Lite spec
const spec = { mark: "bar", config: { axis: { labelAngle: -45 } }, ... }; // config is ignoredClean legend labels at the data level, not with labelExpr
VegaVisual renders its own custom legend UI and ignores Vega-Lite labelExpr.
// ✅ DO: Use a calculate transform to clean values
{ "calculate": "split(datum['Category[Name]'], ']')[0]", "as": "CleanCategory" }
// ❌ DON'T: Use labelExpr in encoding — it will be ignored
{ "encoding": { "color": { "legend": { "labelExpr": "split(datum.label, ']')[0]" } } } }Bracket escaping differs between encoding and calculate
// ✅ DO: Use \\[ in encoding field references
{ "encoding": { "x": { "field": "Date\\[MonthName\\]" } } }
// ✅ DO: Use raw brackets in calculate expressions
{ "calculate": "datum['Date[MonthName]']", "as": "Month" }
// ❌ DON'T: Use raw brackets in encoding fields
{ "encoding": { "x": { "field": "Date[MonthName]" } } }
// ❌ DON'T: Use \\[ escaping in calculate expressions
{ "calculate": "datum['Date\\[MonthName\\]']", "as": "Month" }Dual Y-axis charts need nested layers
// ✅ DO: Wrap each series in its own layer
{
"resolve": { "scale": { "y": "independent" } },
"layer": [
{ "layer": [{ "mark": "line", ... }, { "mark": "point", ... }] },
{ "layer": [{ "mark": "line", ... }, { "mark": "point", ... }] }
]
}Minimal Usage Examples
Basic component usage
import { VegaVisual, useCssTheme } from '@microsoft/fabric-visuals';
import type { VisualizationSpec } from '@microsoft/fabric-visuals';
import type { DataTable } from '@microsoft/fabric-visuals-core';
const spec: VisualizationSpec = {
$schema: 'https://vega.github.io/schema/vega-lite/v6.json',
mark: 'bar',
encoding: {
x: { field: 'category', type: 'nominal', title: 'Category' },
y: { field: 'value', type: 'quantitative', title: 'Value' },
},
};
const data: DataTable = {
columns: [
{ name: 'category', displayName: 'Category' },
{ name: 'value', displayName: 'Value', format: '#,##0' },
],
rows: [
['A', 10],
['B', 25],
['C', 18],
],
};
export function Example() {
const theme = useCssTheme();
return (
<VegaVisual
spec={spec}
data={data}
theme={theme}
style={{ height: 320 }}
/>
);
}Trademarks
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft's Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies.
Security
Microsoft takes the security of our software products and services seriously, which includes all source code repositories in our GitHub organizations.
Please do not report security vulnerabilities through public GitHub issues.
For security reporting information, locations, contact information, and policies, please review the latest guidance for Microsoft repositories at https://aka.ms/SECURITY.md.
Code of conduct
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
