116 lines
4.2 KiB
JavaScript
116 lines
4.2 KiB
JavaScript
/**
|
|
* Wrapper around Chart.js.
|
|
* Attached to window to avoid ES Module CORS issues on file:// protocol.
|
|
*/
|
|
(function (global) {
|
|
class Plotter {
|
|
constructor(canvasId) {
|
|
this.canvas = document.getElementById(canvasId);
|
|
this.ctx = this.canvas.getContext('2d');
|
|
this.chart = null;
|
|
|
|
this.init();
|
|
}
|
|
|
|
init() {
|
|
// Check if Chart is loaded
|
|
if (typeof Chart === 'undefined') {
|
|
console.error("Chart.js is not loaded!");
|
|
document.getElementById('loading').textContent = "Error: Chart.js library not found in lib/chart.js";
|
|
return;
|
|
}
|
|
|
|
// Gradient for the line
|
|
const gradient = this.ctx.createLinearGradient(0, 0, this.canvas.width, 0);
|
|
gradient.addColorStop(0, '#00f2ff'); // Cyan
|
|
gradient.addColorStop(1, '#bd00ff'); // Purple
|
|
|
|
Chart.defaults.color = '#8888aa';
|
|
Chart.defaults.font.family = "'Inter', 'Roboto', sans-serif";
|
|
|
|
this.chart = new Chart(this.ctx, {
|
|
type: 'line',
|
|
data: {
|
|
labels: [],
|
|
datasets: [{
|
|
label: 'Sine Wave',
|
|
data: [],
|
|
borderColor: '#00f2ff', // Fallback
|
|
backgroundColor: 'rgba(0, 242, 255, 0.1)',
|
|
borderWidth: 3,
|
|
tension: 0.4,
|
|
pointRadius: 0,
|
|
pointHoverRadius: 6,
|
|
fill: true,
|
|
shadowColor: 'rgba(0, 242, 255, 0.5)',
|
|
shadowBlur: 10
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
interaction: {
|
|
mode: 'index',
|
|
intersect: false,
|
|
},
|
|
plugins: {
|
|
legend: { display: false },
|
|
tooltip: {
|
|
backgroundColor: 'rgba(10, 10, 16, 0.8)',
|
|
titleColor: '#fff',
|
|
bodyColor: '#ccc',
|
|
borderColor: 'rgba(0, 242, 255, 0.3)',
|
|
borderWidth: 1,
|
|
backdropFilter: 'blur(4px)'
|
|
}
|
|
},
|
|
scales: {
|
|
x: {
|
|
grid: { color: 'rgba(255, 255, 255, 0.05)', borderColor: 'transparent' },
|
|
ticks: { maxTicksLimit: 10 }
|
|
},
|
|
y: {
|
|
grid: { color: 'rgba(255, 255, 255, 0.05)', borderColor: 'transparent' },
|
|
min: -1.2,
|
|
max: 1.2
|
|
}
|
|
},
|
|
animation: {
|
|
duration: 1500,
|
|
easing: 'easeOutQuart'
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
update(labels, data) {
|
|
if (!this.chart) return;
|
|
|
|
this.chart.data.labels = labels;
|
|
this.chart.data.datasets[0].data = data;
|
|
|
|
const gradient = this.ctx.createLinearGradient(0, 0, this.ctx.canvas.width, 0);
|
|
gradient.addColorStop(0, '#00f2ff');
|
|
gradient.addColorStop(0.5, '#7000ff');
|
|
gradient.addColorStop(1, '#ff0055');
|
|
|
|
this.chart.data.datasets[0].borderColor = gradient;
|
|
this.chart.data.datasets[0].backgroundColor = (context) => {
|
|
const ctx = context.chart.ctx;
|
|
const gradient = ctx.createLinearGradient(0, 0, 0, ctx.canvas.height);
|
|
gradient.addColorStop(0, 'rgba(0, 242, 255, 0.2)');
|
|
gradient.addColorStop(1, 'rgba(0, 242, 255, 0)');
|
|
return gradient;
|
|
};
|
|
|
|
this.chart.update();
|
|
|
|
// Hide loading text on first successful update
|
|
const loading = document.getElementById('loading');
|
|
if (loading) loading.style.display = 'none';
|
|
}
|
|
}
|
|
|
|
global.Plotter = Plotter;
|
|
})(window);
|