Is it possible to do a custom rendering with highchart-ng?! - angularjs

I tried to use Highcharts Renderer to create my own custom shapes.
Unfortunately, I cannot find a way to invoke those methods.
Is it even possible to use Highcharts methods? with highcharts-ng?!
My Plunk
My code:
var myapp = angular.module('myapp', ["highcharts-ng"]);
myapp.controller('myctrl', function ($scope) {
$scope.chartDonut = {
options: {
chart: {
type: 'pie',
},
colors: [
'#FFFFFF',
'#AA4643',
],
credits: {
enabled: false
},
legend: {
borderWidth: 0
},
plotOptions: {
pie: {
borderWidth: 0.2,
borderColor: '#000000',
}
}
},
title: {
text: 'Browser market share, April, 2011'
},
backgroundColor: '#cccccc',
tooltip: {
formatter: function() {
return '<b>'+ this.point.name +'</b>: '+ this.y +' %';
}
},
series: [{
name: 'Browsers',
data: [{
name: 'MATCHED',
y: 25
}, {
name: 'UNMATCHED',
y: 50,
color: {
pattern: 'http://highcharts.com/demo/gfx/pattern1.png',
width: 6,
height: 6
}
}],
size: '60%',
innerSize: '56%',
showInLegend: false,
dataLabels: {
enabled: true,
connectorWidth: 0,
connectorPadding: 0,
useHTML: true,
x: 20,
formatter: function() {
if (this.point.name === 'UNMATCHED')
return '<div id="donut_unmatched">'
+ '<div id="unmatched_num">' + this.y + '</div>'
+ '<div id="unmatched_txt">' + this.point.name + '</div>'
+ '</div>';
}
}
}]
};
});

This can be done with current version, while documentation is not clear.
In source code, highcharts constructor is called:
new Highcharts.Chart(mergedOptions, func)
The second parameter is a callback when highcharts initialization is finished:
http://api.highcharts.com/highcharts#Highcharts.Chart (it does not explain its arguments)
We can get the chart object from the 1st argument of this function. Add following code to your chart config object:
func: function(chart) {
$scope.chartObj = chart;
}
Then you can use it in your view or code (for any API calls):
<span>{{chartObj.renderer.height}}</span>
$scope.chartObj.renderer.circle(...);
$scope.chartObj.getSelectedPoints();
As an example I forked the original plunk here:
http://plnkr.co/edit/6WvHEjJfr4pGqd2OvPKF?p=preview

Author here. At the moment it is not possible to do this. Pull requests gladly accepted. I'll probably add it myself in the near future.
See here to track changes: https://github.com/pablojim/highcharts-ng/issues/97

i can't find the answer either,but i've got a resolution, which is invoke the renderer in the formatter of xAxis label formatter function, and it works..

Related

how to add data from mongodb database to highchart-ng

This is the highchart code in angular controller
I am using charts for the first time in angularjs.I want to show data from my mongodb database like on x-axis all the names of tasks and on y-axis the total time required by that particular task to complete i.e- Total Duration.
I have added static data for the html to look like the attached image.
I am developing a project using MEAN Stack.I want to how know how do i add the data i get from database to highcharts.
This is how the output should look without statically giving data:
var tasks = ['Task1','Task2','Task3' ]
var res = [26,61,1]
$scope.chartConfig = {
chart: {
type: 'column'
},
title: {
text: 'Task Duration'
},
xAxis: {
categories: tasks,
crosshair: true
},
yAxis: {
min: 0,
title: {
text: 'Task Duration (Hrs)'
}
},
tooltip: {
headerFormat: '<span style="font-size:10px">{point.key}</span>
<table>',
pointFormat: '<tr><td style="color:{series.color};padding:0">
{series.name}: </td>' +
'<td style="padding:0"><b>{point.y:.1f} mm</b></td></tr>',
footerFormat: '</table>',
shared: true,
useHTML: true
},
plotOptions: {
column: {
pointPadding: 0.2,
borderWidth: 0
}
},
series: [{
name: 'Tasks',
data: res
}]
}

Highchart: How to change y-axis title text inside angularjs controller?

I have created highchart directive
App.directive('hcChart', function ($parse) {
'use strict';
return {
restrict: 'E',
replace: true
,
template: '<div><div class="chart"></div></div></div>',
link: function (scope, element, attrs) {
attrs.chart = new Highcharts.chart(element[0], {
xAxis: {
title: {
text: "Date"
},
type: 'datetime'
// labels: {
// step: 24
// }
// ,
// tickInterval: 2
},
yAxis: {
title: {
text: "Value"
}
},
dataLabels: {
enabled: true
}
,
title: {
text: ""
},
chart: {
opacity: 0.51,
backgroundColor: "white",
// plotBackgroundColor: 'rgba(0, 0, 0, 0.7)',
plotBackgroundColor: 'white',
// width: 1600,
height: 800,
zoomType: 'x',
resetZoomButton: {
position: {
x: -140,
y: 0
}
}
},
tooltip: {
crosshairs: {
width: 3,
color: 'black',
dashStyle: 'shortdot'
}
how to change y-axis title text inside controller.
As i want to show different unit for different selection.
inside controller i'm using $scope.myseries for data and $scope.categories for x-axis date time.
html code
<hc-chart id="container" categories="{{myCategories}}" series="{{mySeries}}">Placeholder for generic chart </hc-chart>
how to use $scope to update y-axis?
i tried using
$scope.yAxis[0].setTitle({text : "abc"})
but its throwing errror. not defined property.
any help please!
To change yAxis title inside angularjs controller, we need to set its property:
Highcharts.charts[0].yAxis[0].setTitle({
text: $scope.NAME
});

What option controls the linewithFocusChart focus area (Angular-nvD3)?

I am trying to modify the linewithFocusChart's focus properties (the focus being the small navigable viewport beneath the main chart) using the focus options (focusEnable, focusHeight, etc). These options are not having any affect on my graph though. I am using Angular-nvD3 directives. Any ideas?
HTML
<nvd3 options="options" data="data" config="config"></nvd3>
Angular controller
$scope.options = {
chart: {
type: 'lineWithFocusChart',
height: 350,
margin : {
"top": 20,
"right": 40,
"bottom": 60,
"left": 40
},
focusEnable:true,
focusHeight: 80,
focusShowAxisX: true,
focusShowAxisY: false,
brushExtent: [new Date(1427846400000), new Date(1435708800000)],
xAxis: {
axisLabel: '',
tickFormat: function(d){
return d3.time.format('%b-%Y')(
new Date(d))
}
},
x2Axis: {
tickFormat: function(d){
return d3.time.format('%b/%Y')(
new Date(d))
}
},
yAxis: {
axisLabel: '',
tickFormat: function(d){
return d3.format(',d')(d);
},
rotateYLabel: false
},
y2Axis: {
tickFormat: function(d){
return d3.format(',')(d);
}
},
tooltip: {
distance: 0,
duration: 100,
hideDelay: 100
},
tooltipContent: function (key, x, y, e) {
return '<h3>' + e.point.y + '</h3>' +
'<p>' + x + '</p>';
}
}
};
From a quick look at the source code, the option you are looking for is focusHeight.
{
"chart": {
"type": "linePlusBarChart",
"height": 500,
"margin": {
"top": 30,
"right": 75,
"bottom": 50,
"left": 75
},
"bars": {
"forceY": [
0
]
},
"bars2": {
"forceY": [
0
]
},
"color": [
"#2ca02c",
"darkred"
],
"xAxis": {
"axisLabel": "X Axis"
},
"x2Axis": {
"showMaxMin": false
},
"y1Axis": {
"axisLabel": "Y1 Axis"
},
"y2Axis": {
"axisLabel": "Y2 Axis"
},
"y3Axis": {},
"y4Axis": {},
"transitionDuration": 250,
"focusHeight": 300 //<-- ADD THIS
}
}
The reason the options did not work for me was because I was using an outdated version of angular-nvd3 directive -- one in which the aforementioned options were not supported. I uninstalled angular-directive, nvd3, and d3 with bower, and updated to angular-directive v1.0.0-rc2, nvd3 v1.8.1 by running the following command:
bower install angular-nvd3#1.0.0-rc.2 --save
Problem resolved!

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;
});

AngularJS : link between directive and controller

I'm trying to call a function of my directive in my controller. I would like to reshape a curve. At the moment, I can do within the Directive. But I need to outsource the call. Do you know how can I proceed?
My directive :
.directive('drawCharts', function () {
return function (scope, element, attrs) {
scope.$watch('curveArray', function () {
drawPlot();
}, true);
var drawPlot = function () {
/* Define var for interactive chart */
var tickInterval = scope.intervalMillisecond;
var typeLine = 'line';
var chart = function (curveArrayShow, typeLine, optionLineBool, yAxisCurveArrayShow, pointStart, pointEnd) {
var optionLine = { dataLabels: { enabled: optionLineBool, y: -20 }};
new Highcharts.Chart({
chart: {
pinchType: 'x',
renderTo: 'container',
type: typeLine,
backgroundColor:'rgba(255, 255, 255, 0.95)',
events: {
load: function(event) {
//alert ('Chart loaded : ' + event);
//scope.isLoading = false;
}
}
},
legend: {
enabled: false
},
title: {
text: ''
},
xAxis: [{
type: 'datetime',
labels: {
format: '{value: <b>%d/%m</b> %H:%M}',
staggerLines: 1
},
opposite: true,
plotLines: [{
color: '#FF0000', // Red
width: 2,
value: new Date().getTime() // Position, you'll have to translate this to the values on your x axis
}],
min: pointStart,
max: pointEnd,
minPadding: 0,
maxPadding: 0,
startOnTick: false, // allow to start not from tick
endOnTick: false,
tickInterval: tickInterval
}],
yAxis: yAxisCurveArrayShow,
tooltip: {
style:{ zindex: 10 },
xDateFormat: '%d/%m %H:%M',
shared: true,
},
plotOptions: {
column: { borderWidth: 1, borderColor: '#000000' },
spline: {
marker: {
radius: 4,
lineColor: '#666666',
lineWidth: 1
}
},
series: {
dataLabels: {
enabled: optionLineBool,
style: {font: 'bold 11px Arial', textShadow: '0 0 3px white, 0 0 3px white'}
},
marker: {
lineColor: null,
radius: 6,
states: {
hover: {
radius: 10
}
}
}
},
line: optionLine
},
series: curveArrayShow
}}
var pointStart = scope.intervalResearchTime.startDateTime + scope.intervalMillisecond; //remove padding that adding for serie type column
var pointEnd = scope.intervalResearchTime.endDateTime - scope.intervalMillisecond; //remove padding that adding for serie type column
chart(scope.curveArray, typeLine, false, scope.yAxisCurveArray, pointStart, pointEnd);
}
};
In my controller i need to update my chart. So i would like to call the function :
$scope.redrawCurve = function(_index) {
/* My algorithm ...... */
chart(curveArrayShow, typeLine, false, $scope.yAxisCurveArray, pointStart, pointEnd);
};
Thx,
Alex
My suggestion is to use event to notify the directive to redraw the plot, like this:
Controller:
$scope.redrawCurve = function(_index) {
/* My algorithm ...... */
$scope.$broadcast('redraw', arg1, arg2, /* other necessary arguments */);
};
Directive:
scope.$on('redraw', function(arg1, arg2, /* other necessary arguments */) {
drawPlot();
});

Resources