Vistral
Visual + Stream , a live stream data visualization lib, follows the Grammar of Graphics
Install / Use
/learn @timeplus-io/VistralREADME
A powerful streaming data visualization library based on the Grammar of Graphics. Designed for real-time data visualization with support for time series, bar/column charts, single value metrics, and data tables.

Introduction Blog https://www.timeplus.com/post/vistral
Examples and Playground can be found here https://timeplus-io.github.io/vistral/
Introduction Presentation https://timeplus-io.github.io/gg-vistral-introduction/
Concept Introduction https://timeplus-io.github.io/vistra-temporal-binding/
API Reference docs/api-reference.md
Design Principles docs/design-principles.md
Table of Contents
- Features
- Installation
- Quick Start
- Chart Types
- Temporal Binding Modes
- Using Individual Chart Components
- Data Format
- Streaming Data with Hooks
- Color Palettes
- API Reference
- Design Principles
- Development
- Browser Support
- License
Features
- 📊 Multiple Chart Types: Line, Area, Bar, Column, Single Value, Data Table, and Geo Map
- 🔄 Streaming Support: Built for real-time data with efficient updates
- ⏱️ Temporal Binding: Three modes for handling streaming data (axis-bound, frame-bound, key-bound)
- 🎨 Beautiful Themes: Dark and light themes with customizable color palettes
- 📱 Responsive: Auto-fit to container with resize detection
- 🎯 TypeScript: Full TypeScript support with comprehensive types
- ⚡ Performant: Optimized for streaming data with minimal re-renders
- 🧩 Modular: Use the unified
StreamChartor individual chart components
Installation
NPM/Yarn/PNPM
npm install @timeplus/vistral
UMD (Browser/CDN)
Vistral is available as a UMD bundle, allowing you to use it directly in the browser via script tags.
<!-- 1. Dependencies -->
<script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/lodash@4/lodash.min.js"></script>
<script src="https://unpkg.com/ramda@0.29/dist/ramda.min.js"></script>
<script src="https://unpkg.com/@antv/g2@5/dist/g2.min.js"></script>
<script src="https://unpkg.com/@antv/s2@2/dist/s2.min.js"></script>
<!-- 2. Vistral -->
<script src="https://unpkg.com/@timeplus/vistral/dist/index.umd.min.js"></script>
<!-- 3. Usage -->
<script>
const { Vistral, React, ReactDOM } = window;
const { StreamChart } = Vistral;
const data = {
columns: [{ name: 'val', type: 'number' }],
data: [{ val: 10 }, { val: 20 }]
};
const config = { chartType: 'table' };
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(React.createElement(StreamChart, { data, config }));
</script>
Peer Dependencies
Make sure you have React installed (if using NPM):
npm install react react-dom
Quick Start
import { StreamChart } from '@timeplus/vistral';
function App() {
const data = {
columns: [
{ name: 'timestamp', type: 'datetime64' },
{ name: 'value', type: 'float64' },
{ name: 'category', type: 'string' },
],
data: [
['2024-01-01T10:00:00Z', 42.5, 'A'],
['2024-01-01T10:01:00Z', 45.2, 'A'],
['2024-01-01T10:02:00Z', 38.1, 'B'],
// ... more data
],
};
const config = {
chartType: 'line',
xAxis: 'timestamp',
yAxis: 'value',
color: 'category',
legend: true,
gridlines: true,
};
return (
<div style={{ width: '100%', height: '400px' }}>
<StreamChart config={config} data={data} theme="dark" />
</div>
);
}
Chart Types
Line Chart

Perfect for time series data showing trends over time.
import { StreamChart } from '@timeplus/vistral';
<StreamChart
config={{
chartType: 'line',
xAxis: 'timestamp',
yAxis: 'value',
color: 'series',
lineStyle: 'curve', // or 'straight'
points: true,
legend: true,
gridlines: true,
temporal: {
mode: 'axis',
field: 'timestamp',
range: 5, // Show last 5 minutes
},
fractionDigits: 2,
}}
data={data}
theme="dark"
/>
Area Chart

Similar to line charts but with filled areas, great for showing volume or stacked data.
<StreamChart
config={{
chartType: 'area',
xAxis: 'timestamp',
yAxis: 'value',
color: 'category', // Creates stacked areas
legend: true,
}}
data={data}
/>
Bar Chart (Horizontal)

Horizontal bar charts for categorical comparisons.
<StreamChart
config={{
chartType: 'bar',
xAxis: 'category',
yAxis: 'value',
color: 'subcategory',
groupType: 'stack', // or 'dodge'
dataLabel: true,
}}
data={data}
/>
Column Chart (Vertical)

Vertical column charts for categorical data.
<StreamChart
config={{
chartType: 'column',
xAxis: 'month',
yAxis: 'sales',
color: 'region',
groupType: 'dodge',
gridlines: true,
}}
data={data}
/>
Single Value

Display a single metric with optional sparkline and delta indicator.
<StreamChart
config={{
chartType: 'singleValue',
yAxis: 'activeUsers',
fontSize: 72,
color: 'green',
fractionDigits: 0,
sparkline: true,
delta: true,
unit: { position: 'left', value: '$' },
}}
data={data}
/>
Multiple Value

Display multiple values side-by-side, split by a specific key. Key bound is required.
<StreamChart
config={{
chartType: 'multipleValue',
yAxis: 'cpu_usage',
key: 'server_id',
fontSize: 48,
color: 'cyan',
fractionDigits: 0,
sparkline: true,
delta: true,
unit: { position: 'right', value: '%' },
}}
data={data}
/>
Data Table

Display streaming data in a tabular format with column configuration.
<StreamChart
config={{
chartType: 'table',
tableStyles: {
timestamp: { name: 'Time', width: 200 },
value: {
name: 'Value',
miniChart: 'sparkline',
color: {
type: 'condition',
conditions: [
{ operator: 'gt', value: 100, color: '#22C55E' },
{ operator: 'lt', value: 50, color: '#EF4444' },
],
},
},
},
temporal: {
mode: 'key', // Deduplicate by key
field: 'id',
},
}}
data={data}
/>
Geo Chart

Display geographic data points on an interactive map with pan and zoom.
<StreamChart
config={{
chartType: 'geo',
latitude: 'lat',
longitude: 'lng',
color: 'category', // Color points by category
size: {
key: 'value', // Size points by value
min: 4,
max: 20,
},
zoom: 3,
center: [40.7128, -74.006], // [lat, lng]
showZoomControl: true,
showCenterDisplay: true,
pointOpacity: 0.8,
}}
data={data}
/>
Temporal Binding Modes
Vistral provides three temporal binding modes for handling streaming data:
| Mode | Description | Use Case | |------|-------------|----------| | axis | Time mapped to axis with sliding window | Time-series trends | | frame | Only latest timestamp visible | Real-time snapshots | | key | Latest value per unique key | Live dashboards |
Axis-Bound (Sliding Window)
For time series charts, shows a sliding time window:
<StreamChart
config={{
chartType: 'line',
xAxis: 'timestamp',
yAxis: 'value',
temporal: {
mode: 'axis',
field: 'timestamp',
range: 5, // 5-minute window
},
}}
data={data}
/>
Frame-Bound (Latest Timestamp)
Shows only rows with the latest timestamp - useful for real-time snapshots:
<StreamChart
config={{
chartType: 'table',
temporal: {
mode: 'frame',
field: 'timestamp',
},
}}
data={data}
/>
Key-Bound (Deduplicate by Key)
Keeps the latest value for each unique key. Supports composite keys by passing an array o
Related Skills
node-connect
343.3kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
92.1kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
Writing Hookify Rules
92.1kThis skill should be used when the user asks to "create a hookify rule", "write a hook rule", "configure hookify", "add a hookify rule", or needs guidance on hookify rule syntax and patterns.
review-duplication
99.7kUse this skill during code reviews to proactively investigate the codebase for duplicated functionality, reinvented wheels, or failure to reuse existing project best practices and shared utilities.
