// 📈 Real-time Data Chart Demo - TimerBox + WebCanvasBox + RandomBox // Dynamic chart visualization with multiple chart types and data streaming print("📈 === Real-time Data Chart Demo Starting ===") // Initialize components local canvas, timer, random canvas = new WebCanvasBox("demo-canvas", 800, 500) timer = new TimerBox() random = new RandomBox() // Chart configuration local chartConfig chartConfig = { type: "line", // line, bar, area, scatter title: "Nyash Performance Metrics", width: 700, height: 350, marginLeft: 80, marginTop: 50, marginRight: 50, marginBottom: 80, maxDataPoints: 50, updateInterval: 100, // milliseconds colors: ["#3498db", "#e74c3c", "#2ecc71", "#f39c12", "#9b59b6"] } // Data series local dataSeries dataSeries = [ {name: "Memory Usage", data: [], color: "#3498db", unit: "MB"}, {name: "CPU Usage", data: [], color: "#e74c3c", unit: "%"}, {name: "Network I/O", data: [], color: "#2ecc71", unit: "KB/s"}, {name: "Disk Usage", data: [], color: "#f39c12", unit: "GB"} ] // Chart drawing functions local drawAxes drawAxes = function() { local plotX, plotY, plotWidth, plotHeight plotX = chartConfig.marginLeft plotY = chartConfig.marginTop plotWidth = chartConfig.width - chartConfig.marginLeft - chartConfig.marginRight plotHeight = chartConfig.height - chartConfig.marginTop - chartConfig.marginBottom // Draw axes canvas.setStrokeStyle("#34495e") canvas.setLineWidth(2) // Y axis canvas.drawLine(plotX, plotY, plotX, plotY + plotHeight, "#34495e", 2) // X axis canvas.drawLine(plotX, plotY + plotHeight, plotX + plotWidth, plotY + plotHeight, "#34495e", 2) // Grid lines canvas.setStrokeStyle("#ecf0f1") canvas.setLineWidth(1) local i, x, y // Vertical grid lines i = 1 loop(i < 10) { x = plotX + (plotWidth / 10) * i canvas.drawLine(x, plotY, x, plotY + plotHeight, "#ecf0f1", 1) i = i + 1 } // Horizontal grid lines i = 1 loop(i < 8) { y = plotY + (plotHeight / 8) * i canvas.drawLine(plotX, y, plotX + plotWidth, y, "#ecf0f1", 1) i = i + 1 } } local drawLabels drawLabels = function() { local plotX, plotY, plotWidth, plotHeight plotX = chartConfig.marginLeft plotY = chartConfig.marginTop plotWidth = chartConfig.width - chartConfig.marginLeft - chartConfig.marginRight plotHeight = chartConfig.height - chartConfig.marginTop - chartConfig.marginBottom // Y axis labels canvas.setFillStyle("#2c3e50") local i, value, y i = 0 loop(i <= 8) { value = 100 - (i * 12.5) // 0-100 scale y = plotY + (plotHeight / 8) * i canvas.fillText(value.toString(), plotX - 30, y + 5, "12px Arial", "#2c3e50") i = i + 1 } // X axis labels (time) i = 0 loop(i <= 10) { local timeLabel, x timeLabel = "-" + (10 - i) + "s" x = plotX + (plotWidth / 10) * i canvas.fillText(timeLabel, x - 10, plotY + plotHeight + 20, "12px Arial", "#2c3e50") i = i + 1 } // Axis titles canvas.fillText("Time", plotX + plotWidth / 2 - 20, plotY + plotHeight + 50, "14px Arial", "#2c3e50") // Y axis title (rotated) canvas.fillText("Value", 20, plotY + plotHeight / 2, "14px Arial", "#2c3e50") } local drawLineChart drawLineChart = function() { local plotX, plotY, plotWidth, plotHeight plotX = chartConfig.marginLeft plotY = chartConfig.marginTop plotWidth = chartConfig.width - chartConfig.marginLeft - chartConfig.marginRight plotHeight = chartConfig.height - chartConfig.marginTop - chartConfig.marginBottom local i, series i = 0 loop(i < dataSeries.length()) { series = dataSeries[i] if (series.data.length() > 1) { canvas.setStrokeStyle(series.color) canvas.setLineWidth(3) canvas.beginPath() local j, x, y, value j = 0 loop(j < series.data.length()) { value = series.data[j] x = plotX + (j / (chartConfig.maxDataPoints - 1)) * plotWidth y = plotY + plotHeight - (value / 100) * plotHeight if (j == 0) { canvas.moveTo(x, y) } else { canvas.lineTo(x, y) } j = j + 1 } canvas.stroke(series.color, 3) // Draw data points j = 0 loop(j < series.data.length()) { value = series.data[j] x = plotX + (j / (chartConfig.maxDataPoints - 1)) * plotWidth y = plotY + plotHeight - (value / 100) * plotHeight canvas.setFillStyle(series.color) canvas.fillCircle(x, y, 4) j = j + 1 } } i = i + 1 } } local drawBarChart drawBarChart = function() { local plotX, plotY, plotWidth, plotHeight plotX = chartConfig.marginLeft plotY = chartConfig.marginTop plotWidth = chartConfig.width - chartConfig.marginLeft - chartConfig.marginRight plotHeight = chartConfig.height - chartConfig.marginTop - chartConfig.marginBottom if (dataSeries[0].data.length() > 0) { local barWidth, spacing, i, series, value, x, y, height barWidth = (plotWidth / chartConfig.maxDataPoints) * 0.8 spacing = (plotWidth / chartConfig.maxDataPoints) * 0.2 local dataIndex dataIndex = dataSeries[0].data.length() - 1 i = 0 loop(i < dataSeries.length()) { series = dataSeries[i] if (dataIndex < series.data.length()) { value = series.data[dataIndex] x = plotX + plotWidth - barWidth * (i + 1) - spacing * i height = (value / 100) * plotHeight y = plotY + plotHeight - height canvas.setFillStyle(series.color) canvas.fillRect(x, y, barWidth * 0.8, height) // Value label canvas.setFillStyle("#2c3e50") canvas.fillText(value.toString(), x + 5, y - 10, "10px Arial", "#2c3e50") } i = i + 1 } } } local drawAreaChart drawAreaChart = function() { local plotX, plotY, plotWidth, plotHeight plotX = chartConfig.marginLeft plotY = chartConfig.marginTop plotWidth = chartConfig.width - chartConfig.marginLeft - chartConfig.marginRight plotHeight = chartConfig.height - chartConfig.marginTop - chartConfig.marginBottom local i, series i = 0 loop(i < dataSeries.length()) { series = dataSeries[i] if (series.data.length() > 1) { // Create area fill canvas.beginPath() local j, x, y, value j = 0 loop(j < series.data.length()) { value = series.data[j] x = plotX + (j / (chartConfig.maxDataPoints - 1)) * plotWidth y = plotY + plotHeight - (value / 100) * plotHeight if (j == 0) { canvas.moveTo(x, plotY + plotHeight) canvas.lineTo(x, y) } else { canvas.lineTo(x, y) } j = j + 1 } // Close the area canvas.lineTo(plotX + plotWidth, plotY + plotHeight) canvas.lineTo(plotX, plotY + plotHeight) canvas.closePath() // Fill with semi-transparent color local fillColor fillColor = series.color.replace(")", ", 0.3)") if (series.color.startsWith("#")) { // Convert hex to rgba fillColor = series.color + "80" // Add alpha } canvas.fill(fillColor) // Draw border line canvas.setStrokeStyle(series.color) canvas.setLineWidth(2) canvas.beginPath() j = 0 loop(j < series.data.length()) { value = series.data[j] x = plotX + (j / (chartConfig.maxDataPoints - 1)) * plotWidth y = plotY + plotHeight - (value / 100) * plotHeight if (j == 0) { canvas.moveTo(x, y) } else { canvas.lineTo(x, y) } j = j + 1 } canvas.stroke(series.color, 2) } i = i + 1 } } // Legend drawing local drawLegend drawLegend = function() { local legendX, legendY, i, series legendX = chartConfig.width - chartConfig.marginRight - 150 legendY = chartConfig.marginTop + 20 // Legend background canvas.setFillStyle("#f8f9fa") canvas.fillRect(legendX - 10, legendY - 10, 160, dataSeries.length() * 25 + 20) canvas.setStrokeStyle("#dee2e6") canvas.strokeRect(legendX - 10, legendY - 10, 160, dataSeries.length() * 25 + 20) canvas.setFillStyle("#2c3e50") canvas.fillText("Legend", legendX, legendY, "14px Arial", "#2c3e50") i = 0 loop(i < dataSeries.length()) { series = dataSeries[i] // Color box canvas.setFillStyle(series.color) canvas.fillRect(legendX, legendY + 15 + i * 25, 15, 15) // Series name and latest value canvas.setFillStyle("#2c3e50") local latestValue, valueText if (series.data.length() > 0) { latestValue = series.data[series.data.length() - 1] valueText = series.name + ": " + latestValue + series.unit } else { valueText = series.name + ": --" } canvas.fillText(valueText, legendX + 20, legendY + 27 + i * 25, "12px Arial", "#2c3e50") i = i + 1 } } // Data generation local generateDataPoint generateDataPoint = function(seriesIndex) { local baseValue, variation, value if (seriesIndex == 0) { // Memory Usage baseValue = 45 variation = random.randInt(-5, 15) } else if (seriesIndex == 1) { // CPU Usage baseValue = 35 variation = random.randInt(-10, 25) } else if (seriesIndex == 2) { // Network I/O baseValue = 25 variation = random.randInt(-15, 30) } else { // Disk Usage baseValue = 60 variation = random.randInt(-3, 8) } value = baseValue + variation return Math.max(0, Math.min(100, value)) } // Update data local updateData updateData = function() { local i, series, newValue i = 0 loop(i < dataSeries.length()) { series = dataSeries[i] newValue = generateDataPoint(i) // Add new data point series.data.push(newValue) // Remove old data points if exceeding max if (series.data.length() > chartConfig.maxDataPoints) { series.data.removeFirst() } i = i + 1 } } // Main chart drawing function local drawChart drawChart = function() { // Clear canvas canvas.setFillStyle("#ffffff") canvas.fillRect(0, 0, 800, 500) // Title canvas.setFillStyle("#2c3e50") canvas.fillText(chartConfig.title, 250, 30, "20px Arial", "#2c3e50") // Chart type indicator canvas.fillText("Chart Type: " + chartConfig.type.toUpperCase(), 50, 30, "16px Arial", "#34495e") // Draw chart elements drawAxes() drawLabels() if (chartConfig.type == "line") { drawLineChart() } else if (chartConfig.type == "bar") { drawBarChart() } else if (chartConfig.type == "area") { drawAreaChart() } drawLegend() // Status info canvas.setFillStyle("#6c757d") local statusText statusText = "Data Points: " + dataSeries[0].data.length() + "/" + chartConfig.maxDataPoints + " | Update Rate: " + chartConfig.updateInterval + "ms" canvas.fillText(statusText, 50, 480, "12px Arial", "#6c757d") } // Initialize with some sample data local i i = 0 loop(i < 10) { updateData() i = i + 1 } // Draw initial chart drawChart() // Simulate real-time updates local updateCount updateCount = 0 local simulateUpdates simulateUpdates = function() { local frameCount frameCount = 0 loop(frameCount < 20) { updateData() drawChart() frameCount = frameCount + 1 updateCount = updateCount + 1 } } simulateUpdates() print("📈 Real-time Data Chart Demo Ready!") print("• Chart type: " + chartConfig.type) print("• Data series: " + dataSeries.length()) print("• Max data points: " + chartConfig.maxDataPoints) print("• Update interval: " + chartConfig.updateInterval + "ms") print("• Total updates: " + updateCount) // Demo different chart types local chartTypes chartTypes = ["line", "bar", "area"] i = 0 loop(i < chartTypes.length()) { chartConfig.type = chartTypes[i] drawChart() print("✓ Rendered " + chartTypes[i] + " chart") i = i + 1 } // Set back to line chart chartConfig.type = "line" drawChart() print("🌟 Advanced chart features:") print("• Multiple visualization types (line, bar, area)") print("• Real-time data streaming with history") print("• Professional grid system and axes") print("• Interactive legend with current values") print("• Responsive layout with proper margins") print("• Data point management with rolling buffer") print("🌐 Everything is Box - even data visualization!") print("✅ Real-time Data Chart Demo Complete!")