简体   繁体   English

如何使用angular-chart.js和chart.js创建水平滚动效果

[英]How can I create a horizontal scroll effect with angular-chart.js and chart.js

I'm using angular-chart.js (v1.1.1), an angular wrapper around chart.js (I believe angular-chart.js uses chart.js v2.x), and am having trouble creating a horizontal scroll effect when the number of bars in a bar chart start to get large. 我正在使用angular-chart.js (v1.1.1),一个围绕chart.js的角度包装器(我相信angular-chart.js使用chart.js v2.x),并且在创建水平滚动效果时遇到了麻烦条形图中的条形数量开始变大。

I've seen this as the solution elsewhere: http://jsfiddle.net/mbhavfwm/ 我将其视为其他地方的解决方案: http : //jsfiddle.net/mbhavfwm/

But: 但:

  1. I'm not sure if I have access to the underlying chart element in the way the user does here with angular-chart.js 我不确定是否可以通过用户使用angular-chart.js来访问底层图表元素
  2. I can't even get access to onAnimationComplete in angular-chart.js . 我甚至无法访问onAnimationCompleteangular-chart.js
  3. It seems a bit hacky to use this solution. 使用此解决方案似乎有点棘手。 Is there a better way to not render 2 x axes while ensuring the bar graph can scroll horizontal? 有没有一种更好的方法在确保条形图可以水平滚动的同时不渲染2 x轴?

Here is my current solution: I have 3 containing divs, and the canvas is finally rendered inside the 3rd containing div with the following config: 这是我当前的解决方案:我有3个div,最后使用以下配置将canvas渲染到第3个div中:

this.chartOptions = this.composeChartService.createChartOptions({
  title: ctrl.chartTitle,
  legend: {
    position: 'bottom'
  },
  responsive: true,
  maintainAspectRatio: true
});

Here is the jade: 这是玉:

mixin dynamic-chart(type)
  canvas(
    class=`chart chart-${ type }`
    title="$ctrl.chartId"
    chart-data="$ctrl.events" 
    chart-series="$ctrl.cities" 
    chart-labels="$ctrl.labels"
    chart-click="$ctrl.onClickBar"
    chart-options="$ctrl.chartOptions")

div.chart-wrapper(ng-switch="$ctrl.chartType")
  //- Bar chart
  div.chart-area-wrapper(ng-when="bar")
    div.chart-test
      +dynamic-chart('bar')

And here is the stylus that affects these divs: 这是影响这些div的手写笔:

.chart-wrapper
  width: 800px
  overflow: auto  
  canvas
    background-color: white
    width: 100%

.chart-test
  width: 1200px !important
  background-color: yellow

The horizontal scroll kind of works with this solution, but the bar thickness is too low, and I don't like arbitrarily picking the width of the .chart-test div when that width isn't needed. 水平滚动类型适用于此解决方案,但是条形图的厚度太小,我不喜欢在.chart-test该宽度时随意选择.chart-test div的宽度。 Also,the title and legend sometimes are hidden with this solution (depending on how long the scroll is). 而且,有时标题和图例会被此解决方案隐藏(取决于滚动的时间)。

So, is there a better way to make angular.chart.js play nice with horizontal scroll? 因此,是否有更好的方法可以使angular.chart.js与水平滚动angular.chart.js播放?

There are some API changes to work with the later version of chart.js . 有一些API更改可与更高版本的chart.js

So, for instance, properties like xScalePaddingLeft are no longer available, and 因此,例如, xScalePaddingLeft类的属性不再可用,并且

onAnimationComplete : function(){} 

is now 就是现在

animation: { onComplete : function(){} }

There is no better way to do it (IMO) because you really need to have that independent floating Y-axis and chart.js doesn't provide that option out of the box. 没有更好的方法(IMO),因为您确实需要具有独立的浮动Y轴,而chart.js并没有提供该选项。

I've rewritten the above example to work with the latest versions of angular-charts.js and chart.js : 我重写了上面的示例,以使用最新版本的angular-charts.jschart.js

 var app = angular.module("app", ["chart.js"]); app.controller("LineCtrl", function($scope) { $scope.labels = ["January", "February", "March", "April", "May", "June", "July"]; $scope.series = ['Series A', 'Series B']; $scope.data = [ [65, 59, 80, 81, 56, 55, 40], [28, 48, 40, 19, 86, 27, 90] ]; $scope.onClick = function(points, evt) { console.log(points, evt); }; $scope.datasetOverride = [{ yAxisID: 'y-axis-1' }]; $scope.options = { scales: { yAxes: [{ id: 'y-axis-1', type: 'linear', display: true, position: 'left' }] }, responsive: false, animation: { onComplete: function() { var sourceCanvas = this.chart.ctx.canvas; var copyWidth = this.chart.controller.chartArea.left - 5; // the +5 is so that the bottommost y axis label is not clipped off // we could factor this in using measureText if we wanted to be generic var copyHeight = this.chart.controller.chartArea.bottom + 5; // 282 //this.scale.endPoint + 5; var targetCtx = document.getElementById("myChartAxis").getContext("2d"); targetCtx.canvas.width = copyWidth; targetCtx.drawImage(sourceCanvas, 0, 0, copyWidth, copyHeight, 0, 0, copyWidth, copyHeight); } } }; }); 
 .chartWrapper { position: relative; } .chartWrapper>canvas { position: absolute; left: 0; top: 0; pointer-events: none; } .chartAreaWrapper { width: 600px; overflow-x: scroll; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.js"></script> <script src="https://cdn.jsdelivr.net/angular.chartjs/latest/angular-chart.min.js"></script> <div ng-app="app" ng-controller="LineCtrl"> <div class="chartWrapper"> <div class="chartAreaWrapper"> <canvas id="line" class="chart chart-line" chart-data="data" chart-labels="labels" chart-series="series" chart-options="options" chart-dataset-override="datasetOverride" chart-click="onClick" width="1200" height="300"></canvas> </div> <canvas id="myChartAxis" height="300" width="0"></canvas> </div> </div> 

Here's the same in a jsfiddle: https://jsfiddle.net/vfzyvg6z/1/ 这在jsfiddle中是相同的: https ://jsfiddle.net/vfzyvg6z/1/

Update with non-scrolling Title and Legend: https://jsfiddle.net/vfzyvg6z/2/ 使用非滚动标题和图例更新https//jsfiddle.net/vfzyvg6z/2/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM