@akitain/sandjs
v0.3.6
Published
Sunburst Advanced Node Data
Readme
Sand.js
Sunburst Advanced Node Data
A lightweight, framework-agnostic JavaScript library for building interactive sunburst charts using SVG. Sand.js is fully data-driven: describe your chart in JSON, and it handles both layout computation and rendering.
Documentation
For detailed guides, API reference, and examples, visit the full documentation.
Table of Contents
- Introduction
- Installation
- Quick Start
- Core Concepts
- Configuration Reference
- Features
- API Reference
- Build & Development
- CDN Usage
- License
Introduction
Sand.js is designed for developers who need to visualize hierarchical data as sunburst charts with minimal setup. Built with modern web standards, it offers:
- Zero dependencies: Lightweight and fast
- Framework agnostic: Works with vanilla JavaScript or any framework
- JSON-driven: Declarative configuration
- Interactive: Built-in tooltips, navigation, and event callbacks
- Customizable: Extensive theming and styling options
- TypeScript ready: Full type definitions included
Installation
npm install @akitain/sandjsFor Yarn users:
yarn add @akitain/sandjsQuick Start
Create a basic sunburst chart in three steps:
- Add an SVG element to your HTML:
<svg id="chart"></svg>- Define your data configuration:
import { renderSVG } from '@akitain/sandjs';
const config = {
size: { radius: 200 },
layers: [
{
id: 'main',
radialUnits: [0, 2],
angleMode: 'free',
tree: [
{ name: 'Engineering', value: 45, key: 'eng' },
{
name: 'Design',
value: 30,
key: 'design',
children: [
{ name: 'UI', value: 15 },
{ name: 'UX', value: 15 }
]
},
{ name: 'Marketing', value: 25, key: 'marketing' }
]
}
]
};- Render the chart:
const chart = renderSVG({
el: '#chart',
config,
tooltip: true
});That's it! You now have a fully interactive sunburst chart.
Core Concepts
Understanding these fundamental concepts will help you build complex charts:
Sunburst
The complete chart containing one or more layers. Defined by overall size (radius and optional angle).
Layer
A logical grouping of rings with a shared dataset. Layers can operate independently (free mode) or align with other layers (align mode).
Properties:
id(string): Unique identifierradialUnits([number, number]): Inner and outer radial positionsangleMode('free' | 'align'): How angular space is distributedtree(Node | Node[]): Data structure for the layer
Node
A unit of data representing a segment in your chart. Nodes can have children for hierarchical data.
Key properties:
name(string): Display labelvalue(number): Size of the segmentkey(string, optional): Stable identifier for animations and alignmentchildren(Node[], optional): Child nodes for hierarchical structure
Arc
A computed geometric entity created by the layout engine, ready for rendering with coordinates and metadata.
Ring
A radial band in the chart, automatically calculated based on nodes and their expandLevels property.
Key-group
Nodes sharing the same key value, used for alignment across layers and coordinated interactions.
Configuration Reference
SunburstConfig
The root configuration object for your chart.
{
size: {
radius: number; // Final radius in pixels
angle?: number; // Total angle in radians (default: 2π)
},
layers: LayerConfig[] // Array of layer definitions
}LayerConfig
{
id: string; // Unique layer identifier
radialUnits: [number, number]; // [inner, outer] radial positions
angleMode: 'free' | 'align'; // Angular distribution mode
alignWith?: string; // Reference layer ID (for 'align' mode)
padAngle?: number; // Gap between arcs (radians)
baseOffset?: number; // Global rotation offset (radians)
arcOffsetMode?: 'relative' | 'absolute'; // Offset calculation mode
defaultArcOffset?: number; // Default offset for all arcs
borderColor?: string; // Border color for arcs in this layer
borderWidth?: number; // Border width in pixels
labelColor?: string; // Label text color for this layer
showLabels?: boolean; // Show/hide labels for this layer
tree: TreeNodeInput | TreeNodeInput[]; // Data structure
}TreeNodeInput
{
name: string; // Display name
value: number; // Arc size (auto-summed if children exist)
key?: string; // Stable identifier
expandLevels?: number; // Radial thickness in rings (default: 1)
offset?: number; // Local angular offset
color?: string; // Custom color (CSS format)
labelColor?: string; // Custom label text color
children?: TreeNodeInput[]; // Child nodes
tooltip?: string; // Custom tooltip content
collapsed?: boolean; // Hide children while preserving value
hidden?: boolean; // Hide node completely
}Features
Color Themes
Sand.js includes 14 built-in color palettes across three theme types.
Qualitative Themes
Best for categorical data with no inherent order:
import { renderSVG, QUALITATIVE_PALETTES } from '@akitain/sandjs';
renderSVG({
el: '#chart',
config,
colorTheme: {
type: 'qualitative',
palette: 'ocean', // 'default' | 'pastel' | 'vibrant' | 'earth' | 'ocean' | 'sunset'
assignBy: 'key' // Color assignment strategy
}
});Sequential Themes
Best for ordered data with progression from low to high:
colorTheme: {
type: 'sequential',
palette: 'blues', // 'blues' | 'greens' | 'purples' | 'oranges'
assignBy: 'depth'
}Diverging Themes
Best for data with a meaningful midpoint (e.g., positive/negative values):
colorTheme: {
type: 'diverging',
palette: 'redBlue', // 'redBlue' | 'orangePurple' | 'greenRed'
assignBy: 'value'
}Color Assignment Strategies
- key: Consistent colors based on arc keys (default for qualitative)
- depth: Colors vary by hierarchical depth (default for sequential/diverging)
- index: Sequential assignment by arc position
- value: Colors mapped to normalized values
Custom Palettes
colorTheme: {
type: 'qualitative',
palette: ['#ff6b6b', '#4ecdc4', '#45b7d1', '#f7dc6f'],
assignBy: 'key'
}Custom Color Keys
colorTheme: {
type: 'qualitative',
palette: 'default',
deriveKey: (arc) => arc.data.category // Use any arc property
}Note: Individual node.color values always override theme colors.
Navigation & Drilldown
Enable interactive drill-down navigation with smooth transitions:
Basic Usage
const chart = renderSVG({
el: '#chart',
config,
navigation: true, // Enable with defaults
transition: true // Enable smooth animations
});Advanced Options
navigation: {
layers: ['main', 'details'], // Specify navigable layers
rootLabel: 'Home', // Breadcrumb root text
focusTransition: {
duration: 600, // Animation duration (ms)
easing: (t) => t * t // Custom easing function
},
onFocusChange: (focus) => {
if (focus) {
console.log('Focused:', focus.arc.data.name);
} else {
console.log('Reset to root');
}
}
}Programmatic Control
// Reset to root view
chart.resetNavigation?.();Tooltips
Display contextual information on hover.
Basic Tooltips
renderSVG({
el: '#chart',
config,
tooltip: true // Enable default tooltips
});Custom Tooltips
tooltip: {
formatter: (arc) => {
return `
<strong>${arc.data.name}</strong><br>
Value: ${arc.data.value}<br>
Percentage: ${arc.percentage.toFixed(1)}%
`;
},
container: '#tooltip-container' // Custom container selector
}Per-Node Tooltips
tree: [
{
name: 'Engineering',
value: 45,
tooltip: 'Custom tooltip for Engineering department'
}
]Breadcrumbs
Visualize the current navigation path.
Basic Breadcrumbs
renderSVG({
el: '#chart',
config,
breadcrumbs: true // Enable with defaults
});Advanced Configuration
breadcrumbs: {
container: '#breadcrumb-trail', // Custom container
interactive: true, // Enable click navigation
separator: ' › ', // Custom separator
rootLabel: 'Overview', // Root element label
formatter: (arc) => arc.data.name.toUpperCase() // Custom formatting
}Highlighting
Highlight related arcs by key.
Basic Highlighting
renderSVG({
el: '#chart',
config,
highlightByKey: true // Enable with defaults
});Advanced Options
highlightByKey: {
className: 'highlighted', // Custom CSS class
pinOnClick: true, // Keep highlight on click
onPinChange: (key, pinned) => {
console.log(`${key} is ${pinned ? 'pinned' : 'unpinned'}`);
}
}Transitions
Smooth animations when updating your chart.
Enable Transitions
renderSVG({
el: '#chart',
config,
transition: true // Enable with defaults
});Custom Transition Settings
transition: {
duration: 800, // Animation duration (ms)
easing: (t) => t * t, // Easing function
delay: 100 // Delay before animation starts (ms)
}Updating with Transitions
const chart = renderSVG({ el: '#chart', config, transition: true });
// Later, update with smooth transition
chart.update({
config: newConfig,
transition: {
duration: 500
}
});Labels
Render text labels on arcs.
Enable Labels
renderSVG({
el: '#chart',
config,
labels: true // Enable default labels
});Custom Label Formatting
labels: {
formatter: (arc) => {
if (arc.percentage > 10) {
return `${arc.data.name} (${arc.percentage.toFixed(0)}%)`;
}
return ''; // Hide labels for small arcs
}
}Note: Labels automatically hide on arcs that are too narrow to display text legibly.
API Reference
renderSVG(options)
Main function to create a sunburst chart.
Parameters:
{
el: string | SVGElement; // Target SVG element or selector
config: SunburstConfig; // Chart configuration
tooltip?: boolean | TooltipOptions; // Tooltip settings
breadcrumbs?: boolean | BreadcrumbOptions; // Breadcrumb settings
highlightByKey?: boolean | HighlightByKeyOptions; // Highlight settings
navigation?: boolean | NavigationOptions; // Navigation settings
transition?: boolean | TransitionOptions; // Transition settings
labels?: boolean | LabelOptions; // Label settings
colorTheme?: ColorThemeOptions; // Color theme
onArcEnter?: (payload) => void; // Hover enter callback
onArcMove?: (payload) => void; // Hover move callback
onArcLeave?: (payload) => void; // Hover leave callback
onArcClick?: (payload) => void; // Click callback
debug?: boolean; // Enable diagnostic logging
}Returns:
{
update: (updateInput) => void; // Update the chart
dispose: () => void; // Clean up resources
resetNavigation?: () => void; // Reset to root (if navigation enabled)
}layout(config)
Compute arc geometries from configuration (layout-only mode).
Parameters:
config(SunburstConfig): Chart configuration
Returns:
LayoutArc[]: Array of computed arcs with geometry and metadata
formatArcBreadcrumb(arc)
Generate a breadcrumb trail for an arc.
Parameters:
arc(LayoutArc): The arc to generate breadcrumbs for
Returns:
BreadcrumbTrailItem[]: Array of breadcrumb items
Build & Development
Development Setup
# Clone the repository
git clone https://github.com/aqu1tain/sandjs.git
cd sandjs
# Install dependencies
npm install
# Run tests
npm test
# Build the library
npm run build
# Run tests and build
npm run verifyDevelopment Server
npm run devOpens a development server at http://localhost:4173 with live examples.
Project Structure
sandjs/
├── src/
│ ├── index.ts # Public API exports
│ ├── layout/ # Layout computation
│ ├── render/ # SVG rendering
│ └── types/ # TypeScript definitions
├── demo/ # Interactive examples
├── dist/ # Build output (generated)
└── tests/ # Test suiteBuild Output
dist/sandjs.mjs: ES Module (default)dist/sandjs.iife.min.js: Minified IIFE for CDN usagedist/index.d.ts: TypeScript type definitions
CDN Usage
For quick prototyping or non-bundled environments:
<svg id="chart"></svg>
<script src="https://unpkg.com/@akitain/[email protected]/dist/sandjs.iife.min.js"></script>
<script>
const { renderSVG } = window.SandJS;
renderSVG({
el: '#chart',
config: {
size: { radius: 200 },
layers: [
{
id: 'main',
radialUnits: [0, 2],
angleMode: 'free',
tree: [
{ name: 'Category A', value: 40 },
{ name: 'Category B', value: 60 }
]
}
]
},
tooltip: true
});
</script>License
MIT © Aqu1tain
