I am new to Angular JS and trying to render my highcharts (Basic Line) by creating a directive. Please tell me the approach I should follow here. Any help would be appreciated.
Here is my script for the highcharts:
<script type="text/javascript">
$(function () {
$('#container').highcharts({
chart: {
type: 'line',
marginRight: 130,
marginBottom: 25
},
title: {
text: 'Monthly Average Temperature',
x: -20 //center
},
subtitle: {
text: 'Source: WorldClimate.com',
x: -20
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
yAxis: {
title: {
text: 'Temperature (°C)'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
valueSuffix: '°C'
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -10,
y: 100,
borderWidth: 0
},
series: [{
name: 'Tokyo',
data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6]
}, {
name: 'New York',
data: [-0.2, 0.8, 5.7, 11.3, 17.0, 22.0, 24.8, 24.1, 20.1, 14.1, 8.6, 2.5]
}, {
name: 'Berlin',
data: [-0.9, 0.6, 3.5, 8.4, 13.5, 17.0, 18.6, 17.9, 14.3, 9.0, 3.9, 1.0]
}, {
name: 'London',
data: [3.9, 4.2, 5.7, 8.5, 11.9, 15.2, 17.0, 16.6, 14.2, 10.3, 6.6, 4.8]
}]
});
});
</script>
Example of pie chart:
http://jsfiddle.net/csTzc/
function MyCtrl($scope, limitToFilter) {
$scope.ideas = [
['ideas1', 1],
['ideas2', 8],
['ideas3', 5]
];
$scope.limitedIdeas = limitToFilter($scope.ideas, 2);
}
angular.module('myApp', [])
.directive('hcPie', function () {
return {
restrict: 'C',
replace: true,
scope: {
items: '='
},
controller: function ($scope, $element, $attrs) {
console.log(2);
},
template: '<div id="container" style="margin: 0 auto">not working</div>',
link: function (scope, element, attrs) {
console.log(3);
var chart = new Highcharts.Chart(options);
scope.$watch("items", function (newValue) {
chart.series[0].setData(newValue, true);
}, true);
}
}
});
Alternative implementation here: http://jsfiddle.net/pablojim/Cp73s/
This uses https://github.com/pablojim/highcharts-ng
This allows you to create a highchart with the below html:
<highchart id="chart1" series="chart.series" title="chart.title" options="chart.options"></highchart>
In the above case chart.series is an array of javascript objects representing the series on the chart - these take standard Highcharts options. These are then watched by angularjs for any changes.
chart.options is the highcharts initalisation options - also watched for changes. Although changes to this recreate the entire chart.
chart.title is the highcharts title object - also watched for changes.
app.directive('hcChart', function () {
return {
restrict: 'A',
template: '<div></div>',
scope: {
options: '='
},
link: function (scope , element, attribute) {
Highcharts.chart('chart', {
chartOptions: {
type: 'line'
},
title: {
text: 'Temperature data'
},
series: [{
data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
}]
});
}
}
});
<div id="chart" hc-chart>Placeholder for generic chart</div>
Make sure highchart lib is added in your index.html
Related
i have trying to create a chart like
this. I have tried with highchart.js and chart.js but result is not like expected. Is there any plugin to create a chart like this? Or any other way to stack like this in highchart.js or in chart.js? Thank you.
You can use highcharts Fixed placement columns that is inverted. Check the demo posted below.
HTML:
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container"></div>
JS:
Highcharts.chart('container', {
chart: {
type: 'column',
inverted: true
},
xAxis: {
categories: [
'Seattle HQ',
'San Francisco',
'Tokyo'
]
},
yAxis: [{
min: 0,
title: {
text: 'Employees'
}
}, {
title: {
text: 'Profit (millions)'
},
opposite: true
}],
legend: {
shadow: false
},
tooltip: {
shared: true
},
plotOptions: {
column: {
grouping: false,
shadow: false,
borderWidth: 0
}
},
series: [{
name: 'Employees',
color: 'rgba(165,170,217,1)',
data: [150, 73, 20],
pointPadding: 0,
groupPadding: 0.15,
pointPlacement: 0
}, {
name: 'Employees Optimized',
color: 'rgba(126,86,134,.9)',
data: [140, 90, 40],
pointPadding: 0.2,
pointPlacement: 0
}]
});
Demo:
https://jsfiddle.net/BlackLabel/g0b9uev5/1/
I am trying to make a pie chart based on the value of variables in the controller plz suggest easiest way to implement this.
You can use
1) Angular chart (using Chart.js)
2) angular directives for commonly used d3 charts
3) AngularJS Directive
4) An AngularJS directive for NVD3 re-usable charting library (based on D3).
5) Google Charts also use with AngularJS
I hope this will help you...
I hope this answer will help you. Using Angular charts you can make a pie chart or any other chart
Angular Chart
npm install angular-chart.js --save
It requires only 2 dependencies angularjs and chartjs
Angular nvD3 chart
{ "chart": {
"type": "pieChart",
"height": 500,
"showLabels": true,
"duration": 500,
"labelThreshold": 0.01,
"labelSunbeamLayout": true,
"legend": {
"margin": {
"top": 5,
"right": 35,
"bottom": 5,
"left": 0
}
}
}
}
You can use Highchart API with angular js
https://www.npmjs.com/package/angular2-highcharts
You can use alos Highchart without angular js to draw Pie chart ->
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="min-width: 310px; height: 400px; max-width: 600px; margin: 0 auto"></div>
<script>
Highcharts.chart('container', {
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
type: 'pie'
},
title: {
text: 'Browser market shares in January, 2018'
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
format: '<b>{point.name}</b>: {point.percentage:.1f} %',
style: {
color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black'
}
}
}
},
series: [{
name: 'Brands',
colorByPoint: true,
data: [{
name: 'Chrome',
y: 61.41,
sliced: true,
selected: true
}, {
name: 'Internet Explorer',
y: 11.84
}, {
name: 'Firefox',
y: 10.85
}, {
name: 'Edge',
y: 4.67
}, {
name: 'Safari',
y: 4.18
}, {
name: 'Sogou Explorer',
y: 1.64
}, {
name: 'Opera',
y: 1.6
}, {
name: 'QQ',
y: 1.2
}, {
name: 'Other',
y: 2.61
}]
}]
});
I am using Angular Directives to render Highcharts visuals and am trying to change the directive used based on User input. For testing, attempting to switch between line and column charts.
The directives are:
myApp.directive('columnChart', function () {
return function (scope, element, attrs) {
initChart();
function initChart() {
var chartConfig = {
chart: {
type: 'column',
zoomType: 'xy'
},
title: {
text: ''
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
yAxis: [{
min: 0,
title: {
text: 'Y Axis Label'
},
}],
series: [{
data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
}]
};
var chart = $(element).highcharts(chartConfig);
}
};
});
and
myApp.directive('lineChart', function () {
return function (scope, element, attrs) {
initChart();
function initChart() {
var chartConfig = {
chart: {
type: 'line',
zoomType: 'xy'
},
title: {
text: ''
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
yAxis: [{
min: 0,
//max:200,
title: {
text: 'Y Axis Label'
},
}],
series: [{
data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
}]
};
var chart = $(element).highcharts(chartConfig);
}
};
});
I have a simple test page with buttons that change the directive:
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div ng-controller="MyCtrl">
<button ng-click="setLineChart()">Set Line Chart</button>
<button ng-click="setColumnChart()">Set Column Chart</button>
<div id="container" column-Chart style="min-width: 400px; height: 400px; margin: 0 auto"></div>
</div>
and the code to set the Directive:
$scope.setLineChart = function() {
var docElement = document.getElementById("container");
var scope = angular.element(docElement).scope();
var element = angular.element(docElement);
element.html('<div id="chartContainer" line-Chart style="min-width: 400px; height: 400px; margin: 0 auto"></div>');
console.log("element: " , element);
$compile(element)(scope);
};
Clicking on the Set Line Chart button causes the Directive for the line chart to get called, but the chart still resolved as a column chart.
Here is the jsfiddle: https://jsfiddle.net/MFRTest/xsadzv4f/12/
I appreciate any insight into what I am missing
With the AngularJS framework, avoid manipulating DOM in controllers. The framework separates concerns to make the app more easily understood, debugged, tested, and maintained.
Instead have a directive that create highcharts based on the Model furnished by the Controller:
app.directive("highchart", function() {
return {
link: postLink
}
function postLink(scope, elem, attrs) {
scope.$watch(attrs.highchart, function (chartConfig) {
elem.highcharts(chartConfig);
}, true)
}
})
Usage:
<button ng-click="$ctrl.chart = $ctrl.lineChart">Set Line Chart</button>
<button ng-click="$ctrl.chart = $ctrl.colChart">Set Column Chart</button>
<div highchart="$ctrl.chart"
style="min-width: 300px; height: 300px; margin: 0 auto">
</div>
The DEMO
angular.module("app",[])
.directive("highchart", function() {
return {
link: postLink
}
function postLink(scope, elem, attrs) {
scope.$watch(attrs.highchart, function (chartConfig) {
elem.highcharts(chartConfig);
})
}
})
.controller("ctrl", function() {
this.colChart = {
chart: {
type: 'column',
zoomType: 'xy'
},
title: {
text: ''
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
]
},
yAxis: [{
min: 0,
//max:200,
title: {
text: 'Y Axis Label'
},
}],
series: [{
data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
}]
};
this.lineChart = {
chart: {
type: 'line',
zoomType: 'xy'
},
title: {
text: ''
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
yAxis: [{
min: 0,
//max:200,
title: {
text: 'Y Axis Label'
},
}],
series: [{
data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
}]
};
})
<script src="//unpkg.com/jquery"></script>
<script src="//unpkg.com/highcharts"></script>
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app" ng-controller="ctrl as $ctrl">
<h3>Highchart Directive DEMO</h3>
<button ng-click="$ctrl.chart = $ctrl.lineChart">
Set Line Chart
</button>
<button ng-click="$ctrl.chart = $ctrl.colChart">
Set Column Chart
</button>
<div highchart="$ctrl.chart"
style="min-width: 300px; height: 180px; margin: 0 auto">
</div>
</body>
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!
I currently have this as my directive:
app.directive('highchart', function () {
return {
restrict: 'E',
template: '<div></div>',
replace: true,
link: function(scope, element, attrs) {
scope.$watch(function() { return attrs.chart; }, function() {
if (!attrs.chart) return;
var chart = JSON.parse(attrs.chart);
$(element[0]).highcharts(chart);
});
}
};
})
And this is my controller:
function ProdSvcViewsCtrl($scope, $routeParams, $http, $location) {
$scope.example_chart = get_chart();
function get_chart() {
return {
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
plotOptions: {
series: {
name: 'Page Views',
color:'#FFFFFF',
cursor: 'pointer',
point: {
events: {
click: function () {
alert('Category: ' + this.category + ', value: ' + this.y);
}
}
},
}
},
chart: {
renderTo: 'container',
backgroundColor : {
linearGradient : [0, 0, 0, 400],
stops : [
[0, 'rgb(100, 100, 100)'],
[1, 'rgb(50, 50, 50)']
]
},
plotBackgroundColor: 'rgba(255, 255, 255, 0.1)',
width: 775,
height: 300,
},
title: {
text: "Product Page Views",
align: "center",
y: 15,
style: {
color: "#ffffff",
fontSize: "18px",
fontWeight: 500,
fontFamily:'Calibri,Helvetica,Arial'
}
},
legend: {
backgroundColor: 'transparent',
color:'#FFFFFF',
layout: 'horizontal',
floating: true,
align: 'left',
verticalAlign: 'top',
x: 60,
y: 1,
shadow: false,
border: 0,
borderRadius: 0,
borderWidth: 0
},
series: [{
data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
}]
};
}
}
How would I migrate the properties over to the directive from my controller so they can be dynamic depending upon what attributes I apply to the respective directive, ie, color, width, etc?
In your directive you could add watches to the parts of the chart you want to be dynamic.
This is the approach taken by this directive: https://github.com/pablojim/highcharts-ng