class ChartLoader { constructor(canvas, effectCanvas, detectionCanvas, parent, legend, dataDiv) { this.canvas = canvas this.effectCanvas = effectCanvas this.detectionCanvas = detectionCanvas this.parent = parent this.legend = legend this.dataDiv = dataDiv this.clickedShapeIndex = null this.selectedShapeIndex = null } //Načtení dat loadData(code) { fetch("/api/charts/" + code, { method: 'GET', headers: { 'Content-Type': 'json' } }) .then(response => response.json()) .then(data => { let metadata = data.metadata metadata.custom_x_values = "" let table = data.table if (data !== null) { this.drawChart(metadata, table) this.parent.style.backgroundColor = metadata.backgroundColor } else this.parent.innerHTML = "graph not found." }) } getShapeIndex(canvas, pos) { let ctx = canvas.getContext('2d') // Get neigboring pixels let imageData = Array.from(ctx.getImageData(pos.x - 2, pos.y - 2, 5, 5).data) // Convert into indexes let indexes = [] while (imageData.length > 0) { let pixel = imageData.splice(0, 4) // only if alpha is 100% if (pixel[3] === 255) { let index = (pixel[0] * 256 + pixel[1]) * 256 + pixel[2] indexes.push(index) } } function mode(array) { if (array.length == 0) return null let modeMap = {} let maxEl = array[0], maxCount = 1 for (let i = 0; i < array.length; i++) { let el = array[i] if (modeMap[el] == null) modeMap[el] = 1 else modeMap[el]++ if (modeMap[el] > maxCount) { maxEl = el maxCount = modeMap[el] } } return maxEl } // To avoid edge cases because of anti aliasing let mostCommonIndex = mode(indexes) return mostCommonIndex } getEffectObjects() { } addListener(newChart) { //Click document.addEventListener('mousemove', (e) => { const pos = { x: e.clientX, y: e.clientY } let shapeIndex = this.selectedShapeIndex if (shapeIndex === null) shapeIndex = this.getShapeIndex(this.detectionCanvas, pos) if (shapeIndex !== null) { let obj = newChart.objects[shapeIndex] // Effect let effectCtx = this.effectCanvas.getContext("2d") effectCtx.clearRect(0, 0, effectCanvas.width, effectCanvas.height) this.effectCanvas.style.opacity = 1 newChart.drawEffect(effectCtx, [obj]) this.dataDiv.style.display = "block" // make the info fit into the chart div if (pos.x + this.dataDiv.clientWidth <= this.parent.clientWidth - 2) this.dataDiv.style.left = pos.x + "px" else this.dataDiv.style.left = pos.x - this.dataDiv.clientWidth + "px" if (pos.y + this.dataDiv.clientHeight <= parent.clientHeight - 2) this.dataDiv.style.top = pos.y + "px" else this.dataDiv.style.top = pos.y - this.dataDiv.clientHeight + "px" this.dataDiv.style.display = "block" let name = newChart.data[obj.colId.toString()].col_name this.dataDiv.innerHTML = "" + name + "

" + obj.value + "

" } else { this.dataDiv.style.display = "none" this.effectCanvas.style.opacity = 0 } }) document.addEventListener("mousedown", (e) => { const pos = { x: e.clientX, y: e.clientY } this.clickedShapeIndex = this.getShapeIndex(this.detectionCanvas, pos) }) document.addEventListener("mouseup", (e) => { const pos = { x: e.clientX, y: e.clientY } if (this.clickedShapeIndex === null || this.clickedShapeIndex !== this.getShapeIndex(this.detectionCanvas, pos)) this.selectedShapeIndex = null else this.selectedShapeIndex = this.clickedShapeIndex console.log(this.clickedShapeIndex + " " + this.getShapeIndex(this.detectionCanvas, pos) + " " + this.shapeSelected) }) window.addEventListener("resize", e => { //newChart.updateLegend(graphSettings.displayLegend, data) newChart.resizeCanvas(this.parent, this.legend.offsetHeight) newChart.draw() this.addInteractivity() }) } async addInteractivity() { setTimeout(() => { console.time("2") this.effectCanvas.width = this.canvas.width this.effectCanvas.height = this.canvas.height this.detectionCanvas.width = this.canvas.width this.detectionCanvas.height = this.canvas.height this.chart.drawDetectionMap(this.detectionCanvas.getContext("2d")) console.timeEnd("2") }, 0) } drawChart(graphSettings, data) { //Choose the correct graph switch (graphSettings.type) { case "point": this.chart = new PointChart(this.canvas, data, graphSettings) break case "line": this.chart = new LineChart(this.canvas, data, graphSettings) break case "smoothline": this.chart = new SmoothLineChart(this.canvas, data, graphSettings) break case "pie": this.chart = new PieChart(this.canvas, data, graphSettings) break case "donut": this.chart = new DonutChart(this.canvas, data, graphSettings) break case "bar": this.chart = new BarChart(this.canvas, data, graphSettings) break case "area": this.chart = new AreaChart(this.canvas, data, graphSettings) break case "smootharea": this.chart = new SmoothAreaChart(this.canvas, data, graphSettings) break case "stacked": this.chart = new StackedChart(this.canvas, data, graphSettings) break } setTimeout(this.chart.updateLegend(graphSettings.displayLegend, this.legend, this), 0) this.chart.resizeCanvas(this.parent, this.legend.offsetHeight) this.chart.draw() this.addInteractivity() this.addListener(this.chart) } }