<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GGraphs Usage Example</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Kanit:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">
<style>
body {
font-family: Kanit, Arial, sans-serif;
margin: 0;
padding: 20px;
background-color: #f0f0f0;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
.graph-container {
background-color: white;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
margin-bottom: 20px;
padding: 20px;
}
.graph-header {
font-size: 18px;
font-weight: bold;
margin-bottom: 10px;
}
.graph {
height: 300px;
width: 100%;
position: relative;
background-color: rgba(255, 255, 255, 1);
}
.controls {
margin-top: 10px;
}
button {
background-color: #4CAF50;
border: none;
color: white;
padding: 10px 20px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
border-radius: 4px;
}
/* Customize buttons for start and stop */
.start-button {
background-color: #008CBA;
}
.stop-button {
background-color: #f44336;
}
/* Hide data table from display */
table {
display: none;
}
</style>
</head>
<body>
<div class="container">
<h1>GGraphs Usage Example</h1>
<!-- Multi-series Line Graph -->
<div class="graph-container">
<div class="graph-header">Multi-series Line Graph</div>
<div id="lineGraph" class="graph"></div>
<div class="controls">
<select onchange="graphControls.changeDataSet('lineGraph')">
<option value="mixed">Mixed Data (Positive and Negative)</option>
<option value="positive">All Positive Data</option>
<option value="negative">All Negative Data</option>
<option value="decimal">Decimal Data</option>
</select>
<button onclick="graphControls.toggleCurve('lineGraph')">Toggle Curve/Straight</button>
<!-- Buttons for starting and stopping real-time updates -->
<button id="realtimeStartButton" class="start-button" onclick="graphControls.startRealtimeUpdate('lineGraph')">Start Real-time Update</button>
<button id="realtimeStopButton" class="stop-button" onclick="graphControls.stopRealtimeUpdate('lineGraph')" style="display: none;">Stop Real-time Update</button>
</div>
</div>
<!-- Multi-type Bar Graph -->
<div class="graph-container">
<div class="graph-header">Multi-type Bar Graph</div>
<div id="barGraph" class="graph"></div>
<div class="controls">
<button onclick="graphControls.animateGraph('barGraph')">Show Animation</button>
<select onchange="graphControls.changeDataSet('barGraph')">
<option value="mixed">Mixed Data (Positive and Negative)</option>
<option value="positive">All Positive Data</option>
<option value="negative">All Negative Data</option>
<option value="decimal">Decimal Data</option>
</select>
</div>
</div>
<!-- Pie Chart -->
<div class="graph-container">
<div class="graph-header">Pie Chart</div>
<div id="pieChart" class="graph"></div>
<div class="controls">
<button onclick="graphControls.animateGraph('pieChart')">Show Animation</button>
</div>
</div>
<!-- Donut Chart -->
<div class="graph-container">
<div class="graph-header">Donut Chart</div>
<div id="donutChart" class="graph"></div>
<div class="controls">
<button onclick="graphControls.animateGraph('donutChart')">Show Animation</button>
</div>
</div>
<!-- Gauge Chart -->
<div class="graph-container">
<div class="graph-header">Gauge Chart</div>
<div id="gaugeChart" class="graph"></div>
<div class="controls">
<button onclick="graphControls.animateGraph('gaugeChart')">Show Animation</button>
</div>
</div>
<!-- New graph loading data from HTML table -->
<div class="graph-container">
<div class="graph-header">Line Graph from HTML Table</div>
<div id="tableLineGraph" class="graph"></div>
<div class="controls">
<button onclick="graphControls.renderGraphFromTable('tableLineGraph')">Load Data from Table</button>
</div>
</div>
</div>
<!-- Data table for Line Graph from HTML Table -->
<table id="tableLineGraphData">
<thead>
<tr>
<th>Day</th>
<th>Sales</th>
</tr>
</thead>
<tbody>
<tr>
<th>1</th>
<td data-value="10" data-tooltip="Day 1: 10">10</td>
</tr>
<tr>
<th>2</th>
<td data-value="15" data-tooltip="Day 2: 15">15</td>
</tr>
<tr>
<th>3</th>
<td data-value="20" data-tooltip="Day 3: 20">20</td>
</tr>
<tr>
<th>4</th>
<td data-value="25" data-tooltip="Day 4: 25">25</td>
</tr>
<tr>
<th>5</th>
<td data-value="30" data-tooltip="Day 5: 30">30</td>
</tr>
<!-- Add rows as needed -->
</tbody>
</table>
<script src="./ggraphs.js"></script>
<script>
const commonOptions = {
showDataLabels: true,
animation: true,
showLegend: true,
showAxisLabels: true,
fillArea: true
};
const barData = {
mixed: [
{
name: "Product A",
data: [
{label: "Q1", value: -5},
{label: "Q2", value: 15},
{label: "Q3", value: 25},
{label: "Q4", value: -10}
]
},
{
name: "Product B",
data: [
{label: "Q1", value: 10},
{label: "Q2", value: 8},
{label: "Q3", value: 19.6},
{label: "Q4", value: 22}
]
}
],
positive: [
{
name: "Product A",
data: [
{label: "Q1", value: 1200},
{label: "Q2", value: 2600},
{label: "Q3", value: 3300},
{label: "Q4", value: 1900}
]
},
{
name: "Product B",
data: [
{label: "Q1", value: 1000},
{label: "Q2", value: 1200},
{label: "Q3", value: 2600},
{label: "Q4", value: 3500}
]
}
],
negative: [
{
name: "Product A",
data: [
{label: "Q1", value: -1200},
{label: "Q2", value: -2600},
{label: "Q3", value: -3300},
{label: "Q4", value: -1900}
]
},
{
name: "Product B",
data: [
{label: "Q1", value: -1000},
{label: "Q2", value: -1200},
{label: "Q3", value: -2600},
{label: "Q4", value: -3500}
]
}
],
decimal: [
{
name: "Product A",
data: [
{label: "Q1", value: 0.5},
{label: "Q2", value: 0.2},
{label: "Q3", value: 0.8},
{label: "Q4", value: 0.4}
]
},
{
name: "Product B",
data: [
{label: "Q1", value: 0.3},
{label: "Q2", value: 0.7},
{label: "Q3", value: 0.6},
{label: "Q4", value: 0.2}
]
}
]
};
const pieData = [
{
name: "Market Share",
data: [
{label: "Product A", value: 30},
{label: "Product B", value: 25},
{label: "Product C", value: 20},
{label: "Product D", value: 15},
{label: "Product E", value: 15},
{label: "Product F", value: 15},
{label: "Others", value: 10}
]
}
];
const gaugeData = [
{
name: "Progress",
data: [{label: "Completion", value: 75}]
}
];
// Object to store graph instances
const graphs = {};
// Object for graph control functions
const graphControls = {
animateGraph: function(graphId) {
if (graphs[graphId]) {
graphs[graphId].renderGraph();
} else {
console.error(`Graph ${graphId} not found`);
}
},
toggleCurve: function(graphId) {
if (graphId === 'lineGraph' && graphs[graphId]) {
const graph = graphs[graphId];
graph.options.curveType = graph.options.curveType === 'linear' ? 'curve' : 'linear';
graph.renderGraph();
} else {
console.error(`Graph ${graphId} not found or is not a line graph`);
}
},
// Function to start real-time updates
startRealtimeUpdate: function(graphId, interval = 2000) { // Update every 2 seconds
if (!graphs[graphId]) {
console.error(`Graph ${graphId} not found`);
return;
}
if (graphs[graphId].realtimeInterval) {
console.warn(`Realtime update for ${graphId} is already running.`);
return;
}
graphs[graphId].realtimeInterval = setInterval(() => {
const now = new Date();
const label = now.toLocaleTimeString();
const newDataPoints = [
{seriesIndex: 0, data: {label: label, value: Math.floor(Math.random() * 100)}},
{seriesIndex: 1, data: {label: label, value: Math.floor(Math.random() * 100)}}
];
graphs[graphId].addDataPoints(newDataPoints);
}, interval);
// Change button states
document.getElementById('realtimeStartButton').style.display = 'none';
document.getElementById('realtimeStopButton').style.display = 'inline-block';
},
// Function to stop real-time updates
stopRealtimeUpdate: function(graphId) {
if (!graphs[graphId]) {
console.error(`Graph ${graphId} not found`);
return;
}
if (graphs[graphId].realtimeInterval) {
clearInterval(graphs[graphId].realtimeInterval);
graphs[graphId].realtimeInterval = null;
// Change button states
document.getElementById('realtimeStartButton').style.display = 'inline-block';
document.getElementById('realtimeStopButton').style.display = 'none';
} else {
console.warn(`Realtime update for ${graphId} is not running.`);
}
},
changeDataSet: function(graphId) {
const select = document.querySelector(`#${graphId} + .controls select`);
if (graphs[graphId]) {
graphs[graphId].setData(barData[select.value]);
} else {
console.error(`Graph ${graphId} not found`);
}
},
// Function to load graph from HTML table
renderGraphFromTable: function(graphId) {
if (graphs[graphId]) {
graphs[graphId].options.table = 'tableLineGraphData';
graphs[graphId].initialize(); // Call initialize method to reload data from table
} else {
console.error(`Graph ${graphId} not found`);
}
}
};
// Function to create and set up graphs
function initializeGraphs() {
// Create line graph
graphs.lineGraph = new GGraphs('lineGraph', {
...commonOptions,
type: 'line',
data: barData.mixed,
curveType: 'curve',
centerText: 'Sales'
});
// Create bar graph
graphs.barGraph = new GGraphs('barGraph', {
...commonOptions,
type: 'bar',
data: barData.mixed,
centerText: 'Sales'
});
// Create pie chart
graphs.pieChart = new GGraphs('pieChart', {
...commonOptions,
type: 'pie',
data: pieData,
centerText: 'Market Share'
});
// Create donut chart
graphs.donutChart = new GGraphs('donutChart', {
...commonOptions,
type: 'donut',
data: pieData,
centerText: 'Total'
});
// Create gauge chart
graphs.gaugeChart = new GGraphs('gaugeChart', {
...commonOptions,
type: 'gauge',
data: gaugeData,
centerText: '75%'
});
// Create new graph loading from HTML table
graphs.tableLineGraph = new GGraphs('tableLineGraph', {
...commonOptions,
type: 'line',
table: 'tableLineGraphData', // Specify ID of the table to load data from
curveType: 'linear',
centerText: 'Sales from Table'
});
// Show initial animations
Object.keys(graphs).forEach(graphId => {
graphs[graphId].renderGraph();
});
// Handle window resizing
window.addEventListener('resize', function() {
Object.values(graphs).forEach(graph => graph.handleResize());
});
}
// Wait for DOM to load before initializing graphs
document.addEventListener('DOMContentLoaded', initializeGraphs);
</script>
</body>
</html>