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
Related
Chart.js doughnut text visibility. Tell me how to make it so that when the values intersect, the text comes out and changes its position.
const myChart = new Chart(canvas,
{
type: 'doughnut',
data: {
labels: dataNameDB,
datasets: [{
data: dataCountDB,
backgroundColor: backgroundColor,
borderWidth: 0,
}],
},
plugins: [ChartDataLabels, DoughnutLabel],
options: {
cutout: 340,
responsive: true,
animation: false,
plugins: {
legend: {
display: false,
},
datalabels: {
formatter: (val, ctx) => {
return Math.round((ctx.chart.data.datasets[0].data[ctx.dataIndex] * 100) / summChart()) + "%";
},
display: (val,ctx) =>{
return 'auto';
},
clamp: true,
clip: true,
anchor: 'center',
align: 'center',
offset: 1,
font: {
size: 65,
weight: 'bold',
color: '000000'
},
color: '000000',
labels: {
value: {
color: '#000000'
}
}
},
doughnutlabel: {
labels: [{
text: summChart,
font: {
size: 140,
weight: 'bold',
color: '000000'
}
}]
}
}
}
},
);
Now it outputs something like this, but I need it to be like this:
Although the documentation says that display 'auto' is responsible for this, how to catch it when the text is hidden in order to move it?
A beginner in react... I am able to reach a function post-click event of a bar but unable to route to a link or page.
I may have other defined routes to which I want to go, like a page consisting of a table, listing all the sales and it automatically gets filtered. How am I supposed to do that? Please guide me through. I have searched for this a lot and finally was able to reach a function but now I am stuck.
class SalesWidget2 extends Component {
routeChange(index){
console.log('I am here');
// let history = useHistory();
// history.push('google.com');
}
constructor(props) {
super(props);
this.state = {
colors:['#FEB019'],
series: [{
name: 'Sales ',
type: 'column',
data: [1.4, 2, 2.5, 1.5, 2.5, 2.8, 3.8, 4.6],
}],
options: {
chart: {
type: 'bar',
height: 350,
fontFamily: 'Roboto, sans-serif',
fontSize: '14px',
events:{
click: (event, chartContext, config) =>{
this.routeChange(config.dataPointIndex);
}
},
},
plotOptions: {
bar: {
borderRadius: 4,
horizontal: false,
}
},
dataLabels: {
enabled: false
},
title: {
text: 'My Store Performance',
align: 'left',
offsetX: 50,
fontSize: '14px',
},
xaxis: {
title: {
text: 'Time',
style: {
fontSize: '14px',
},
},
categories: ['June 2021', 'July 2021','August 2021', 'September 2021', 'October 2021','November 2021','December 2021', 'January 2022'],
},
yaxis:{
title: {
text: 'Sales',
style: {
fontSize: '14px',
}
},
labels:{
formatter: function(val) {
return val.toFixed(1);
}
}
},
tooltip: {
x:{
title:{
text: 'Sales',
}
},
y: {
formatter: function(val) {
return "$" + val.toFixed(0) + " million";
}
}
},
fill:{
colors:['#FEB019'],
},
stroke:{
colors:['#FEB019'],
},
legend: {
horizontalAlign: 'left',
offsetX: 40,
fontSize: '14px',
},
responsive: [{
breakpoint: 1000,
options: {
plotOptions: {
bar: {
horizontal:true,
vertical: false,
}
},
legend:{
position: "bottom"
},
yaxis:{
labels:{
formatter: function(val) {
return val.toFixed(0);
}
}
},
xaxis:{
labels:{
formatter: function(val) {
return val.toFixed(1);
}
}
},
},
}],
},
};
}
render() {
return(
<Chart options={this.state.options} series={this.state.series} type="bar" height="350" />
)
}}
There is a solution here that explains how to use web worker with makepdf. However, I want to know how to apply this solution to angular using requirejs.
I have tried to use ngwebworker along with requireJs, as the RequireJS within webworker, but I had no success. Can someone help me?
EDIT:
To make it easier to visualize the problem, I will put on this edit the code that it is not working:
$scope.exportToPDF = function(){
var list = $rootScope.orderedData;
var body = [];
var headers = new Array();
headers.push({ text: 'A', fillColor: '#0075E5', color: '#ffffff'});
headers.push({ text: 'B', fillColor:#0075E5', color: '#ffffff'});
headers.push({ text: 'C', fillColor:#0075E5', color: '#ffffff'});
headers.push({ text: 'D', fillColor:#0075E5', color: '#ffffff'});
headers.push({ text: 'E', fillColor:#0075E5', color: '#ffffff'});
headers.push({ text: 'F', fillColor:#0075E5', color: '#ffffff'});
body.push(headers);
for (var key in list)
{
if (list.hasOwnProperty(key)){
var position = list[key];
var fila = new Array();
fila.push( { text: position.a.toString(), fillColor: '#ffffff' } );
fila.push( { text: position.b.toString(), fillColor: '#ffffff'} );
fila.push( { text: position.c.toString(), fillColor: '#ffffff'} );
fila.push( { text: position.d.toString().substring(0,5) + "...", fillColor: '#ffffff'} );
fila.push( { text: position.e.toString(), fillColor: '#ffffff'} );
body.push(fila);
}
}
var dd = {
background: [{
width: 30,
alignment: 'left'
}],
pageOrientation: 'landscape',
footer: function(currentPage, pageCount) { return currentPage.toString() + '/' + pageCount;},
info: {
title: 'Title',
author: 'Me'
},
content: [
{ text: 'Text', style: 'header' },
{
style: 'tableHeader',
table:
{
dontBreakRows: true,
headerRows: 1,
widths: ['5%', '10%', '10%', 'auto', '15%', 'auto', 'auto', '10%', '10%', 'auto', '4%', '10%'],
body: body
}
}
],
styles: {
header: {
fontSize: 18,
bold: true,
margin: [0, 0, 0, 10],
alignment: 'center'
},
subheader: {
fontSize: 16,
bold: true,
margin: [0, 10, 0, 5]
},
tableExample: {
margin: [0, 5, 0, 15]
},
tableHeader: {
bold: true,
fontSize: 9,
color: 'black',
margin: [0, 5, 0, 15]
}
},
defaultStyle: {
},
};
var obj = pdfMake.createPdf(dd) // FAST PROCESS!
var myWorker = Webworker.create(downloadIt);
myWorker.run(obj).then(function(body) {
});
function downloadIt(obj) {
obj.download("Title.pdf"); // REALLY SLOW PROCESS THAT SHOULD BE IN BACKGROUND
}
}
The problem is that to transfer an object to a web worker, they suggest to use JSON.parse and JSON.stringify. However, if I use that on my object, I will loose the method "download". Is there a way to send this object to my function downloadIt without loosing the method download of pdfmake object?
i have highchart graph api similar to pasted fiddle link, the problem
is number is missing in few stacked column( example in fiddle decission line one label value is missing) could anyone help on this why
this is happening
$(function () {
$('#container').highcharts({
chart: {
type: 'column',
inverted:true,
height: 200
},
title: {
text: 'Stacked column chart'
},
xAxis: {
categories: ['Pending', 'Further', 'Decision']
},
yAxis: {
min: 0,
//max:100,
title: {
text: 'Total fruit consumption'
},
stackLabels: {
enabled: true,
style: {
fontWeight: 'bold',
color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray'
}
}
},
legend: {
align: 'center',
x: -30,
verticalAlign: 'top',
y: 25,
floating: false,
backgroundColor: (Highcharts.theme && Highcharts.theme.background2) || 'white',
borderColor: '#CCC',
borderWidth: 1,
shadow: false
},
tooltip: {
headerFormat: '<b>{point.x}</b><br/>',
pointFormat: '{series.name}: {point.y}<br/>Total: {point.stackTotal}'
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true,
crop:false,
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white',
style: {
textShadow: '0 0 3px black'
}
}
}
},
series: [{
data:[3, 2, 1],
name:'Today'
}, {
data:[2, 2, 19],
name:'1 Day'
}, {
data:[14, 2, 22],
name:'2 Days'
},{
data:[6, 2, 18],
name:'3 Days'
},{
data:[10, 2, 537],
name:'>3 Days'
}]
});
});
http://jsfiddle.net/g6wsd1hm/
If I change stacking to percent ,all labels are visible. minPointLength is set to make minimum column stacks width for a relatively less number
use following :
plotOptions: {
column: {
stacking: 'percent',
minPointLength:10 //this needs to added
}
}
Fiddle Here
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