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.
I've seen this as the solution elsewhere: http://jsfiddle.net/mbhavfwm/
But:
angular-chart.js
onAnimationComplete
in angular-chart.js
. 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:
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:
.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. 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?
There are some API changes to work with the later version of chart.js
.
So, for instance, properties like xScalePaddingLeft
are no longer available, and
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.
I've rewritten the above example to work with the latest versions of angular-charts.js
and chart.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/
Update with non-scrolling Title and Legend: https://jsfiddle.net/vfzyvg6z/2/
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.