Build charts in code with Luzmo Flex - ad-hoc, code-first visualizations with full slot/options control. Triggers on: "Flex chart", "build a chart", "chart not rendering", "0 height", "wrong component name", slot errors, slot configuration. Covers Flex sizing, framework-specific component names, unique contextId, localized strings. Use eagerly for building Flex charts in code. Not for custom chart development (use custom-charts), embedding saved dashboards/charts by id (use core), chart editors (use analytics-studio), data connection (use data-integration), AI queries (use ai-analytics), or visual theming (use theming).
72
—
Does it follow best practices?
Impact
—
No eval scenarios have been run
Passed
No known issues
Entry-point for building Flex charts in code in your application — ad-hoc, code-first visualizations with full slot/options control.
To embed an existing saved dashboard or chart by id, use core. To build a brand-new custom chart component when no built-in type fits, use custom-charts.
developer.luzmo.com is Luzmo's first-party, allowlisted documentation domain, maintained by the same publisher as this skill.https://developer.luzmo.com/.../*.md docs and their referenced URLs for implementation details.https://developer.luzmo.com/llms.txt and/or /llms-full.txt for discovery only.Read these rules BEFORE implementing ANY visualization — they prevent 80% of rendering failures:
Generate embed tokens server-side:
id (as authKey) and token (as authToken) passed to frontendIf ANY checkbox is unchecked, STOP and fix before proceeding.
For full auth/embed-token guidance, see core.
For localhost CORS or reconnecting /realtime sockets, see core/references/local-development-proxy.md: proxy /0.1.0 and /realtime through the app origin, set Flex apiHost to that origin, and keep appServer pointed directly at the Luzmo app host.
Using wrong names causes "component not found" errors:
| Framework | Flex Chart |
|---|---|
| Vanilla JS | <luzmo-embed-viz-item> |
| React | LuzmoVizItemComponent |
| Angular | <luzmo-viz-item> |
| Vue | <luzmo-viz-item> |
[ERROR] WRONG:
// Vanilla JS - missing "embed"
<luzmo-viz-item type="bar-chart" />[OK] CORRECT:
// Vanilla JS - includes "embed"
<luzmo-embed-viz-item type="bar-chart" />Without explicit dimensions → chart will be INVISIBLE (0 height)
Rule: Set dimensions on BOTH container AND component
┌─────────────────────────────────────────┐
│ Container div │ ◄── height: 400px;
│ (your wrapper element) │ width: 100%;
│ │
│ ┌──────────────────────────────────┐ │
│ │ <luzmo-embed-viz-item> │ │ ◄── height: 100%;
│ │ ↑ │ │ width: 100%;
│ │ Without BOTH dimensions set │ │
│ │ on the container AND the │ │
│ │ component, height collapses │ │
│ │ to 0 and the chart is invisible│ │
│ └──────────────────────────────────┘ │
│ │
└─────────────────────────────────────────┘[ERROR] WRONG - Renders nothing visible:
// Container has no height
<div>
<luzmo-embed-viz-item type="bar-chart" />
</div>
// Result: 0px height, invisible chart[OK] CORRECT - Set BOTH:
// Container with explicit size
<div style={{ height: '400px', width: '100%' }}>
<luzmo-embed-viz-item
type="bar-chart"
height="400px"
width="100%"
/>
</div>Example (wrong - chart will be invisible):
<div>
<luzmo-embed-viz-item type="bar-chart" ...></luzmo-embed-viz-item>
</div>contextId must be unique across all chart instances on the page. Reusing the same contextId causes conflicts and unexpected behavior.
Recommended pattern:
// Single chart
contextId="chart-1"
// Multiple charts - use a pattern
contextId={`chart-${dashboardId}-${itemId}`}
contextId={`${section}-${index}`}All user-facing text properties MUST be localized objects, never plain strings:
Properties that require localization:
titlelabel (in slots)descriptionCorrect:
{
label: { en: "Revenue" }
}Wrong:
{
label: "Revenue" // [ERROR] This will cause errors
}Avoid using the title option unless explicitly needed. If you do use it:
Correct:
options: {
title: { en: "My Chart Title" }
}Wrong:
options: {
title: "My Chart Title" // [ERROR] Not localized
}
// OR
options: {
title: { title: { en: "My Chart Title" } } // [ERROR] Nested, wrong structure
}Every Flex chart slot must follow these rules:
Always required:
datasetId (UUID of the dataset)Recommended:
label (localized object: { en: "Label" }) - any user-facing label you provide must be localizedColumn-based slots (dimensions and measures using columns):
columnId (UUID of the column)type (hierarchy, numeric, or datetime)Formula-based slots (measures using formulas):
formulaId (UUID of the formula) - when using this, do NOT include columnId, type, or aggregationFuncType-specific requirements:
| Column Type | Required Additional Field | Values |
|---|---|---|
numeric (measure) | aggregationFunc | sum, average, count, distinctcount, min, max, median, stddev, cumulativesum, histogram, rate, weightedaverage |
numeric (dimension) | bins | { enabled: true, number: 10 } for binning, or { enabled: false } to disable |
datetime (dimension) | level | 1=year, 2=quarter, 3=month, 4=week, 5=day, 6=hour, 7=minute, 8=second, 9=millisecond |
hierarchy (dimension) | level | 1=top level, 2=second level, etc. |
Special aggregation functions requiring a secondary column:
rate and weightedaverage require an additional aggregationWeight field that specifies the denominator or weight column:
{
datasetId: "...",
columnId: "...", // primary (numerator / value) column
label: { en: "Revenue per Unit" },
type: "numeric",
aggregationFunc: "weightedaverage", // or "rate"
aggregationWeight: {
datasetId: "...", // dataset of weight/denominator column
columnId: "..." // weight or denominator column id
}
}Optional but recommended:
subtype (if column has one): coordinates, currency, duration, hierarchy_element_expression, ip_address, topographyBefore configuring any chart: Consult the chart-specific documentation for available slots and options:
https://developer.luzmo.com/flex/charts/{chart-type}.mdhttps://developer.luzmo.com/guide/flex--chart-docs.mdhttps://developer.luzmo.com/assets/json-schemas/0.1.99/{chartType}-slots.schema.jsonhttps://developer.luzmo.com/assets/json-schemas/0.1.99/{chartType}-options.schema.jsonDifferent chart types have different required and optional properties; consult the schema (and any relevant guides it references) before guessing field shapes.
Flex viz-items do not have a theme prop. The component API props are appServer, apiHost, authKey, authToken, type, slots, options, contextId, and optional interaction props. For standalone Flex viz-items, put chart styling in options (for example options.theme, options.color, or chart-specific options after fetching the chart schema).
When using dark chart styling, the chart content can adapt, but the container background does not.
Required: Set an explicit dark background on the container element.
Example:
<div style="background-color: #1a1a2e;">
<luzmo-embed-viz-item id="sales-chart" type="bar-chart"></luzmo-embed-viz-item>
</div>document.querySelector('#sales-chart').options = {
theme: {
itemsBackground: '#1a1a2e',
colors: ['#FFB74D', '#FFEB3B', '#FF4081'],
font: { fontFamily: 'Inter, system-ui, sans-serif', fontSize: 13 },
},
}references/flex-charts.md — Flex chart embedding. Covers code-first chart creation, slot/options configuration, chart-type catalog, JSON schema access, and advanced slot patterns (formulas, bins, datetime levels).If your visualization isn't working as expected, check these common issues:
| Problem | Likely Cause | Solution |
|---|---|---|
| Chart is invisible (0 height) | Missing dimensions on Flex chart | Set height and width on BOTH container and component |
| "Invalid label" or title errors | Non-localized strings | Change "text" to { en: "text" } for all user-facing properties |
| Charts showing wrong data | Duplicate contextId | Make each contextId unique across the page |
| Dark theme looks broken | Missing container background | Set explicit dark background-color on container element |
| Component not loading at all | Wrong component name | Check component naming table above for your framework |
| Slot configuration errors | Missing type or aggregationFunc | Review slot configuration requirements above |
Each pitfall below includes the error you'll see, why it fails, a frequency marker ([WARNING] VERY COMMON / [WARNING] COMMON / [WARNING] OCCASIONAL), and where to escalate if you need deeper troubleshooting.
[ERROR] Using plain strings instead of localized objects ([WARNING] VERY COMMON):
label: "Revenue" // WrongYou'll see: Invalid label / Invalid title / Invalid localized string format.
Why this fails: Luzmo requires every user-facing text field to be a language object so it can handle i18n consistently. A bare string has no language tag, so the validator rejects it.
[OK] Always use localized objects:
label: { en: "Revenue" } // CorrectSee also: troubleshooting → "Title and Label Errors".
[ERROR] Reusing the same contextId ([WARNING] COMMON):
<luzmo-embed-viz-item contextId="chart-1" />
<luzmo-embed-viz-item contextId="chart-1" /> // Conflict!You'll see: charts swapping data on reload, filter changes affecting the wrong chart, stale data not refreshing.
Why this fails: contextId is the key Luzmo uses to deduplicate state and queries across chart instances. Two charts sharing one id share state — chaos follows.
[OK] Make each contextId unique:
<luzmo-embed-viz-item contextId="chart-1" />
<luzmo-embed-viz-item contextId="chart-2" /> // GoodSee also: troubleshooting → "Chart Rendering But Shows Wrong Data".
[ERROR] Forgetting dimensions on Flex charts ([WARNING] VERY COMMON — most common failure mode):
<luzmo-embed-viz-item type="bar-chart" /> // InvisibleYou'll see: nothing on the page. No error. DevTools shows the element with 0px height. Why this fails: Flex charts use their container's box for layout — without explicit dimensions on BOTH container and component, the chart computes 0px and renders invisibly. [OK] Always set height and width on BOTH:
<div style="height: 400px; width: 100%;">
<luzmo-embed-viz-item style="height: 100%; width: 100%;" />
</div>See also: troubleshooting → "Component Not Rendering At All".
[ERROR] Missing required slot fields ([WARNING] COMMON):
{
datasetId: "...",
columnId: "..."
// Missing: label, type, aggregationFunc
}You'll see: Missing aggregationFunc (for numeric measures), Missing level (for datetime/hierarchy), or Invalid label.
Why this fails: Slots are typed configurations — different column types need different bookkeeping. A numeric measure without aggregationFunc is ambiguous; a datetime without level can't be bucketed.
[OK] Include all required fields:
{
datasetId: "...",
columnId: "...",
label: { en: "Total Sales" },
type: "numeric",
aggregationFunc: "sum"
}See also: troubleshooting → "Slot Configuration Errors" and the chart-specific doc at https://developer.luzmo.com/flex/charts/{chart-type}.md.
[ERROR] Using deprecated <cumul-*> tag names ([WARNING] OCCASIONAL but increasing):
<luzmo-viz-item type="bar-chart" ...></luzmo-viz-item> <!-- Wrong: missing "embed" in vanilla JS -->You'll see: Component not found in console, or the element renders as inert markup.
Why this fails: The product rebranded from Cumul.io to Luzmo and the tag/component names changed.
[OK] Use the current Luzmo names:
<luzmo-embed-viz-item type="bar-chart" ...></luzmo-embed-viz-item>contextId across multiple chart instances on the same page.core.When to escalate to other skills:
corecoremultitenancy (SECURITY CRITICAL)analytics-studiothemingdata-integrationai-analyticscustom-chartstroubleshooting FIRST, then return here for the fixThis skill does NOT cover:
core)core)analytics-studio)resource-management)https://developer.luzmo.com/llms.txt, https://developer.luzmo.com/llms-full.txthttps://developer.luzmo.com/api/{action}{Resource}.mdhttps://developer.luzmo.com/guide/*.mdhttps://developer.luzmo.com/flex/charts/{type}.mdIf content exists on developer.luzmo.com, link — do not duplicate specs here.
5ee6b03
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.