jtblin / angular-chart.js Goto Github PK
View Code? Open in Web Editor NEWReactive, responsive, beautiful charts for AngularJS using Chart.js: http://jtblin.github.io/angular-chart.js
License: Other
Reactive, responsive, beautiful charts for AngularJS using Chart.js: http://jtblin.github.io/angular-chart.js
License: Other
When a dataset is defined as an attribute of a json object (eg myObject.data) and labels are defined, sometimes the console can display the following error until the json is resolved.
TypeError: Cannot read property '0' of undefined
Adding a check for data corrects.
function getData (labels, data, colours) { colours = colours || Chart.defaults.global.colours; if (data) { return labels.map(function (label, i) { return { label: label, value: data[i], color: colours[i].strokeColor, highlight: colours[i].pointHighlightStroke }; }); } else { return [] ; }
getData or getDataSeries loops through an array of colors with a possible array out of range exception(when data.length is > than scope.colours.length(or default colors length).
A possible (but ugly fix might be):
//Prevent an undefined compilation error
colours: '=?',
//Remove colour array assignment in getdata and getdata series
function createChart()
scope.colours = scope.colours || Chart.defaults.global.colours;
if(scope.colours.length < scope.data.length)
{
var itemsToAdd = scope.data.length - scope.colours.length;
for(var i=0; i<=itemsToAdd; i++)
{
var color = getRandomColor();
scope.colours.push({
fillColor: color,
strokeColor: color,
pointColor: color,
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(151,187,205,0.8)"
});
}
}
getRandomColor() is a matter of a flavour.
Cheers!
Cannot figure out how to format values on tooltips. For instance, I would like a pie chart to display a value as "$4,500" instead of "4500". Is this functionality currently available?
It seems like if passing the parameter height it is ignored and not passed on?
eg.
Rendered Height is then 205px
If there is already a work around for this, please let me know, but here is my use case / issue.
I am using foundation's tabset directive to build up tabs and their corresponding containers. I have some the chart.js graphs being defined inside a hidden container; therefore, the charts have no container width or height when it comes to rendering the graphs.
Would there be a way to achieve this? Could you potentially add in a "reset" watch to the angular-chart.js which will destroy and recreate the chart?
The default CSS styles for the legend list items seems to have some issues when wrapping. I've made a few updates locally that seem to resolve the issue.
First, for the "li" styles, change "display: inline" to "display: inline-block" and add "white-space: nowrap;" so that each list item is able to wrap individually, but the text for the list item doesn't wrap. This ensures that a long list item name doesn't wrap from one line to another.
Finally, for the "span" styles, change "height: 100%" to "height: 20px" so that the legend color swatches are square and not the entire height of the legend box.
Please let me know if you have any questions or if you run into any issues.
Thanks,
Brian
When using ng-view container on one-page app the chart is empty 0x0px, is there any known issue about that?
When using a Dynamic Chart, Bar or Radar, and trying to change it to Line, this error occurs:
Uncaught TypeError: Cannot read property 'highlightFill' of undefined
It happened only once, and I was not able to render the Line chart.
Now every time I reload the browser I have this error, on every type of chart. (But now they all render...)
Here are my options:
$scope.options = {
responsive: true,
maintainAspectRatio: true,
animation: false
};
I use a 3 series chart.
Note: with animation set to true, the error disappeared.
How can I add double Y axis in chart?
When creating a chart with empty labels, data, series, etc. for later loading via AJAX, a Javascript exception occurs unless the data array is initialized as an array of an empty array (e.g. [[]]
). I've included a fix below:
Broken Code:
if (hasDataSets(type) && !newVal[0].length) return;
Fixed Code:
if (hasDataSets(type) && (!newVal.length || !newVal[0].length)) return;
I'm working around this currently by initializing my data variable in the previously mentioned style ([[]]
) and then clearing it and pushing the multiple series of data to the data array, so this isn't an urgent issue but is more of a nice to have if it doesn't cause other problems.
Thanks,
Brian
Chartjs won't (as I understand it) draw a chart with empty values (whether that be nulls or 0's), and it won't update a chart that hasn't been drawn. As a result, when instantiating a chart with all 0's the chart never actually updates when it's data changes.
Unfortunately I haven't got an example on hand, but it should be fairly easy to replicate with the example code in the readme if you change the initial values to 0; I've only tested this with pie and donut charts too.
I couldn't find a way to check if the chart has already been drawn, so a quick fix was to check to see if oldVal > 0 in canUpdateChart:
function canUpdateChart(type, newVal, oldVal) {
if (newVal && oldVal && newVal.length && oldVal.length) {
if(oldVal.reduce(function(carry, val){return carry+val;}, 0) > 0)
return hasDataSets(type) ?
newVal.length === oldVal.length && newVal[0].length === oldVal[0].length :
newVal.length === oldVal.length;
else
return false;
}
return false;
}
Hi,
I have implemented a pie chart on my page and set custom colours using "colours" attribute.
On first load, eveything is well, but if I update data, the fill color change and isn't consistent.
The behaviour is OK if I do not specify custom colours.
Im doing a post to a database via my angular service, 1 of 10 times the graph loads, but 9 out of 10 times it only shows up when i resize the window.
Im guessing that the graph is drawn before the data is populated from my service, allthough from the documentation the graph data could be empty and update when populated (reactive)?
Heres ,my example
<canvas id="line" class="chart chart-line" data="data" options="options" labels="labels" series="series"></canvas>
GraphService.fetchSensorLogs(sensortofetch, function(response) {
$scope.series = ['Measurement'];
$scope.labels = response.labels;
$scope.options = { animation: false, showScale : true, showTooltips : false, scaleShowLabels: true, pointDot: true, scaleShowGridLines : false};
$scope.data = response.data;
});
Charts which change its' type dynamically duplicate its legend everytime the type is changed.
This can be tested by going to line 353 of the example "charts.html" and making the dynamic chart show a legend by placing the legend attribute such as legend="true"
There are a lot of "options" that can be passed through to Chart.js. It would be nice if these were dynamic so that if we changed an option the chart would automatically update. You can accomplish this by watching the "options" databinding in angular-chart. Here is how I did it:
scope.$watch('options', function (newVal, oldVal) {
var chartType = type || scope.chartType;
if (! chartType) return;
if (chart) chart.destroy();
chart = createChart(chartType, scope, elem);
});
You could also do it with this line, but then you would have to modify the first line of resetChart to allow an object to pass through.
scope.$watch('options', resetChart, true);
Hi! Please add support for horizontal bar charts, it is often prefered way to display chart on mobile devices
why is there padding-right: 15px;
on the canvas
element?
https://github.com/jtblin/angular-chart.js/blob/master/angular-chart.less#L2
this causes the charts to be distorted. also seems that charts don't fit within their parent. quick looks indicates that they ignore the parent element's padding but I'd have to investigate more to be sure. also this may be an issue outside of the scope of this module.
I get an infinite digest loop when I try to put a function inside the "data" attribute of a doughnut chart (not sure if this happens for all of them. I'm using an ng-repeat to create multiple charts from a dataset. Like this -
<div ng-repeat="lesson in lessonStats">
<canvas id="doughnut" class="chart chart-doughnut" data="dataForLesson(lesson)"</canvas>
</div>
in controller -
$scope.dataForLesson = function(lesson){
return [
lesson["not_started"]["total"],
lesson["in_progress"]["total"],
lesson["completed"]["total"]
];
}
If I manually put the array into the data tag it works, but I'd rather keep that logic out of my HTML. Am I doing something wrong?
Fairly new to Angular so I appreciate I may not be going about this the best way.
Scenario: I'm looking to use multiple charts on a single page app. Currently set up to use ng-show to determine which div is shown via a dropdown menu and, as such, what chart and controller is used. On switching charts I broadcast a message to pull in the correct data required.
When updating data alone it works fine and both charts are visible.... When adding extra values to series and data on one graph and then switching to a second graph and then back (i.e. from line to bar to line) the line chart is disappearing from the page with just the legend left behind. It appears to be hitting the destroy and reset functions multiple times due to the watch on data and series but the chart is no longer visible.
Any ideas what is causing the chart to disappear? Or how to better go about attempting this?
I'm using bootstrap's tabs with chartjs charts inside every tab.
One problem that have occurred though is that the graph canvas wont be drawn until i resize the browser window. And this is happening in both latest Chrome and Firefox.
I'm having exactly the same problem described here: http://stackoverflow.com/questions/26178399/chartjs-wont-draw-graph-inside-bootstrap-tab-until-window-resize
Thanks!
The demo page does not work.
Also I cant get a line chart working it says undefined field data.datasets my chart code looks like this:
$scope.allreports = {
labels : [ "Jun", "July",
"Aug"],
datasets : [ {
fillColor : "rgba(151,187,205,0.5)",
strokeColor : "rgba(151,187,205,1)",
pointColor : "rgba(151,187,205,1)",
pointStrokeColor : "#fff",
data : [1, 2, 3]
} ]
};
All it says is: "Error: data is undefined" WHy.
Hi,
I've been trying to figure this out but couldn't get to it... have no experience with Chart.js either. Is there any way to set the values on the y-axis in a line chart? E.g. my chart runs between 80 and 95, but I want the values on the y-axis to be between let's say 0 and 120. This way my chart doesn't start straight from the bottom but starts already somewhere above the middle and the swings between values don't look as too big jumps.
I assume this should be possible but really can't find the function for it.
Thanks,
It appears as though the legend is not being updated along with the rest of the data. Not much code needed to repro the issue; setup a basic chart:
<canvas class="chart chart-doughnut" data="points" labels="labels" legend="true"></canvas>
After a short delay, change the labels as well as the data. Legend is not updated.
I'm seeing this issue in both Chrome and Internet Explorer, so it doesn't appear to be browser-related.
It should support hex colours e.g. $scope.colors = ['#FD1F5E','#1EF9A1','#7FFD1F','#68F000'];
Named colours e.g. red are out of scope.
Replicating the issue is fairly easy:
Chart.types.Line.extend({
name: "LineAlt",
initialize: function(data){
Chart.types.Line.prototype.initialize.apply(this, arguments);
}
});
The "data" parameter is all wrong. The problem seems to be in the following code:
function hasDataSets(type) {
return ['Line', 'Bar', 'Radar'].indexOf(type) > -1;
}
The extension will have a different name and hasDataSets will return false which in turn will result in a non-dataset formatted parameter being supplied to the chart constructor.
If the view changes and results in the angular-chart scope being destroyed, the ChartJS object is not given the opportunity to clean itself up. This can lead to memory leaks.
I believe the solution is to add the following three lines to angular-chart.js
scope.$on('$destroy', function() {
if (chart) chart.destroy();
});
only piece of code where id is used is this:
document.getElementById(scope.id)
and this could be switched to:
elem[0]
[0] to unwrap jqlite
Seb here :-)
The directive markup is missing chart-base in the class attribute
Wrong:
<canvas id="chart-base" class="chart" chart-type="type" data="data" labels="labels"></canvas>
Fixed:
<canvas id="chart-base" class="chart chart-base" chart-type="type" data="data" labels="labels"></canvas>
I was wondering why it wasn't working until I took a look at how you implemented the directive in the demo page.
Hi,
I'm using the mean.io template. I've installed chart.js using "bower install angular-chart.js --save".
I have verified that it installed and is available in bower_components.
I have added "bower_components/angular-chart.js/angular-chart.js" to config/assets.json
And declared it as a dependency in my module:
angular.module('mean.posts', ['ngSanitize', 'angularFileUpload', 'infinite-scroll', 'chart.js'])
Upon running my app, I get the error "Error: [$injector:nomod] Module 'chart.js' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument."
I've used the same process to add other dependencies without error (such as angularFileUpload and infinite-scroll). I'm not sure how to resolve the error.
Any suggestions?
Thanks!
As described here in chartjs/Chart.js#411 I'd like to define:
Chart.defaults.global.scaleLabel = function(label){return label.value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".");};
This works with pure Chart.js like here: http://jsbin.com/secikusevi/1/edit?html,js,output
But angular-chart.js returns this error:
[Error] Error: undefined is not a function (evaluating 't.replace(/[\r\t\n]/g," ")')
e@https://silberpfeil.local:8000/static/Chart.js/Chart.min.js:9:4237
template@https://silberpfeil.local:8000/static/Chart.js/Chart.min.js:9:4489
buildYLabels@https://silberpfeil.local:8000/static/Chart.js/Chart.min.js:9:18649
fit@https://silberpfeil.local:8000/static/Chart.js/Chart.min.js:9:19226
initialize@https://silberpfeil.local:8000/static/Chart.js/Chart.min.js:9:18536
Element@https://silberpfeil.local:8000/static/Chart.js/Chart.min.js:9:13480
https://silberpfeil.local:8000/static/Chart.js/Chart.min.js:9:2206
buildScale@https://silberpfeil.local:8000/static/Chart.js/Chart.min.js:10:8329
https://silberpfeil.local:8000/static/Chart.js/Chart.min.js:10:6945
each@https://silberpfeil.local:8000/static/Chart.js/Chart.min.js:9:1554
initialize@https://silberpfeil.local:8000/static/Chart.js/Chart.min.js:10:3547
Type@https://silberpfeil.local:8000/static/Chart.js/Chart.min.js:9:9728
s@https://silberpfeil.local:8000/static/Chart.js/Chart.min.js:9:12990
https://silberpfeil.local:8000/static/Chart.js/Chart.min.js:9:26271
o@https://silberpfeil.local:8000/static/angular-chart.js/dist/angular-chart.js:1:535
https://silberpfeil.local:8000/static/angular-chart.js/dist/angular-chart.js:1:281
$digest@https://silberpfeil.local:8000/static/angular/angular.min.js:109:405
$apply@https://silberpfeil.local:8000/static/angular/angular.min.js:112:405
h@https://silberpfeil.local:8000/static/angular/angular.min.js:72:460
v@https://silberpfeil.local:8000/static/angular/angular.min.js:77:796
onreadystatechange@https://silberpfeil.local:8000/static/angular/angular.min.js:79:25
(anonyme Funktion) (angular.min.js, line 92)
(anonyme Funktion) (angular.min.js, line 68)
$digest (angular.min.js, line 110)
$apply (angular.min.js, line 112)
h (angular.min.js, line 72)
v (angular.min.js, line 77)
onreadystatechange (angular.min.js, line 79)
How do you put the legend on the right-hand-side?
Hi,
I just downloaded the current angular-chart.tar.gz file. It contains a zero bytes angular-chart.css file. The file itself in the dist/-folder at GitHub has its content.
I'm not sure what the best way is of extending your current directives to support the StackedBar extension at https://github.com/Regaddi/Chart.StackedBar.js, but if you'd like add support directly it's pretty straightforward.
First, a new directive needs to be added:
.directive("chartStackedBar", function () { return chart('StackedBar'); });
Next, the click handler needs to be updated:
cvs.onclick = function (evt) {
var click = chart.getPointsAtEvent || chart.getSegmentsAtEvent || chart.getBarsAtEvent;
if (click) {
var activePoints = click.call(chart, evt);
scope.click(activePoints, evt);
}
};
Finally, the hasDataSets method needs to be updated:
function hasDataSets(type) {
return ['Line', 'Bar', 'Radar', 'StackedBar'].indexOf(type) > -1;
}
If you'd rather not add support directly into the current set of directives, could you suggest a way of extending the existing directives to support it?
The click event doesn't apply scope changes afterwards, so any changes to data or any other scope changes don't take effect. The easy fix for this issue to add a call to scope.$apply() after the call to the click event handler.
if (scope.click) {
cvs.onclick = function (evt) {
var click = chart.getPointsAtEvent || chart.getBarsAtEvent || chart.getSegmentsAtEvent;
if (click) {
var activePoints = click.call(chart, evt);
scope.click(activePoints, evt);
scope.$apply() // Add this line
}
};
}
If you'd like to me to submit a pull request or if you need any more information please let me know.
Thanks.
Comparing tooltip colors on line chart and bar chart, it seems like in line chart shown colors are taken from the line and not from the fill, but in bar chart the color seems to be taken from the fill color. Also the bars doesn't highlight when the mouse is over.
Because of all the watch, charts are getting created too many times, we should only destroy/create the chart when needed.
When dynamically updating Bar charts, the error "dataset.points is undefined" is raised.
This can be easily reproduced by changing the first chart in "charts.html" in the examples folder from "chart-line" to "chart-bar" (the one that has a timeout to update it dynamically).
See the Plnkr: http://plnkr.co/edit/6AjxKI?p=preview
Great project - I was looking at porting across from https://github.com/gonewandering/angles however our existing code sets colours on our doughnut chart based on the values (red, orange, green for scores considered bad, ok and good). We use doughnut to show a single percentage-like score by having two datasets (one is same colour as background so it looks like just the score is showing).
I can't see how to do this in your project - would be nice if it could be added. Ideally we could set classes instead of the actual colours, but whatever works.
When I set the legend option to false, legend is still shown below charts, after debugging the code, I found the scope.legend value is "false" (a string instead of a boolean value), so the if condition will be true: if (scope.legend) setLegend(elem, chart), I'm using the AngularJS v1.3.4.
I would like to specify the color of a segment in a Doughnut chart based on the type of data. Any direction is much appreciated. Thank you.
Name of the module in the library and in the documentation are different.
library
chart.js
documentation
angular-chart.js - Installation
Hi I'm trying to create Bar-Charts using ng-repeat, but the data is not getting rendered. Please Help.
Plunker : http://plnkr.co/edit/DAUkixDSOvjBKGhYjAu3?p=preview
Hi,
Here's the code i'm using.
$scope.ejecutarBusqueda = function ()
{
var promise = $http.get(url + "opt=call_log_stats&data=" + angular.toJson($scope.filtro));
promise.success(function (response)
{
var app = angular.element($("#LineCtrl")).scope();
app.series = response["dates"];
app.data = response["series"];
});
};
The data changes perfectly but the series' names remain the same if previous length is the same, it only changes when the array length changes, in this case if response["dates"] decrease or increase its contents.
Chart doesn't work with only one series constantly gives errors.
$timeout(function () {
$scope.labels = ['2006', '2007', '2008', '2009', '2010', '2011', '2012'];
$scope.series = ['Series A'];
$scope.data = [
[65, 59, 80, 81, 56, 55, 40]
];
}, 1000);
For the bar chart example at http://jtblin.github.io/angular-chart.js/ this code is being displayed:
$scope.labels = ['2006', '2007', '2008', '2009', '2010', '2011', '2012'];
$scope.data = [
{"Series A": [65, 59, 80, 81, 56, 55, 40]},
{"Series B": [28, 48, 40, 19, 86, 27, 90]}
];
it does not work. In the source code you use this code which is working:
$scope.labels = ['2006', '2007', '2008', '2009', '2010', '2011', '2012'];
$scope.series = ['Series A', 'Series B'];
$scope.data = [
[65, 59, 80, 81, 56, 55, 40],
[28, 48, 40, 19, 86, 27, 90]
];
As per the bower guidelines: https://github.com/bower/bower.json-spec#main
Use case is when using tools to concatenate all bower dependencies in one js/css file, you can then choose to leave as is or minify all the libraries yourself.
hello, i want to change the label of the chart using jquery.
i already did this
$.get('/report', function(data) {
$timeout(function () {
$scope.data = data;
$scope.series = ['test', 'test2'];
}, 200);
});
but it's not working..
Wondering if it possible to get a reference to the created ChartJS chart object created by the directive from inside a controller? I basically need to further customize the chart and or call some of the chart methods. Is there any sort of event that can be tied into that occurs after the chart is created? Any help or ideas would be greatly appreciated - thanks!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.