UNPKG

maher-tradingview-api

Version:

Tradingview instant stocks API, indicator alerts, trading bot, and more !

182 lines (163 loc) 6.17 kB
// Enhanced Chart Renderer with better performance and features class EnhancedChartRenderer { constructor(options = {}) { this.options = { animations: true, responsiveAnimationDuration: 500, tooltips: true, crosshair: true, zoom: true, ...options }; this.charts = new Map(); } renderPriceChart(canvasId, labels, values, symbol, additionalOptions = {}) { const ctx = document.getElementById(canvasId)?.getContext('2d'); if (!ctx) return null; const gradientFill = ctx.createLinearGradient(0, 0, 0, ctx.canvas.height); gradientFill.addColorStop(0, 'rgba(0, 136, 204, 0.3)'); gradientFill.addColorStop(1, 'rgba(0, 136, 204, 0.05)'); const chartOptions = { type: 'line', data: { labels: labels, datasets: [{ label: symbol, data: values, borderColor: '#0088cc', backgroundColor: gradientFill, borderWidth: 2, fill: true, pointRadius: 0, pointHoverRadius: 4, pointHoverBackgroundColor: '#0088cc', pointHoverBorderColor: '#fff' }] }, options: { animation: { duration: this.options.animations ? this.options.responsiveAnimationDuration : 0 }, responsive: true, maintainAspectRatio: false, interaction: { intersect: false, mode: 'index' }, plugins: { legend: { display: true, position: 'top', rtl: true, labels: { font: { family: 'Arial' } } }, tooltip: { enabled: this.options.tooltips, rtl: true, mode: 'index', intersect: false, callbacks: { label: (context) => { return `${context.dataset.label}: ${context.parsed.y.toFixed(2)}`; } } }, crosshair: { enabled: this.options.crosshair, line: { color: '#666', width: 1, dashPattern: [5, 5] } }, zoom: { enabled: this.options.zoom, mode: 'x', sensitivity: 3, speed: 0.1 } }, scales: { x: { grid: { display: false }, ticks: { maxRotation: 0, autoSkip: true, maxTicksLimit: 10 } }, y: { position: 'right', grid: { color: 'rgba(0, 0, 0, 0.05)' }, ticks: { callback: (value) => value.toFixed(2) } } } } }; const finalOptions = this.mergeChartOptions(chartOptions, additionalOptions); const chart = new Chart(ctx, finalOptions); this.charts.set(canvasId, chart); return chart; } mergeChartOptions(baseOptions, additionalOptions) { return this.deepMerge(baseOptions, additionalOptions); } deepMerge(target, source) { const isObject = (obj) => obj && typeof obj === 'object'; if (!isObject(target) || !isObject(source)) { return source; } Object.keys(source).forEach(key => { const targetValue = target[key]; const sourceValue = source[key]; if (Array.isArray(targetValue) && Array.isArray(sourceValue)) { target[key] = targetValue.concat(sourceValue); } else if (isObject(targetValue) && isObject(sourceValue)) { target[key] = this.deepMerge(Object.assign({}, targetValue), sourceValue); } else { target[key] = sourceValue; } }); return target; } updateChart(canvasId, newData, newLabels) { const chart = this.charts.get(canvasId); if (!chart) return; chart.data.labels = newLabels; chart.data.datasets[0].data = newData; chart.update('none'); // Using 'none' for better performance } destroyChart(canvasId) { const chart = this.charts.get(canvasId); if (chart) { chart.destroy(); this.charts.delete(canvasId); } } addIndicator(canvasId, indicator) { const chart = this.charts.get(canvasId); if (!chart) return; chart.data.datasets.push(indicator); chart.update(); } removeIndicator(canvasId, indicatorId) { const chart = this.charts.get(canvasId); if (!chart) return; chart.data.datasets = chart.data.datasets.filter(dataset => dataset.id !== indicatorId); chart.update(); } } // Export the enhanced renderer window.EnhancedChartRenderer = new EnhancedChartRenderer();