Why isn't my spline chart showing when using combo charts? - angularjs

So I'm using Highcharts-ng with Angular to create a combination chart of a spline chart and a column chart formatted as a histogram to show trends.
The way it works is that the on the load of the page, I only see the histogram, and not the spline. Changing the order does nothing.
It looks as though if I have the spline chart data hard-coded it shows, but using the program to add in the data after a service is called in does not work.
(function() {
'use strict';
angular
.module('app.widgets')
.directive('trends', trends);
trends.$inject = ['ResultsService'];
/* #ngInject */
function trends() {
var ddo = {
restrict: 'EA',
templateUrl: 'app/widgets/trends/trends.directive.html',
link: link,
scope: {
data: '=',
config: '='
},
controller: controller,
controllerAs: 'vm',
bindToController: true
};
return ddo;
function link(scope, element, attrs) {
}
function controller($scope, ResultsService) {
var vm = this;
var parent = $scope.widgetController;
var size = {
height: angular.element('li.widget-border.ng-scope.gridster-item')[1].style.height - 20 ,
width: angular.element('li.widget-border.ng-scope.gridster-item')[1].style.width - 20
};
vm.histogram = {
chart: {
zoomType: 'xy'
},
title: {
text: 'Average Monthly Weather Data for Tokyo'
},
subtitle: {
text: 'Source: WorldClimate.com'
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
crosshair: true
},
yAxis: { // Primary yAxis
labels: {
style: {
color: Highcharts.getOptions().colors[2]
}
},
title: {
text: 'Events',
style: {
color: Highcharts.getOptions().colors[2]
}
}
},
tooltip: {
shared: true
},
legend: {
layout: 'vertical',
align: 'left',
x: 80,
verticalAlign: 'top',
y: 55,
floating: true,
backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColor) || '#FFFFFF'
},
series: [{
name: 'Average',
type: 'spline',
data: [],
marker: {
enabled: true
}
}],
loading: false,
useHighStocks: false,
size: {
height: size.height,
width: size.width
}
};
vm.processChartData = processChartData;
vm.data = {
charts: {
}
};
ResultsService.getData().then(function(res) {
vm.data = {
charts: {}
};
vm.data.charts = processChartData(res);
vm.histogram.xAxis.categories = [];
vm.histogram.series.push ({
name: 'Events per month',
type: 'column',
data: [],
marker: {
enabled: true
}
});
console.log(vm.histogram.series);
angular.forEach(vm.data.charts.months, function(v,k){
vm.histogram.xAxis.categories.push(k);
vm.histogram.series[1].data.push(v);
});
vm.histogram.options = {
plotOptions: {
}
};
vm.histogram.options.plotOptions = {
column: {
borderWidth: 0.5,
groupPadding: 0,
shadow: true
},
};
console.log(vm.data.charts.months);
vm.histogram.xAxis.categories.sort();
var average = calculateAverage();
vm.histogram.series[0].data=average;
console.log(vm.histogram.series);
});
function swap(pos1, pos2){
var temp = vm.histogram.series[pos1];
vm.histogram.series[pos1] = vm.histogram.series[pos2];
vm.histogram.series[pos2] = temp;
}
function calculateAverage() {
var averageArray = [];
var total = 0;
angular.forEach(vm.data.charts.months, function(v,k){
console.log(v);
total += v;
});
console.log((total/12.0).toFixed(2));
var average = (total/12.0).toFixed(2);
angular.forEach(vm.histogram.xAxis.categories, function(v,k){
averageArray.push(average);
});
return averageArray;
}
function processChartData(data) {
var output = {};
var months = {};
var dayOfWeek = {};
var epoch = {};
angular.forEach(data, function (value, index) {
// by month
if (!months[value.eventDate.month]) {
months[value.eventDate.month] = 1;
}
months[value.eventDate.month] += 1;
// by day of week
if (!dayOfWeek[value.eventDate.dayOfWeek]) {
dayOfWeek[value.eventDate.dayOfWeek] = 1;
}
dayOfWeek[value.eventDate.dayOfWeek] += 1;
// by day
if (!epoch[value.eventDate.epoch]) {
epoch[value.eventDate.epoch] = 1;
}
epoch[value.eventDate.epoch] += 1;
});
output.months = months;
output.dayOfWeek = dayOfWeek;
return output;
}
$scope.$on('gridster-item-resized', function(item){
var element = angular.element(item.targetScope.gridsterItem.$element[0]);
vm.histogram.size = {
height: element.height()-35,
width: element.width()
};
$scope.$broadcast('highchartsng.reflow');
});
}
}
})();
The chart on the webpage looks like this with the given code!
As you can see, it shows the legend with the spline, but the spline doesn't show up. I can't figure out why.

Your calculateAverage() function returns an array of strings since .toFixed(2) returns a string. Make sure it's an array of numbers. Convert average to a number with average = parseFloat(average) for example.

Related

How to create dynamic update spline Highcharts chart?

I'm scratching my head for few days with no luck.
I would like to create Highcharts chart that shows data from my database.
I did some charts without problem, but I'm stuck on chart that shows some points (20 or more) and scrolls spline chart to the left showing new data.
I have created two arrays jfDatumi (containing times in format hh:mm from database) (12:10) and jfTempOuts containing temperature values (-2.3…).
Now I want to show those data on chart that moves every second adding new point (time, temperature) but showing only 20 points at the time.
When it comes to the end of an array I would like chart to start over from first point.
It's like this chart https://www.highcharts.com/demo/dynamic-update but I want X axis to show my times from my array (jfDatumi) not current time (without var x = (new Date()).getTime())
Can anyone please help me? I'm pulling my hair out because of this.
Below is my current code.
$(function ()
{
$(document).ready(function ()
{
Highcharts.setOptions(
{
global:
{
useUTC: false,
}
});
$('#test').highcharts(
{
credits:
{
text: 'By: http://amicus.ba',
href: 'http://amicus.ba'
},
chart:
{
type: 'spline',
animation: Highcharts.svg, // Ne animiraj u starom IE
marginRight: 1,
events:
{
load: function ()
{
// Postaviti update grafikona svake sekunde
var series = this.series[0];
setInterval(function ()
{
var x = jfDatumi, // Trenutno vrijeme
//var x = new Date(), // current time
//x=jfDatumi,
//var x = (new Date()).getTime(),
y = jfTempOuts;
series.addPoint([x, y], true, true);
}, 1500);
}
}
},
title:
{
text: 'Test Vanjska temperatura [°C]'
},
xAxis:
{
type: 'datetime',
categories: jfDatumi,
minRange: 1,
title:
{
text: 'Vrijeme'
},
tickPixelInterval: 1,
},
yAxis:
{
minRange: 0,
title:
{
text: '[°C]'
},
plotLines: [
{
value: 0,
width: 2,
color: '#808080'
}]
},
tooltip:
{
formatter: function ()
{
return '<b>' + this.series.name + '</b><br/>' +
Highcharts.numberFormat(this.y, 2) + ' [°C]';
}
},
legend:
{
enabled: false
},
exporting:
{
enabled: false
},
series: [
{
name: 'Vanjska temperatura',
//data: (jfTempOuts)
data: (function () {
// generate an array of random data
var data = [],
time = jfDatumi,
i;
for (i = 0; i <= 20; i += 1) {
data.push([
time,
jfTempOuts
]);
}
return data;
}())
}]
});
});
});
At this time, i have my times from jfDatumi, but NO temperature values from jfTempOuts.
I have found solution by myself.
Here is code that works for me:
// Animirani grafikon vanjske temperature
$(function ()
{
$(document).ready(function ()
{
Highcharts.setOptions(
{
global:
{
useUTC: false,
}
});
$('#vanjskaTemp').highcharts(
{
credits:
{
text: 'By: http://amicus.ba',
href: 'http://amicus.ba'
},
chart:
{
type: 'spline',
animation: Highcharts.svg, // Ne animiraj u starom IE
marginRight: 1,
events:
{
load: function ()
{
// Postaviti update grafikona po podešenom intervalu
var series = this.series[0];
var br=20; // Start brojača za indeksiranje niza temperatura (podešeno u: for (i = 0; i <= 20; i += 1))
setInterval(function ()
{
br=br+1; // Brojač za indeksiranje niza temperatura
// Zaustavljanje skrolovanja ako je dostignut kraj niza jfTempOuts
if (br<=jfTempOuts.length-1)
{
var x = jfSamoVrijeme; // Vrijeme za X osu (zaustavi se osa ako se ne očitava)
y = jfTempOuts[br]; // Vrijednosti za Y osu (Vanjske temperature)
series.addPoint([x, y], true, true);
}
else
{
//document.write("BR:<li>"+br+"</li>");
}
}, 1500);
}
}
},
title:
{
text: 'Vanjska temperatura [°C]'
},
xAxis:
{
type: 'datetime',
categories: jfSamoVrijeme,
minRange: 1,
title:
{
text: 'Vrijeme'
},
tickPixelInterval: 1,
},
yAxis:
{
minRange: 0,
title:
{
text: 'Vanjska temperatura [°C]'
},
plotLines: [
{
value: 0,
width: 0.5,
color: '#808080'
}]
},
tooltip:
{
formatter: function ()
{
return '<b>' + this.series.name + '</b><br/>' +
Highcharts.numberFormat(this.y, 2) + ' [°C]';
}
},
legend:
{
enabled: false
},
exporting:
{
enabled: false
},
series: [
{
name: 'Vanjska temperatura',
data: (function () {
var data = [],
time = jfSamoVrijeme,
i;
for (i = 0; i <= 20; i += 1) {
data.push([
time,
jfTempOuts
]);
}
return data;
}())
}]
});
});
});
// Kraj animiranog grafikona vanjske temperature
Only problem I have now is that I CAN'T show first 20 points, but not so important.
I will find solution for that problem too.
My chart

How to drilldown to third level when its data is determined by second's click event?

So, I have been trying to use drill down to multiple levels, problem I am facing is that I couldn't drill down to the third level because the data will be fetched by ajax upon second drilldown's selection.
for example, refer to this link:
https://codepen.io/ajaymalhotra15/pen/aZpxXq
drilldown example
Here, the third level is possible because he has the data already, but mine will be depended on seconds selection.
So, how to make this happen, where am I supposed to call the ajax request and set the drill down series data dynamically?
EDIT:
Highcharts.chart("energy_chart", {
chart: {
type: "column",
spacingBottom: 15,
spacingTop: 10,
spacingLeft: 10,
spacingRight: 10,
backgroundColor: "#f2f2f2",
events: {
load: function() {
var fin = new Date();
var finDate = fin.getDate();
var finMonth = fin.getMonth();
var finYear = fin.getFullYear();
var ini = new Date();
ini.setFullYear(ini.getFullYear() - 1);
var iniDate = ini.getDate();
var iniMonth = ini.getMonth();
var iniYear = ini.getFullYear();
if (this.yAxis[0].dataMax == 0) {
this.yAxis[0].setExtremes(null, 1);
}
//this.yAxis.set
this.xAxis[0].setExtremes(
Date.UTC(iniYear, iniMonth, iniDate),
Date.UTC(finYear, finMonth, finDate)
);
},
drilldown: function(e) {
var charts_this = this;
var inidrillDate = new Date(e.point.x);
setTimeout(function() {
inidrillDate.setDate(0);
inidrillDate.setMonth(inidrillDate.getMonth());
var DateinidrillDate = inidrillDate.getDate();
var MonthinidrillDate = inidrillDate.getMonth();
var YearinidrillDate = inidrillDate.getFullYear();
var findrillDate = inidrillDate;
findrillDate.setMonth(findrillDate.getMonth() + 1);
findrillDate.setDate(findrillDate.getDate() - 1);
var DatefindrillDate = findrillDate.getDate();
var MonthfindrillDate = findrillDate.getMonth();
var YearfindrillDate = findrillDate.getFullYear();
charts_this.xAxis[0].setExtremes(
Date.UTC(
YearinidrillDate,
MonthinidrillDate,
DateinidrillDate
),
Date.UTC(
YearfindrillDate,
MonthfindrillDate,
DatefindrillDate
)
);
if (charts_this.yAxis[0].dataMax === 0) {
charts_this.yAxis[0].setExtremes(null, 1);
}
}, 0);
}
}
},
title: {
text: '<p className="energy_gen">Energy Generated</p>'
},
exporting: { enabled: false },
xAxis: {
type: "datetime",
labels: {
step: 1
},
dateTimeLabelFormats: {
day: "%e"
}
},
yAxis: {
title: {
text: "kWh"
}
},
credits: {
enabled: false
},
plotOptions: {
series: {
cursor: "pointer",
dataLabels: {
enabled: true,
format: "{point.y}"
},
color: "#fcd562",
point:{
events:{
click:function(event){
if(this.options!=null){
var dayOfYear=new Date(this.x).getFullYear() +"-"+(new Date(this.x).getMonth()+1)+"-"+new Date(this.x).getDate();
var formatted_date = new Date(this.x).getDate() + " " + months[(new Date(this.x).getMonth())] +" "+ new Date(this.x).getFullYear();
// document.getElementById('chart_date_id').innerHTML = formatted_date; //setting modal title with current date
$('#container').bind('mousemove touchmove touchstart', function (e) {
var chart,
point,
i,
event;
var sync_charts = $('.chart');
for (i = 0; i < sync_charts.length; i = i + 1) {
var chart_1 = sync_charts[i];
var chart_2 = chart_1.getAttribute('data-highcharts-chart');
chart=Highcharts.charts[chart_2];
event = chart.pointer.normalize(e.originalEvent);
point = chart.series[0].searchPoint(event, true);
if (point) {
point.highlight(e);
}
}
});
Highcharts.Pointer.prototype.reset = function () {
return undefined;
};
Highcharts.Point.prototype.highlight = function (event) {
event = this.series.chart.pointer.normalize(event);
this.onMouseOver(); // Show the hover marker
this.series.chart.tooltip.refresh(this); // Show the tooltip
this.series.chart.xAxis[0].drawCrosshair(event, this); // Show the crosshair
};
function syncExtremes(e) {
var thisChart = this.chart;
if (e.trigger !== 'syncExtremes') { // Prevent feedback loop
Highcharts.each(Highcharts.charts, function (chart) {
if (chart !== thisChart) {
if (chart.xAxis[0].setExtremes) { // It is null while updating
chart.xAxis[0].setExtremes(
e.min,
e.max,
undefined,
false,
{ trigger: 'syncExtremes' }
);
}
}
});
}
}
axios({
url: config.fvcstat,
method: "POST",
data: {
"customerId":self.props.location.state.detail.customerId,"rmsVendorId":self.props.location.state.detail.rmsVendorId,
"date":dayOfYear,
"powerType":self.props.location.state.detail.powerType
},
headers: {
"Content-Type": "application/json"
}
}).then((res)=>{
let activity = fvc.data;
if($('.chart')){
$('.chart').remove();
}
$.each(activity.datasets, function (i, dataset) {
console.log(1)
var chartDiv = document.createElement('div');
chartDiv.className = 'chart';
document.getElementById('container').appendChild(chartDiv);
Highcharts.chart(chartDiv,{
chart: {
},
plotOptions: {
series: {
marker:{
enabled:false
}
}
},
exporting: { enabled: false },
title: {
text: dataset.name,
align: 'left',
margin: 0,
x: 30
},
credits: {
enabled: false
},
legend: {
enabled: false
},
xAxis: {
crosshair:{ width: 3},
events: {
setExtremes: syncExtremes
},
labels: {
format: '{value}'
},categories: activity.xData
},
yAxis: {
title: {
text: null
}
},
series: [{
data: dataset
}],
tooltip: {
positioner: function () {
return {
x: this.chart.chartWidth - this.label.width,
y: 10 // align to title
};
},
borderWidth: 0,
backgroundColor: 'none',
pointFormat: '{point.y}',
headerFormat: '',
shadow: false,
style: {
fontSize: '18px'
},
valueDecimals: dataset.valueDecimals
},
series: [{
data: dataset.data,
name: dataset.name,
type: dataset.type,
color: Highcharts.getOptions().colors[i],
fillOpacity: 0.3,
tooltip: {
valueSuffix: ' ' + dataset.unit
}
}]
});
});
})
}
}
}
}
}
},
tooltip: {
formatter: function() {
if (this.point.options.drilldown) {
return (
"Energy generated: <b> " +
this.y +
"</b> kWh " +
"<br>" +
Highcharts.dateFormat("%b %Y", new Date(this.x))
);
} else {
return (
"Energy generated: <b> " +
this.y +
"</b> kWh " +
"<br>" +
Highcharts.dateFormat("%e %b %Y", new Date(this.x))
);
}
}
},
series: [{'data':obj.data,'name':obj.name,"color":"#4848d3"}],
drilldown: {
series: obj.data
}
});
So, here if you notice in plotoptions i am trying to create a whole new chart which is a synced line charts showing frquency, voltage and current.
But, i am guessing my approach is not correct as i am plotting a new highchart.
So, how do i make this synced line chart part of my drilldown.
let me know if you require any help in understanding.
I will suggest first minimize the plotoption. Then expand for further fuck up :P
Thanks.
You can put all your logic to get the third level data and to create a drilldown series in drilldown event:
chart: {
type: 'column',
events: {
drilldown: function(e) {
if (!thirdLevel.length) {
// get data
}
if (!e.seriesOptions) {
var chart = this,
drilldowns = {
'Animals': {
name: 'Animals',
data: [
['Cows', 2],
['Sheep', 3]
]
},
'Fruits': {
name: 'Fruits',
data: [
['Apples', 5],
['Oranges', 7],
['Bananas', 2]
]
},
'Cars': {
name: 'Cars',
data: [
['Toyota', 1],
['Volkswagen', 2],
['Opel', 5]
]
}
},
series = drilldowns[e.point.name];
chart.addSingleSeriesAsDrilldown(e.point, series);
chart.applyDrilldown();
}
}
}
}
Live demo : http://jsfiddle.net/BlackLabel/86v3L4ft/
API Reference: https://api.highcharts.com/highcharts/chart.events.drilldown

Filter by range date for angular-nvd3 directive?

I create an nvd3 graph with the angular-nvd3 directive:
<nvd3 id="analytics-community" options="vm.community.options" data="vm.community.data" config="vm.graphConfig" class="with-3d-shadow with-transitions"></nvd3>
However it does not seem possible to filter the data attribute using |filter:something as it ends up looping infinitely and angular breaks with infinite loop error.
Graph options are setup with:
vm.graphOptions = {
chart: {
type: 'lineChart',
height: 300,
margin : {
top: 50,
right: 50,
bottom: 50,
left: 50
},
x: function(d) {
return d3.time.format.iso.parse(d.key);
},
y: function(d) {
return d.value;
},
useInteractiveGuideline: false,
dispatch: {
stateChange: function(e) { },
changeState: function(e) { },
tooltipShow: function(e) { },
tooltipHide: function(e) { }
},
xScale: d3.time.scale(),
xAxis: {
axisLabel: 'Date',
tickFormat: function (d) {
return d3.time.format('%b %Y')(new Date(d));
}
},
yAxis: {
axisLabel: 'Count',
tickFormat: function(d) {
return d;
}
}
}
};
And the data is set-up with:
vm.community.data = [
{
key: 'Members',
values: vm.statsModel.registeredMembers
},
{
key: 'Students',
values: vm.statsModel.registeredStudents
},
{
key: 'Alumni',
values: vm.statsModel.registeredAlumni
}
];
Where vm.statsModel.registeredMembers is like:
[
{
key: "2015-06-15",
value: 458
},
{
key: "2015-06-23",
value: 459
},
{
key: "2015-06-27",
value: 460
}
]
Any ideas?
Setting the xDomain in vm.graphOptions.chart worked:
vm.graphOptions.chart.xDomain = [new Date(vm.selectedItem.date), dateToday]
Where vm.selectedItem.date = new Date().setMonth(new Date().getMonth() - 6) for 6 months ago... and dateToday = new Date()
So I just $watch for changes on vm.selectedItem which changes with a select box and update xDomain.

Sending a value from html to controller in angularjs. Issue with scope?

I have have a web app set up to display charts using the highcharts-ng directive.
I have the same type of chart with the same series data displaying on multiple views. The only difference between the charts is the height value which I would like to be able to set when I initialise my chart in my html markup.
This is how I have set things up:
The highcharts-ng directive is installed through bower.
I initialise my chart as follows:
<div ng-controller="AgeChartController" >
<highchart diagramHeight="500" id="{{link + '_chart'}}" config="ageChartConfig">
</highchart></div>
In my AgeChartController I do the following:
Pull data from JSON file
Get chart height attribute from diagramHeight
Construct Highcharts options object and send diagramHeight to this options object
angular.module('socialDashboard')
.controller('AgeChartController', function ($scope, $http, $attrs) {
var seventeenCount = 0;
var eighteenCount = 0;
var twentyFiveCount = 0;
var thirtyFiveCount = 0;
var chartHeight = 0;
var posts = [];
$http.get('dummy_content.json')
.then(function(res){
posts = res.data;
for (var i = 0; i < posts.length; i++) {
if (posts[i].age <= 17) {
seventeenCount++;
}
else if ((posts[i].age >= 18) && (posts[i].age <= 24)) {
eighteenCount++;
}
else if ((posts[i].age >= 25) && (posts[i].age <= 34)) {
twentyFiveCount++;
}
else if (posts[i].age >= 35) {
thirtyFiveCount++;
}
}
chartHeight = $attrs.diagramHeight;
$scope.ageChartConfig = {
options: {
chart: {
type: 'bar',
height: chartHeight,
backgroundColor: false
}
},
title: {
text: false
},
xAxis: {
categories: ['< 17', '18 - 24', '25 - 34', '> 35']
},
yAxis: {
gridLineWidth: 0,
title: {
text: 'Post count'
},
labels:
{
enabled: false
}
},
plotOptions: {
series: {
dataLabels: {
enabled: true
}
}
},
legend: {
layout: 'vertical',
floating: true,
backgroundColor: '#FFFFFF',
align: 'right',
verticalAlign: 'top',
y: 60,
x: -60
},
tooltip: {
formatter: function () {
return '<b>' + this.series.name + '</b><br/>' +
this.x + ': ' + this.y;
}
},
navigation: {
buttonOptions: {
enabled: false
}
},
series: [{
name: 'Post count',
showInLegend: false,
data: [{
color: '#9365b8',
y: seventeenCount
}, {
color: '#2c82c9',
y: eighteenCount
}, {
color: '#41a85f',
y: twentyFiveCount
}, {
color: '#fac51c',
y: thirtyFiveCount
}]
}],
loading: false
};
});
});
However when I declare my chart elsewhere with diagramHeight set to 200:
<div ng-controller="AgeChartController">
<highchart diagramHeight="200" id="{{link + '_chart'}}" config="ageChartConfig">
</highchart></div>
Only one of the two values get pulled and my chart is set the same across all charts (height 500). Why is this? Does this have something to do with my scope? I'm pretty new to angular and still getting my head around scope.
You should use angular factory to configure chart
app.factory('chartname', function () {
var agechart={ // your all chart option here
.
.
}
return agechart;
});
You can use above factory in any controller now just like
app.controller("controllername",function(chartname){
$scope.ageChartConfig=chartname;
});

Render Two charts separate charts using angular js directives

I am trying to render two seperate charts using seperate directives for each charts, since the data is different ( also I am no expert in AngualrJs ). But only one chart was rendering to view. Please can someone help with what I have to do so that I can see both charts.Thanks.
'use strict';
angular.module('AngularApp',['AngularApp.directives']);
/*Controllers*/
var HighChartController = function HighChartController($scope) {
$scope.templateUrl = '/_layouts/AngularControls/TestController/View2.html';
$scope.type = '107';
$scope.initData = function () {
$scope.data = [
['Fire', 47.0],
['Wind', 33.0],
['Natural', 20.0]
];
}
$scope.loadChart = function () {
$scope.data1 = [60];
$scope.data2 = [40];
}
$scope.initData();
$scope.loadChart();
}
/* Directives */
angular.module('AngularApp.directives', []).
directive('drawPieChart', function () {
return function (scope, element, attrs) {
var container = $(element).attr("id");
scope.$watch('data', function () {
console.log('data');
drawPlot();
}, true);
var drawPlot = function () {
var chart;
chart = new Highcharts.Chart({
chart: {
renderTo: container,
margin: [0, 0, 0, 0],
spacingTop: 0,
spacingBottom: 0,
spacingLeft: 0,
spacingRight: 0
},
title: {
text: null
},
credits: {
enabled: false
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage}%</b>',
percentageDecimals: 1
},
plotOptions: {
pie: {
size: '100%',
dataLabels: {
enabled: false
}
}
},
series: [{
type: 'pie',
name: 'Browser share',
data: scope.data
}]
});
}
}
});
angular.module('AngularApp.directives', []).
directive('drawBarChart', function () {
return function (scope, element, attrs) {
var container = $(element).attr("id");
scope.$watch('data', function () {
drawPlot();
}, true);
var drawPlot = function () {
var chart = new Highcharts.Chart({
chart: {
type: 'column',
renderTo: container,
marginRight: 50,
events: {
}
},
title: {
text: 'Test Scores',
style: {
color: 'black',
fontWeight: '700',
fontFamily: 'Arial',
fontSize: 20
}
},
xAxis: {
categories: [],
title: {
text: null
},
gridLineWidth: 0,
minorGridLineWidth: 0,
labels: {
style: {
color: 'black',
fontWeight: '700',
fontFamily: 'Arial',
fontSize: 11,
width: 90
}
}
},
yAxis: {
min: 0,
max: 100,
gridLineWidth: 0,
minorGridLineWidth: 0,
labels: {
enabled: false
},
title: {
text: null
}
},
tooltip: {
valueSuffix: ' million'
},
plotOptions: {
series: {
stacking: 'percent'
},
bar: {
dataLabels: {
enabled: false
}
}
},
legend: {
enabled: false,
layout: 'vertical',
align: 'right',
verticalAlign: 'bottom',
x: -40,
y: 100,
floating: true,
borderWidth: 1,
backgroundColor: '#FFFFFF',
shadow: true
},
credits: {
enabled: false
},
series: [{
name: 'null',
data: scope.data2,
borderRadius: 0,
color: "gray"
}, {
name: 'Values',
data: scope.data1,
color: "green",
borderRadius: 0
}]
});
}
}
});
Here is the markup
<div id="barChartContainer" draw-bar-chart =""></div>
</div>
<div id="pieChartContainer" draw-pie-chart="">
</div>
As Oledje mentioned, you declared the AngularApp.directives twice, but there was also an issue with how you are actually referencing the data for the charts in the directive code. I would recommended that you create an isolated scope for each directive and map the properties for the chart data in the scope definition.
So instead of
.directive('drawPieChart', function () {
return function (scope, element, attrs) {
var container = $(element).attr("id");
scope.$watch('data', function () {
console.log('data');
drawPlot();
}, true);
var drawPlot = function () {...};
};
}
You should do
.directive('drawPieChart', function () {
return {
restrict: 'E',
scope: {
chartData: "="
},
link: function (scope, element, attrs) {
scope.$watch('chartData', function (newVal,oldVal) {
if (newVal) {
drawPlot();
}
}, true);
var drawPlot = function () {
// use scope.chartData for the data
};
}
};
}
And then you also need the corresponding HTML
<draw-pie-chart chart-data="pieChartData">
And in your Controller do $scope.pieChartData=[];
Here is a jsFiddle with all of my changes: http://jsfiddle.net/callado4/9far5/5/ (look at the history to see how I progressed)
I think that your problem is that you declare a module twice.
try write not
angular.module('AngularApp.directives', []).
directive('drawPieChart'...)
angular.module('AngularApp.directives', []).
directive('drawBarChart'...)
but
angular.module('AngularApp.directives', []).
directive('drawPieChart'...).
directive('drawBarChart'...)
or
var app = angular.module('AngularApp.directives', []);
app.controller('Ctrl', ...)
app.directive('drawPieChart'...);
app.directive('drawBarChart'...);
Examples:
http://jsfiddle.net/GDQ6B/2/
http://jsfiddle.net/EYz9U/1/

Resources