Now.js Framework Documentation
GraphComponent - Data Visualization
GraphComponent - Data Visualization
Documentation for GraphComponent, a UI Component for displaying graphs and charts
📋 Table of Contents
- Overview
- Installation and Import
- Basic Usage
- Chart Types
- HTML Attributes
- Configuration Options
- Data Format
- Styling and Customization
- Events
- JavaScript API
- Usage Examples
- API Reference
- Best Practices
Overview
GraphComponent is a UI Component for displaying interactive graphs and charts using SVG rendering
Key Features
- ✅ Multiple Chart Types: Line, Bar, Pie, Donut, Gauge
- ✅ SVG Rendering: Sharp vector graphics
- ✅ Responsive: Auto-resize with container
- ✅ Interactive: Tooltips, legends, click events
- ✅ Data Loading: From API, table, or direct data
- ✅ Auto-Refresh: Polling and event-based refresh
- ✅ Animation: Smooth transitions
- ✅ Customizable: Colors, fonts, styles
- ✅ Export: Export as PNG/JPEG/SVG images
When to Use GraphComponent
✅ Use GraphComponent when:
- You need to display data as graphs or charts
- You need ease of use (HTML-based)
- You need responsive graphs
- You need auto-refresh data
- You need to export as images
❌ Don't use GraphComponent when:
- You need very complex charts (use libraries like Chart.js, D3.js)
- You need 3D visualization
- You need real-time streaming >100 data points/sec
Installation and Import
GraphComponent is loaded with the Now.js Framework and is ready to use immediately via the window object:
// No import needed - ready to use immediately
console.log(window.GraphComponent); // GraphComponent objectDependencies
GraphComponent requires these dependencies:
- GraphRenderer - For rendering graphs (optional - has internal renderer)
- ApiService or simpleFetch - For loading data from API (optional)
Basic Usage
1. HTML-Based (Recommended)
<div data-component="graph"
data-type="line"
data-url="/api/sales">
</div>2. With Direct Data
<div data-component="graph"
data-type="bar"
data-props='{
"data": [
{
"name": "Sales",
"data": [
{"label": "Jan", "value": 100},
{"label": "Feb", "value": 120},
{"label": "Mar", "value": 150}
]
}
]
}'>
</div>3. From HTML Table
<table id="sales-table">
<thead>
<tr>
<th></th>
<th>Q1</th>
<th>Q2</th>
<th>Q3</th>
<th>Q4</th>
</tr>
</thead>
<tbody>
<tr>
<th>Sales</th>
<td>100</td>
<td>120</td>
<td>150</td>
<td>130</td>
</tr>
</tbody>
</table>
<div data-component="graph"
data-type="line"
data-table="sales-table">
</div>4. JavaScript-Based
const element = document.querySelector('#my-graph');
const instance = await GraphComponent.create(element, {
type: 'line',
data: [
{
name: 'Sales',
data: [
{label: 'Jan', value: 100},
{label: 'Feb', value: 120},
{label: 'Mar', value: 150}
]
}
]
});Chart Types
GraphComponent supports 5 chart types:
1. Line Chart
Display data as line graph, suitable for showing trends over time
<div data-component="graph"
data-type="line"
data-curve="true"
data-fill-area="true"
data-url="/api/sales-trend">
</div>Use Cases:
- Sales over time
- Website traffic
- Temperature
- Stock prices
2. Bar Chart
Display data as bar graph, suitable for comparing values
<div data-component="graph"
data-type="bar"
data-url="/api/product-sales">
</div>Use Cases:
- Product sales comparison
- Users by region
- Rating scores
- Rankings
3. Pie Chart
Display data as circular chart showing percentage proportions
<div data-component="graph"
data-type="pie"
data-show-value-instead-of-percent="true"
data-url="/api/market-share">
</div>Use Cases:
- Market share
- Revenue distribution
- Age distribution
- Category distribution
4. Donut Chart
Display data as ring chart with center space for text
<div data-component="graph"
data-type="donut"
data-donut-thickness="40"
data-center-text="Total: 1000"
data-url="/api/expenses">
</div>Use Cases:
- Budget
- Expenses
- Resource allocation
- Progress indicators
5. Gauge Chart
Display data as gauge meter, suitable for showing single value in range
<div data-component="graph"
data-type="gauge"
data-max-gauge-value="100"
data-gauge-curve-width="30"
data-url="/api/performance-score">
</div>Use Cases:
- Performance score
- Progress (%complete)
- KPI indicators
- Battery level
- Speed meter
HTML Attributes
GraphComponent supports these attributes for configuration:
Basic Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
data-type |
string | 'line' |
Chart type (line, bar, pie, donut, gauge) |
data-url |
string | - | URL for loading data |
data-table |
string | - | HTML table ID |
data-autoload |
boolean | true |
Auto-load data |
data-debug |
boolean | false |
Debug mode |
Appearance Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
data-colors |
array | [...] |
Chart colors (JSON array) |
data-background-color |
string | '#ffffff' |
Background color |
data-show-grid |
boolean | true |
Show grid |
data-grid-color |
string | '#E0E0E0' |
Grid color |
data-axis-color |
string | '#333333' |
Axis color |
data-text-color |
string | '#333333' |
Text color |
data-font-size |
number | 16 |
Font size |
data-font-family |
string | 'Arial, sans-serif' |
Font family |
Chart-Specific Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
data-curve |
boolean | true |
Curved line (line chart) |
data-fill-area |
boolean | false |
Fill area under line (line chart) |
data-fill-opacity |
number | 0.1 |
Area opacity |
data-point-radius |
number | 4 |
Point size (line chart) |
data-line-width |
number | 2 |
Line thickness |
data-border-width |
number | 1 |
Border thickness |
data-donut-thickness |
number | 30 |
Ring thickness (donut) |
data-gauge-curve-width |
number | 30 |
Gauge thickness (gauge) |
data-max-gauge-value |
number | 100 |
Max gauge value |
data-gap |
number | 2 |
Gap between bars (bar chart) |
Display Options
| Attribute | Type | Default | Description |
|---|---|---|---|
data-show-legend |
boolean | true |
Show legend |
data-legend-position |
string | 'bottom' |
Legend position (top, bottom, left, right) |
data-show-tooltip |
boolean | true |
Show tooltip |
data-show-data-labels |
boolean | true |
Show data labels |
data-show-axis |
boolean | true |
Show axis |
data-show-axis-labels |
boolean | true |
Show axis labels |
data-show-center-text |
boolean | true |
Show center text (donut/gauge) |
data-center-text |
string | - | Center text |
data-show-value-instead-of-percent |
boolean | true |
Show value instead of percent |
Animation & Behavior
| Attribute | Type | Default | Description |
|---|---|---|---|
data-animation |
boolean | false |
Enable animation |
data-animation-duration |
number | 1000 |
Animation duration (ms) |
data-max-data-points |
number | 20 |
Max data points |
Refresh & Polling
| Attribute | Type | Default | Description |
|---|---|---|---|
data-polling-interval |
number | 0 |
Polling interval (ms), 0 = off |
data-refresh-event |
string | - | Event name for refresh (comma-separated) |
Props Attribute
You can use data-props to set all configuration in JSON format:
<div data-component="graph"
data-props='{
"type": "line",
"url": "/api/sales",
"colors": ["#FF6B6B", "#4ECDC4"],
"showGrid": true,
"animation": true
}'>
</div>Configuration Options
When creating an instance with JavaScript, you can configure all options:
const instance = await GraphComponent.create(element, {
// Basic
type: 'line',
autoload: true,
debug: false,
// Data Sources
url: '/api/sales',
table: 'sales-table',
data: null,
// Appearance
colors: ['#FF6B6B', '#4ECDC4', '#45B7D1'],
backgroundColor: '#ffffff',
showGrid: true,
gridColor: '#E0E0E0',
axisColor: '#333333',
textColor: '#333333',
fontSize: 16,
fontFamily: 'Arial, sans-serif',
// Chart Options
curve: true,
fillArea: false,
fillOpacity: 0.1,
pointRadius: 4,
lineWidth: 2,
borderWidth: 1,
borderColor: 'auto',
donutThickness: 30,
gaugeCurveWidth: 30,
maxGaugeValue: 100,
gap: 2,
// Display
showLegend: true,
legendPosition: 'bottom',
showTooltip: true,
tooltipFormatter: null,
showDataLabels: true,
showAxis: true,
showAxisLabels: true,
showCenterText: true,
centerText: null,
showValueInsteadOfPercent: true,
// Animation
animation: false,
animationDuration: 1000,
// Behavior
maxDataPoints: 20,
pollingInterval: 0,
refreshEvent: null,
// Event Handlers
onClick: (data) => {},
onLoad: (data) => {},
onRender: () => {},
onDataChange: (data) => {}
});Data Format
GraphComponent supports multiple data formats:
Format 1: Array of Series (Recommended)
[
{
name: 'Series 1',
data: [
{label: 'Q1', value: 100},
{label: 'Q2', value: 120},
{label: 'Q3', value: 150}
]
},
{
name: 'Series 2',
data: [
{label: 'Q1', value: 80},
{label: 'Q2', value: 90},
{label: 'Q3', value: 110}
]
}
]Format 2: Simple Array (Single Series)
[
{label: 'Category A', value: 100},
{label: 'Category B', value: 120},
{label: 'Category C', value: 80}
]Format 3: API Response
{
"data": [
{
"name": "Sales",
"data": [
{"label": "Jan", "value": 100},
{"label": "Feb", "value": 120}
]
}
]
}Format 4: From HTML Table
HTML table will be automatically converted to data format:
<table id="data-table">
<thead>
<tr>
<th></th>
<th>Q1</th>
<th>Q2</th>
</tr>
</thead>
<tbody>
<tr>
<th>Sales</th>
<td>100</td>
<td>120</td>
</tr>
<tr>
<th>Revenue</th>
<td>200</td>
<td>240</td>
</tr>
</tbody>
</table>Converts to:
[
{
name: 'Sales',
data: [
{label: 'Q1', value: 100},
{label: 'Q2', value: 120}
]
},
{
name: 'Revenue',
data: [
{label: 'Q1', value: 200},
{label: 'Q2', value: 240}
]
}
]Styling and Customization
Color Palette
<div data-component="graph"
data-type="bar"
data-colors='["#FF6B6B", "#4ECDC4", "#45B7D1", "#FFA07A"]'
data-url="/api/sales">
</div>Custom Colors for Each Series
const data = [
{
name: 'Sales',
color: '#FF6B6B',
data: [...]
},
{
name: 'Revenue',
color: '#4ECDC4',
data: [...]
}
];Font Customization
<div data-component="graph"
data-font-family="'Segoe UI', Tahoma, sans-serif"
data-font-size="14"
data-text-color="#555555"
data-url="/api/data">
</div>Grid Customization
<div data-component="graph"
data-show-grid="true"
data-grid-color="#F0F0F0"
data-axis-color="#666666"
data-url="/api/data">
</div>Custom Tooltip
const instance = await GraphComponent.create(element, {
type: 'line',
data: [...],
tooltipFormatter: (label, value, seriesName) => {
return `<strong>${seriesName}</strong><br>${label}: ${value.toFixed(2)}`;
}
});Events
GraphComponent emits events on changes
Event Types
| Event | When | Detail |
|---|---|---|
graph:created |
Graph created | {instance} |
graph:loading |
Data loading | - |
graph:loaded |
Data loaded | {data} |
graph:error |
Error occurred | {error} |
graph:data-changed |
Data changed | {data} |
graph:data-point-added |
Data point added | {point, seriesIndex} |
graph:type-changed |
Chart type changed | {type} |
graph:polling-started |
Polling started | {interval} |
graph:polling-stopped |
Polling stopped | - |
graph:destroyed |
Graph destroyed | - |
Listen to Events
const element = document.querySelector('#my-graph');
element.addEventListener('graph:loaded', (e) => {
console.log('Data loaded:', e.detail.data);
});
element.addEventListener('graph:error', (e) => {
console.error('Error:', e.detail.error);
});
element.addEventListener('graph:data-changed', (e) => {
console.log('Data changed:', e.detail.data);
});Event Handlers in Configuration
const instance = await GraphComponent.create(element, {
type: 'line',
url: '/api/sales',
onClick: function(dataPoint, seriesIndex) {
console.log('Clicked:', dataPoint, seriesIndex);
},
onLoad: function(data) {
console.log('Data loaded:', data);
},
onRender: function() {
console.log('Graph rendered');
},
onDataChange: function(data) {
console.log('Data changed:', data);
}
});JavaScript API
GraphComponent has methods for control via JavaScript
Create Instance
const instance = await GraphComponent.create(element, options);Get Instance
// From element
const instance = GraphComponent.getInstance(element);
// From ID
const instance = GraphComponent.getInstance('#my-graph');
// From element property
const instance = element.graphInstance;Set Data
instance.setData([
{
name: 'Sales',
data: [
{label: 'Jan', value: 100},
{label: 'Feb', value: 120}
]
}
]);Load Data from URL
await instance.loadData('/api/sales');Add Data Point
// Add to first series
instance.addDataPoint({label: 'Mar', value: 150}, 0);
// Add to second series
instance.addDataPoint({label: 'Mar', value: 130}, 1);Change Chart Type
instance.setType('bar'); // Change to bar chart
instance.setType('pie'); // Change to pie chartRefresh Data
instance.refresh(); // Reload data from URLExport to Image
// Export as PNG
instance.exportToImage('sales-chart', 'png');
// Export as JPEG with custom size
instance.exportToImage('sales-chart', 'jpeg', 1920, 1080, 0.9);
// Export as SVG
instance.exportToImage('sales-chart', 'svg');Polling Control
// Start polling (if configured)
GraphComponent.startPolling(instance);
// Stop polling
GraphComponent.stopPolling(instance);Destroy Instance
instance.destroy();
// or
GraphComponent.destroy(instance);Usage Examples
1. Line Chart - Sales Trend
<div style="width: 800px; height: 400px;">
<div data-component="graph"
data-type="line"
data-curve="true"
data-fill-area="true"
data-fill-opacity="0.2"
data-url="/api/sales/monthly"
data-animation="true">
</div>
</div>2. Bar Chart - Product Comparison
<div style="width: 600px; height: 400px;">
<div data-component="graph"
data-type="bar"
data-props='{
"data": [
{
"name": "Q1",
"data": [
{"label": "Product A", "value": 100},
{"label": "Product B", "value": 120},
{"label": "Product C", "value": 80}
]
},
{
"name": "Q2",
"data": [
{"label": "Product A", "value": 110},
{"label": "Product B", "value": 130},
{"label": "Product C", "value": 90}
]
}
]
}'>
</div>
</div>3. Pie Chart - Market Share
<div style="width: 500px; height: 400px;">
<div data-component="graph"
data-type="pie"
data-show-value-instead-of-percent="false"
data-props='{
"data": [
{"label": "Chrome", "value": 65},
{"label": "Safari", "value": 18},
{"label": "Firefox", "value": 10},
{"label": "Edge", "value": 5},
{"label": "Others", "value": 2}
]
}'>
</div>
</div>4. Donut Chart - Budget Distribution
<div style="width: 500px; height: 400px;">
<div data-component="graph"
data-type="donut"
data-donut-thickness="50"
data-center-text="Total: $10,000"
data-props='{
"data": [
{"label": "Marketing", "value": 4000},
{"label": "Development", "value": 3000},
{"label": "Operations", "value": 2000},
{"label": "Other", "value": 1000}
]
}'>
</div>
</div>5. Gauge Chart - Performance Score
<div style="width: 400px; height: 300px;">
<div data-component="graph"
data-type="gauge"
data-max-gauge-value="100"
data-gauge-curve-width="40"
data-center-text="85/100"
data-props='{
"data": [{"label": "Score", "value": 85}]
}'>
</div>
</div>6. Real-time Graph with Polling
<div style="width: 800px; height: 400px;">
<div id="realtime-graph"
data-component="graph"
data-type="line"
data-url="/api/server-stats"
data-polling-interval="5000"
data-max-data-points="20">
</div>
</div>
<script>
// Stop polling after 1 minute
setTimeout(() => {
const instance = GraphComponent.getInstance('#realtime-graph');
GraphComponent.stopPolling(instance);
}, 60000);
</script>7. Dynamic Data Update
<div id="dynamic-graph"
data-component="graph"
data-type="bar"
data-autoload="false"
style="width: 600px; height: 400px;">
</div>
<button onclick="updateGraph()">Update Data</button>
<script>
async function updateGraph() {
const instance = GraphComponent.getInstance('#dynamic-graph');
const newData = [
{
name: 'Sales',
data: [
{label: 'Mon', value: Math.random() * 100},
{label: 'Tue', value: Math.random() * 100},
{label: 'Wed', value: Math.random() * 100}
]
}
];
instance.setData(newData);
}
// Initialize
GraphComponent.getInstance('#dynamic-graph');
</script>8. From HTML Table
<table id="sales-data" style="display: none;">
<thead>
<tr>
<th></th>
<th>Jan</th>
<th>Feb</th>
<th>Mar</th>
<th>Apr</th>
</tr>
</thead>
<tbody>
<tr>
<th>Product A</th>
<td>100</td>
<td>120</td>
<td>150</td>
<td>140</td>
</tr>
<tr>
<th>Product B</th>
<td>80</td>
<td>90</td>
<td>110</td>
<td>100</td>
</tr>
</tbody>
</table>
<div data-component="graph"
data-type="line"
data-table="sales-data"
style="width: 800px; height: 400px;">
</div>9. Event-Driven Refresh
<div id="orders-graph"
data-component="graph"
data-type="bar"
data-url="/api/orders/daily"
data-refresh-event="order:created"
style="width: 600px; height: 400px;">
</div>
<script>
// Somewhere in your app when order is created
async function createOrder(orderData) {
await fetch('/api/orders', {
method: 'POST',
body: JSON.stringify(orderData),
headers: {'Content-Type': 'application/json'}
});
// Trigger graph refresh
EventManager.emit('order:created');
}
</script>10. Export Graph
<div id="export-graph"
data-component="graph"
data-type="line"
data-url="/api/analytics"
style="width: 800px; height: 400px;">
</div>
<button onclick="exportGraph()">Export as PNG</button>
<button onclick="exportGraphJPEG()">Export as JPEG</button>
<button onclick="exportGraphSVG()">Export as SVG</button>
<script>
function exportGraph() {
const instance = GraphComponent.getInstance('#export-graph');
instance.exportToImage('analytics-chart', 'png');
}
function exportGraphJPEG() {
const instance = GraphComponent.getInstance('#export-graph');
instance.exportToImage('analytics-chart', 'jpeg', 1920, 1080, 0.95);
}
function exportGraphSVG() {
const instance = GraphComponent.getInstance('#export-graph');
instance.exportToImage('analytics-chart', 'svg');
}
</script>API Reference
Methods
// Create & Initialize
create(element: HTMLElement|string, options?: object): Promise<Instance>
init(options?: object): Promise<GraphComponent>
// Get Instance
getInstance(element: HTMLElement|string): Instance|null
// Data Operations
setData(instance: Instance, data: Array): void
loadData(instance: Instance, url?: string): Promise<any>
addDataPoint(instance: Instance, point: object, seriesIndex?: number): void
refresh(instance: Instance): void
// Type & Display
setType(instance: Instance, type: string): void
exportToImage(instance: Instance, filename?: string, format?: string, width?: number, height?: number, quality?: number, scale?: number): void
// Polling
startPolling(instance: Instance): void
stopPolling(instance: Instance): void
// Lifecycle
destroy(instance: Instance|string|HTMLElement): boolean
destroyAll(): voidInstance Properties
{
id: string,
element: HTMLElement,
options: object,
data: array|null,
state: {
loading: boolean,
error: string|null,
rendered: boolean,
width: number,
height: number
},
renderer: object|null,
timer: number|null
}Instance Methods
instance.setData(data: Array): void
instance.loadData(url?: string): Promise<any>
instance.addDataPoint(point: object, seriesIndex?: number): void
instance.setType(type: string): void
instance.refresh(): void
instance.exportToImage(filename?: string, format?: string, ...): void
instance.destroy(): voidBest Practices
1. ✅ Set Container Size
<!-- ❌ Bad: No size specified -->
<div data-component="graph" data-url="/api/data"></div>
<!-- ✅ Good: Explicit size -->
<div data-component="graph"
data-url="/api/data"
style="width: 800px; height: 400px;">
</div>2. ✅ Choose Appropriate Chart Type
// Line Chart - for trends over time
{type: 'line', data: timeSeriesData}
// Bar Chart - for comparison
{type: 'bar', data: comparisonData}
// Pie/Donut - for proportions
{type: 'pie', data: proportionData}
// Gauge - for single value
{type: 'gauge', data: singleValueData}3. ✅ Limit Data Points for Performance
<!-- ✅ Good: Limit data points -->
<div data-component="graph"
data-url="/api/realtime"
data-max-data-points="50"
data-polling-interval="5000">
</div>4. ✅ Use Appropriate Polling Interval
<!-- ❌ Bad: Polling every 1 second -->
<div data-polling-interval="1000"></div>
<!-- ✅ Good: Polling every 30 seconds -->
<div data-polling-interval="30000"></div>5. ✅ Handle Loading States
element.addEventListener('graph:loading', () => {
showLoadingSpinner();
});
element.addEventListener('graph:loaded', () => {
hideLoadingSpinner();
});
element.addEventListener('graph:error', (e) => {
showError(e.detail.error);
});6. ✅ Cleanup When Removing
// ✅ Good: Destroy instance when no longer needed
const instance = GraphComponent.getInstance('#my-graph');
GraphComponent.destroy(instance);7. ✅ Use Responsive Design
/* ✅ Good: Use responsive container */
.graph-container {
width: 100%;
max-width: 800px;
height: 400px;
}8. ✅ Provide Meaningful Labels
// ✅ Good: Clear labels
const data = [
{
name: 'Monthly Revenue',
data: [
{label: 'January 2024', value: 100000},
{label: 'February 2024', value: 120000}
]
}
];9. ✅ Use Color Schemes Consistently
// ✅ Good: Use consistent color scheme
const colors = [
'#2196F3', // Primary
'#4CAF50', // Success
'#FFC107', // Warning
'#F44336' // Danger
];10. ✅ Test with Different Data Sizes
// ✅ Good: Test with various data sizes
// - Empty data
// - Single data point
// - Normal dataset (10-50 points)
// - Large dataset (100+ points)Summary
When to Use GraphComponent
| Use Case | Use GraphComponent? |
|---|---|
| Display trend graphs (Line Chart) | ✅ Yes |
| Display comparisons (Bar Chart) | ✅ Yes |
| Display proportions (Pie/Donut) | ✅ Yes |
| Display gauges (Gauge) | ✅ Yes |
| Real-time data | ✅ Can use - use polling |
| Very complex charts | ❌ No - use Chart.js/D3.js |
| 3D visualization | ❌ Not supported |
| Large datasets (1000+ points) | ❌ Not recommended - performance issues |
Key Features
| Feature | Available | Note |
|---|---|---|
| Line Chart | ✅ | With curve & fill options |
| Bar Chart | ✅ | Vertical bars |
| Pie Chart | ✅ | With legend |
| Donut Chart | ✅ | With center text |
| Gauge Chart | ✅ | Single value indicator |
| Responsive | ✅ | Auto-resize |
| Tooltips | ✅ | Interactive |
| Legends | ✅ | Configurable position |
| Animation | ✅ | Optional |
| Data Loading | ✅ | API, table, direct |
| Polling | ✅ | Auto-refresh |
| Export | ✅ | PNG, JPEG, SVG |