1

我尝试使用仪表板 Thingsboard 在 Chart.js 中制作多 Y 轴,我尝试自己解决这个问题,但还没有结果。我已经成功地将标签放置在右侧 Y 轴上,但没有用,除非 X 轴数据已连接到它。我想在左侧和右侧制作 Y 轴。这是 Thingsboard 中的 chart.js

self.onInit = function() {

    var lineData = {
        labels: [],
        datasets: []
    };

    for (var i=0; i < self.ctx.data.length; i++) {
        var dataKey = self.ctx.data[i].dataKey;
        var keySettings = dataKey.settings;
        var backgroundColor = tinycolor(dataKey.color);
        backgroundColor.setAlpha(0.4);
        var dataset = {
            yAxisId: 'A',
            label: dataKey.label,
            data: [],
            borderColor: dataKey.color,
            borderWidth: 2,
            backgroundColor: backgroundColor.toRgbString(),
            pointRadius: keySettings.showPoints ? 1 : 0,
            fill: keySettings.fillLines || false,
            showLine: keySettings.showLines || false,
            spanGaps: false,
            lineTension: angular.isDefined(keySettings.tension) ? keySettings.tension : 0.1
        }
        lineData.datasets.push(dataset)
    }

    var ctx = $('#lineChart', self.ctx.$container);
    self.ctx.chart = new Chart(ctx, {
        type: 'line',
        data: lineData,
        options: {
            responsive: true,
            tooltips: {
                mode: 'index',
                intersect: false,
                enabled: true
            },
            hover: {
                mode: 'index',
                intersect: false,
                enabled: true
            },
            maintainAspectRatio: false,
            /*animation: {
              duration: 200,
              easing: 'linear'
            },*/
            elements: {
              line: {
                  tension: 0.5
              }  
            },
            scales: {
                xAxes: [{
                    type: 'time',
                    ticks: {
                        maxRotation: 20,
                        autoSkip: true
                    },
                    time: {
                        displayFormats: {
                            second: 'hh:mm:ss',
                            minute: 'hh:mm:ss'
                        }
                    }
                }],
                },
            zoom: {
                onSelect: function(startTimeMs, endTimeMs) {
                    self.ctx.timewindowFunctions.onUpdateTimewindow(startTimeMs, endTimeMs);
                },
                onResetSelect: function() {
                    self.ctx.timewindowFunctions.onResetTimewindow();
                }
            },
        }
    });

    self.onResize();

}

self.onDataUpdated = function() {

    if (self.ctx.chart.zoom.isMouseInteraction) {
        return;
    }
    if (!self.ctx.tickUpdate) {
        for (var i = 0; i < self.ctx.data.length; i++) {
            var dataSetData = [];
            var dataKeyData = self.ctx.data[i].data;
            for (var i2 = 0; i2 < dataKeyData.length; i2 ++) {
                dataSetData.push({x: moment(dataKeyData[i2][0]), y: dataKeyData[i2][1]});

            }
            self.ctx.chart.data.datasets[i].data = dataSetData; 
        }
    }

    self.ctx.chart.options.scales.xAxes[0].time.min = moment(self.ctx.timeWindow.minTime);
    self.ctx.chart.options.scales.xAxes[0].time.max = moment(self.ctx.timeWindow.maxTime);

    self.ctx.chart.update(0, true);

}

self.onResize = function() {
    self.ctx.chart.resize();
    self.ctx.chart.update(0, true);
}

self.onDestroy = function() {
}

function getYAxis(chartInstance) {
    var scales = chartInstance.scales;
    for (var scaleId in scales) {
        var scale = scales[scaleId];

        if (!scale.isHorizontal()) {
            return scale;
        }
    }
}

function getXAxis(chartInstance) {
    var scales = chartInstance.scales;
    for (var scaleId in scales) {
        var scale = scales[scaleId];

        if (scale.isHorizontal()) {
            return scale;
        }
    }
}

function eventPointer (e) {
    if (angular.isDefined(e.touches) && e.touches.length > 0) {
      return {
        x : e.touches[0].pageX,
        y : e.touches[0].pageY
      };
    } else if (angular.isDefined(e.changedTouches) && e.changedTouches.length > 0) {
      return {
        x : e.changedTouches[0].pageX,
        y : e.changedTouches[0].pageY
      };
    } else if (e.pageX || e.pageY) {
      return {
        x : e.pageX,
        y : e.pageY
      };
    } else if (e.clientX || e.clientY) {
      var
        d = document,
        b = d.body,
        de = d.documentElement;
      return {
        x: e.clientX + b.scrollLeft + de.scrollLeft,
        y: e.clientY + b.scrollTop + de.scrollTop
      };
    }
}

var zoomPlugin =     {
        beforeInit: function(chartInstance) {
            chartInstance.zoom = {};
            var node = chartInstance.zoom.node = chartInstance.chart.ctx.canvas;

            chartInstance.zoom.mouseDownHandler = function(event) {
                chartInstance.zoom.dragZoomStart = event;
                chartInstance.zoom.dragZoomStartPointer = eventPointer(event);
                chartInstance.zoom.isMouseInteraction = true;
            };

            node.addEventListener('mousedown', chartInstance.zoom.mouseDownHandler);

            chartInstance.zoom.mouseMoveHandler = function(event) {
                if (chartInstance.zoom.dragZoomStart) {
                    chartInstance.update(0);
                    chartInstance.zoom.dragZoomEnd = event;
                    chartInstance.zoom.dragZoomEndPointer = eventPointer(event);
                }
            };

            node.addEventListener('mousemove', chartInstance.zoom.mouseMoveHandler);

            chartInstance.zoom.mouseUpHandler = function(event) {
                if (chartInstance.zoom.dragZoomStart) {

                    var chartArea = chartInstance.chartArea;
                    var yAxis = getYAxis(chartInstance);
                    var beginPoint = chartInstance.zoom.dragZoomStart;
                    var beginPointer = chartInstance.zoom.dragZoomStartPointer;
                    var upEventPointer = eventPointer(event);
                    var offsetX = beginPoint.target.getBoundingClientRect().left;
                    var startX = Math.min(beginPointer.x, upEventPointer.x) - offsetX;
                    var endX = Math.max(beginPointer.x, upEventPointer.x) - offsetX;
                    var dragDistance = endX - startX;

                    if (dragDistance > 0) {
                        var xAxis = getXAxis(chartInstance);
                        var options = chartInstance.options;
                        if (options.scales.xAxes[0].time) {
                            startX = Math.max(startX, xAxis.left);
                            endX = Math.min(endX, xAxis.right);
                            if (endX - startX > 0) {
                                startX = startX - xAxis.left;
                                endX = endX - xAxis.left;
                                var time = options.scales.xAxes[0].time;
                                var min = time.min.valueOf();
                                var max = time.max.valueOf();
                                var axisDistance = xAxis.right - xAxis.left;
                                var timeDistance = max - min;

                                var zoomStartTime = min + startX / axisDistance * timeDistance;
                                var zoomEndTime = min + endX / axisDistance * timeDistance;

                                if (options.zoom && options.zoom.onSelect) {
                                    options.zoom.onSelect(zoomStartTime, zoomEndTime);
                                }
                            }
                        }
                    }
                    chartInstance.zoom.dragZoomStart = null;
                    chartInstance.zoom.dragZoomEnd = null;            
                }
                chartInstance.zoom.isMouseInteraction = false;
            };

            node.addEventListener('mouseup', chartInstance.zoom.mouseUpHandler);

            chartInstance.zoom.mouseLeaveHandler = function(event) {
                if (chartInstance.zoom.dragZoomStart) {
                    chartInstance.zoom.dragZoomStart = null;
                    chartInstance.zoom.dragZoomEnd = null;            
                }
                chartInstance.zoom.isMouseInteraction = false;
            };

            node.addEventListener('mouseleave', chartInstance.zoom.mouseLeaveHandler);

            chartInstance.zoom.dblClickHandler = function(event) {
                if (chartInstance.zoom.dragZoomStart) {
                    chartInstance.zoom.dragZoomStart = null;
                    chartInstance.zoom.dragZoomEnd = null;            
                }
                var options = chartInstance.options;
                if (options.zoom && options.zoom.onResetSelect) {
                    options.zoom.onResetSelect();
                }
            };

            node.addEventListener('dblclick', chartInstance.zoom.dblClickHandler);
        },
        beforeDatasetsDraw: function(chartInstance, easing) {
            var ctx = chartInstance.chart.ctx;
            var chartArea = chartInstance.chartArea;
            ctx.save();
            ctx.beginPath();
            if (chartInstance.zoom && chartInstance.zoom.dragZoomEnd) {
                var yAxis = getYAxis(chartInstance);
                var beginPoint = chartInstance.zoom.dragZoomStart;
                var beginPointer = chartInstance.zoom.dragZoomStartPointer;
                var endPoint = chartInstance.zoom.dragZoomEnd;
                var endPointer = chartInstance.zoom.dragZoomEndPointer;

                var offsetX = beginPoint.target.getBoundingClientRect().left;
                var startX = Math.min(beginPointer.x, endPointer.x) - offsetX;
                var endX = Math.max(beginPointer.x, endPointer.x) - offsetX;
                var rectWidth = endX - startX;
                ctx.fillStyle = 'rgba(157,203,255,0.1)';
                ctx.lineWidth = 1;
                ctx.strokeRect(startX, yAxis.top, rectWidth, yAxis.bottom - yAxis.top);
                ctx.fillRect(startX, yAxis.top, rectWidth, yAxis.bottom - yAxis.top);
            }
            if (chartArea) {
                ctx.rect(chartArea.left, chartArea.top, chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);
            }
            ctx.clip();            
        },

        afterDatasetsDraw: function(chartInstance) {
            chartInstance.chart.ctx.restore();
        },

        destroy: function(chartInstance) {
            if (chartInstance.zoom) {
                var node = chartInstance.zoom.node;
                node.removeEventListener('mousedown', chartInstance.zoom.mouseDownHandler);
                node.removeEventListener('mousemove', chartInstance.zoom.mouseMoveHandler);
                node.removeEventListener('mouseup', chartInstance.zoom.mouseUpHandler);
                node.removeEventListener('mouseleave', chartInstance.zoom.mouseLeaveHandler);    
                node.removeEventListener('dblclick', chartInstance.zoom.dblClickHandler);
                delete chartInstance.zoom;
            }
        }
    };

Chart.pluginService.register(zoomPlugin);

谢谢你。

4

1 回答 1

0

thingsboard 中的折线图已经支持辅助 y 轴。可以检查一下

于 2021-08-01T17:45:56.533 回答