@inglorious/charts
v5.0.2
Published
Chart components for Inglorious Web, inspired by Recharts
Downloads
593
Maintainers
Readme
Inglorious Charts
A powerful, declarative charting library for Inglorious Web, inspired by Recharts. Built with SVG and lit-html, Inglorious Charts provides a flexible and composable way to create beautiful data visualizations.
Features
- 📊 Multiple Chart Types: Line, Area, Bar, Pie, and Donut charts
- 🎨 Two Rendering Modes: Config-first (declarative) and Composition (Recharts-style)
- 🧩 Pure & Stateless: Core logic built with pure functions for predictable rendering and easy testing
- 🎯 Interactive Tooltips: Smart tooltip positioning with automatic overflow detection
- 📈 Multiple Series Support: Render multiple data series in a single chart
- 🎨 Customizable Styling: Full control over colors, sizes, and appearance
- 📱 Responsive: Works seamlessly across different screen sizes
- 🔧 Type-Safe: Built with TypeScript definitions
- 🛡️ Memory-Safe: No global caches or Singletons, preventing memory leaks in complex SPAs
- 🚀 Deterministic Rendering: Optimized rendering engine that avoids expensive try/catch operations and ensures visual stability
Installation
npm install @inglorious/charts
# or
pnpm add @inglorious/chartsQuick Start
Config-First Mode
The simplest way to create charts is using the config-first approach. First, register the chart types in your store:
// In your store/index.js
import { createStore } from "@inglorious/web"
import {
lineChart,
areaChart,
barChart,
pieChart,
donutChart,
} from "@inglorious/charts"
export const store = createStore({
types: {
line: lineChart,
area: areaChart,
bar: barChart,
pie: pieChart,
donut: donutChart,
},
entities,
middlewares,
})Then define your chart entity in the store:
// In your store/entities.js
export const entities = {
myLineChart: {
type: "line",
data: [
{ name: "Jan", value: 400 },
{ name: "Feb", value: 300 },
{ name: "Mar", value: 500 },
],
width: 800,
height: 400,
showGrid: true,
showTooltip: true,
showLegend: true,
},
}Finally, render the chart in your component:
// In your app.js
import { html } from "@inglorious/web"
export const app = {
render(api) {
return html` ${api.render("myLineChart")} `
},
}Composition Mode
For more control and flexibility, use the composition approach. First, define your chart entity in the store:
// In your store/entities.js
export const entities = {
myLineChart: {
type: "line",
data: [
{ name: "Jan", value: 400 },
{ name: "Feb", value: 300 },
{ name: "Mar", value: 500 },
],
},
}Then use the chart helper in your component:
import { html } from "@inglorious/web"
import { chart } from "@inglorious/charts"
export const app = {
render(api) {
return html`
${chart(api, "myLineChart", (c) =>
c.renderLineChart(
[
c.renderCartesianGrid({ stroke: "#eee", strokeDasharray: "5 5" }),
c.renderXAxis({ dataKey: "name" }),
c.renderYAxis({ width: "auto" }),
c.renderLine({
dataKey: "value",
stroke: "#8884d8",
showDots: true,
}),
c.renderTooltip({}),
],
{
width: 800,
height: 400,
dataKeys: ["value"], // Required to sync Y-axis scale across multiple series
stacked: false, // Set to true to automatically sum values (Area/Bar)
},
),
)}
`
},
}Note: The chart helper takes the entityId (e.g., "myLineChart") and fetches the data from your store. You can also override the data by passing it in the config:
c.renderLineChart(
[
/* components */
],
{
width: 800,
height: 400,
dataKeys: ["value"], // Required to sync Y-axis scale across multiple series
stacked: false, // Set to true to automatically sum values (Area/Bar)
data: [
{ name: "Jan", value: 400 },
{ name: "Feb", value: 300 },
], // Override entity data
},
)💡 Smart Layering: The library uses an internal flag system (isGrid, isAxis, etc.) to ensure elements are rendered in the correct visual order (Z-index). The Grid will always be at the back and Axes always at the front, regardless of the order you declare them in the array.
Chart Types
Line Chart
Displays data as a connected line, ideal for showing trends over time.
Config Mode:
{
type: "line",
data: [
{ name: "Jan", value: 100 },
{ name: "Feb", value: 200 },
{ name: "Mar", value: 150 },
],
showPoints: true, // Show dots on data points
}Composition Mode:
c.renderLineChart([
c.renderLine({ dataKey: "value", stroke: "#8884d8", showDots: true }),
// ... other components
])Area Chart
Similar to line charts but with filled areas under the line.
Config Mode:
{
type: "area",
data: [
{ name: "Jan", value: 100 },
{ name: "Feb", value: 200 },
{ name: "Mar", value: 150 },
],
stacked: false, // Set to true for stacked areas
}Composition Mode:
c.renderAreaChart([
c.renderArea({
dataKey: "value",
fill: "#8884d8",
fillOpacity: "0.6",
stroke: "#8884d8",
}),
c.renderDots({ dataKey: "value", fill: "#8884d8" }),
// ... other components
])Bar Chart
Displays data as rectangular bars, perfect for comparing categories.
Config Mode:
{
type: "bar",
data: [
{ name: "A", value: 100 },
{ name: "B", value: 200 },
{ name: "C", value: 150 },
],
}Composition Mode:
c.renderBarChart([
c.renderBar({ dataKey: "value", fill: "#8884d8" }),
// ... other components
])Pie Chart
Circular chart showing proportions of a whole.
Config Mode:
{
type: "pie",
data: [
{ label: "A", value: 30 },
{ label: "B", value: 40 },
{ label: "C", value: 30 },
],
cx: "50%", // Center X
cy: "50%", // Center Y
showTooltip: true,
}Donut Chart
Similar to pie chart but with a hollow center.
Config Mode:
{
type: "donut",
data: [
{ label: "A", value: 30 },
{ label: "B", value: 40 },
{ label: "C", value: 30 },
],
innerRadius: "60%", // Controls the hole size
}Composition Components
When using composition mode, you can combine these components:
Note on Rendering: Components like renderLegend and renderTooltip are rendered as HTML overlays, while renderLine, renderArea, or renderBar are rendered as SVG elements. The library handles this separation automatically to ensure accessibility and styling flexibility.
renderCartesianGrid
Renders grid lines for cartesian charts.
c.renderCartesianGrid({
stroke: "#eee",
strokeDasharray: "5 5",
})renderXAxis
Renders the X-axis with labels.
c.renderXAxis({ dataKey: "name" })renderYAxis
Renders the Y-axis.
c.renderYAxis({ width: "auto" })renderLine
Renders a line series.
c.renderLine({
dataKey: "value",
stroke: "#8884d8",
showDots: true, // Automatically render dots
type: "linear", // Curve type: "linear", "monotone", etc.
})renderArea
Renders an area series.
c.renderArea({
dataKey: "value",
fill: "#8884d8",
fillOpacity: "0.6",
stroke: "#8884d8",
type: "linear",
})renderBar
Renders a bar series.
c.renderBar({
dataKey: "value",
fill: "#8884d8",
})renderDots
Renders dots on data points (alternative to showDots in renderLine).
c.renderDots({
dataKey: "value",
fill: "#8884d8",
r: "0.25em",
stroke: "white",
strokeWidth: "0.125em",
})renderLegend
Renders a legend for multiple series.
c.renderLegend({
dataKeys: ["productA", "productB"],
labels: ["Product A", "Product B"],
colors: ["#8884d8", "#82ca9d"],
})renderTooltip
Renders the tooltip overlay.
c.renderTooltip({})Data Formats
Inglorious Charts supports two data formats:
Wide Format (Recharts Style): Useful for composition. A single object contains multiple keys.
{
name: "Jan",
productA: 100,
productB: 200,
productC: 150,
}Long Format (Config Style): Ideal for dynamic APIs. Separate series with their own arrays.
{
name: "Product A",
values: [
{ x: 0, y: 100 },
{ x: 1, y: 200 },
],
}Multiple Series
Config Mode
For multiple series, use nested data structure:
{
type: "line",
data: [
{
name: "Product A",
values: [
{ x: 0, y: 10 },
{ x: 1, y: 250 },
],
},
{
name: "Product B",
values: [
{ x: 0, y: 280 },
{ x: 1, y: 120 },
],
},
],
showLegend: true,
}Composition Mode
Render multiple series by adding multiple components:
import { html } from "@inglorious/web"
import { chart } from "@inglorious/charts"
// In your component
${chart(api, "multiSeriesChart", (c) =>
c.renderLineChart([
c.renderLegend({
dataKeys: ["productA", "productB"],
labels: ["Product A", "Product B"],
colors: ["#8884d8", "#82ca9d"],
}),
c.renderLine({ dataKey: "productA", stroke: "#8884d8", showDots: true }),
c.renderLine({ dataKey: "productB", stroke: "#82ca9d", showDots: true }),
c.renderTooltip({}),
], {
width: 800,
height: 400,
dataKeys: ["productA", "productB"], // Required to sync Y-axis scale across multiple series
stacked: false, // Set to true to automatically sum values (Area/Bar)
})
)}Styling
Import the base styles and theme:
import "@inglorious/charts/base.css"
import "@inglorious/charts/theme.css"Or customize using CSS variables and classes:
.iw-chart- Main chart container.iw-chart-svg- SVG element.iw-chart-line- Line elements.iw-chart-area- Area elements.iw-chart-bar- Bar elements.iw-chart-dot- Dot elements.iw-chart-modal- Tooltip element. Rendered as absolute HTML outside the SVG, giving you full freedom to use shadows, border-radius, and CSS transitions without SVG limitations..iw-chart-legend- Legend element
API Reference
chart(api, entityId, renderFn)
Helper function for composition mode that provides bound chart methods.
Parameters:
api: Inglorious Web API instanceentityId: Entity ID from the storerenderFn: Function that receives chart methods and returns chart configuration
Returns: TemplateResult
charts.render(entity, api)
Renders a chart from an entity (config mode).
Parameters:
entity: Chart entity objectapi: Inglorious Web API instance
Returns: TemplateResult
Internal Render Method Signature
All render methods follow the standard signature pattern: render<Sub>(entity, props, api)
entity: The chart entity objectprops: Configuration object with method-specific optionsapi: Inglorious Web API instance
This pattern ensures consistency across all chart components and makes the API predictable for developers extending the library.
Chart Entity Properties
Common properties for all chart entities:
type: Chart type ("line","area","bar","pie","donut")data: Array of data pointswidth: Chart width in pixels (default: 800)height: Chart height in pixels (default: 400)showGrid: Show grid lines (default: true)showTooltip: Enable tooltips (default: true)showLegend: Show legend for multi-series (default: true)colors: Array of colors for series (optional)
Examples
See the examples directory for complete working examples of all chart types and rendering modes.
License
MIT
