Now.js Framework Documentation

Now.js Framework Documentation

GraphComponent - Data Visualization

EN 31 Oct 2025 01:21

GraphComponent - Data Visualization

Documentation for GraphComponent, a UI Component for displaying graphs and charts

📋 Table of Contents

  1. Overview
  2. Installation and Import
  3. Basic Usage
  4. Chart Types
  5. HTML Attributes
  6. Configuration Options
  7. Data Format
  8. Styling and Customization
  9. Events
  10. JavaScript API
  11. Usage Examples
  12. API Reference
  13. 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 object

Dependencies

GraphComponent requires these dependencies:

  • GraphRenderer - For rendering graphs (optional - has internal renderer)
  • ApiService or simpleFetch - For loading data from API (optional)

Basic Usage

<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:

[
  {
    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 chart

Refresh Data

instance.refresh(); // Reload data from URL

Export 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(): void

Instance 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(): void

Best 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