在 ChartJS 和 Angular 上进行水平滚动时使 y 轴粘性

inf*_*dev 5 html javascript chart.js angular chartjs-2.6.0

我想在水平滚动时修复 y 轴位置。

这是一个可以工作但不使用 Angular 的示例

$(document).ready(function () {

    function generateLabels() {
        var chartLabels = [];
        for (x = 0; x < 100; x++) {
            chartLabels.push("Label" + x);
        }
        return chartLabels;
    }

    function generateData() {
        var chartData = [];
        for (x = 0; x < 100; x++) {
            chartData.push(Math.floor((Math.random() * 100) + 1));
        }
        return chartData;
    }

    function addData(numData, chart) {
        for (var i = 0; i < numData; i++) {
            chart.data.datasets[0].data.push(Math.random() * 100);
            chart.data.labels.push("Label" + i);
            var newwidth = $('.chartAreaWrapper2').width() + 60;
            $('.chartAreaWrapper2').width(newwidth);
        }
    }

    var chartData = {
        labels: generateLabels(),
        datasets: [{
            label: "Test Data Set",
            data: generateData()
        }]
    };



    $(function () {
        var rectangleSet = false;

        var canvasTest = $('#chart-Test');
        var chartTest = new Chart(canvasTest, {
            type: 'bar',
            data: chartData,
            maintainAspectRatio: false,
            responsive: true,
            options: {
                tooltips: {
                    titleFontSize: 0,
                    titleMarginBottom: 0,
                    bodyFontSize: 12
                },
                legend: {
                    display: false
                },
                scales: {
                    xAxes: [{
                        ticks: {
                            fontSize: 12,
                            display: false
                        }
                    }],
                    yAxes: [{
                        ticks: {
                            fontSize: 12,
                            beginAtZero: true
                        }
                    }]
                },
                animation: {
                    onComplete: function () {
                        if (!rectangleSet) {
                            var sourceCanvas = chartTest.chart.canvas;
                            var copyWidth = chartTest.scales['y-axis-0'].width;
                            var copyHeight = chartTest.scales['y-axis-0'].height + chartTest.scales['y-axis-0'].top + 10;
                            var targetCtx = document.getElementById("axis-Test").getContext("2d");
                            targetCtx.canvas.width = copyWidth;
                            targetCtx.drawImage(sourceCanvas, 0, 0, copyWidth, copyHeight, 0, 0, copyWidth, copyHeight);

                            var sourceCtx = sourceCanvas.getContext('2d');
                            sourceCtx.clearRect(0, 0, copyWidth, copyHeight);
                            rectangleSet = true;
                        }
                    },
                    onProgress: function () {
                        if (rectangleSet === true) {
                            var copyWidth = chartTest.scales['y-axis-0'].width;
                            var copyHeight = chartTest.scales['y-axis-0'].height + chartTest.scales['y-axis-0'].top + 10;

                            var sourceCtx = chartTest.chart.canvas.getContext('2d');
                            sourceCtx.clearRect(0, 0, copyWidth, copyHeight);
                        }
                    }
                }
            }
        });
        addData(5, chartTest);
    });
});
Run Code Online (Sandbox Code Playgroud)
.chartWrapper {
  position: relative;
}

.chartWrapper > canvas {
  position: absolute;
  left: 0;
  top: 0;
  pointer-events: none;
}

.chartAreaWrapper {
  width: 600px;
  overflow-x: scroll;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://github.com/chartjs/Chart.js/releases/download/v2.6.0/Chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="chartWrapper">
  <div class="chartAreaWrapper">
  <div class="chartAreaWrapper2">
      <canvas id="chart-Test" height="300" width="1200"></canvas>
  </div>
  </div>
  <canvas id="axis-Test" height="300" width="0"></canvas>
</div>
Run Code Online (Sandbox Code Playgroud)

当我在我的角度示例中使用它时,它不再起作用,轴不跟随滚动

这是 stackblitz 复制品

umi*_*der 3

在 StackBlitz 中,y 轴的部分(矩形)在目标上正确创建canvas并从源中删除canvas。问题是div水平滚动错误。这可以通过更改模板和相应的css.

请看下面的StackBlitz

更新(动态数据)

如果图表组件通过属性接收动态变化的数据@Input(),您的组件需要实现OnChange生命周期挂钩。

请参阅以下StackBlitz

请注意,此代码远未优化。您应该简单地更新现有图表上的数据和选项,而不是在每次数据更改时从头开始创建图表。