Export Highcharts to PDF with AngularJS Controller - javascript

I'm looking to export a customized chart simliar to the post here Export Highcharts to PDF (using javascript and local server - no internet connection) that references http://fiddle.jshell.net/leighking2/dct9tfvn/. This has the exact functionality that I'm looking for, however I have my chart/data in a sepearte file/controller. Does anyone know how I could take the concept from the post I listed above, but incorporate it into my controller?
Didn't want to include my whole index.html file but here are the two charts from it.
<div id="allCharts" class="col-md-6" >
<button class="export_all" >export all</button>
<highchart id="chart1" config="chartConfig" class="span9 myChart" ></highchart>
<hr>
<highchart id="chart2" config="chartConfig2" class="span9 myChart" ></highchart>
</div>
'use strict';
var myapp = angular.module('myapp', ["highcharts-ng"]);
myapp.controller('myctrl', function ($scope) {
$scope.chartConfig = {
options: {
chart: {
type: 'line'
},
xAxis: {
categories: ['Year 1', 'Year 2', 'Year 3', 'Year 4', 'Year 5'],
title: {
text: null
}
},
plotOptions: {
line: {
events: {
legendItemClick: function () {
return false;
}
}
}, allowPointSelect: false,
series: {
stacking: ''
}
}
},
series: [{ "name": "Purchase Costs", data: $scope.purchaseChartData }, { "name": "Rental Costs", data: $scope.rentalChartData }],
title: {
text: 'Rental and Purchase Costs'
},
credits: {
enabled: true
},
loading: false,
size: {}
};
$scope.chartConfig2 = {
options: {
chart: {
type: 'column'
},
xAxis: {
categories: ['Year 1', 'Year 2', 'Year 3', 'Year 4', 'Year 5'],
title: {
text: null
}
},
plotOptions: {
column: {
events: {
legendItemClick: function () {
return false;
}
}
}, allowPointSelect: false,
series: {
stacking: ''
}
}
},
exporting:{
allowHTML:true
},
series: [{ "name": "Annual Savings", data: $scope.savingsChartData }],
title: {
useHTML:false,
text: 'Savings Compounded Annually'
},
credits: {
enabled: true
},
loading: false,
size: {}
};
$scope.reflow = function () {
$scope.$broadcast('highchartsng.reflow');
};
});
Question Update
Thanks Vaelyr! I now have the print button working; however I only have it adding text. I'm just having trouble linking my chart to the imageData. For now I just have the script within my html page until I get this working.
Attaching the charts to the imageData (via a loop) isn't working for me. I have class="myCharts" attached to both of my charts, but no luck. Now I'm just bacially trying to add my charts to the imageData.
<div id="allCharts" class="col-md-6" >
<button class="exportAll" onClick="printPDF()" id="export_btn">export all</button>
<highchart id="chart1" config="chartConfig" class="span9 myChart" ></highchart>
<hr>
<highchart id="chart2" config="chartConfig2" class="span9 myChart" ></highchart>
function printPDF() {
var doc = new jsPDF();
// chart height defined here so each chart can be palced
// in a different position
var chartHeight = 80;
// All units are in the set measurement for the document
// This can be changed to "pt" (points), "mm" (Default), "cm", "in"
doc.setFontSize(40);
doc.text(35, 25, "My Exported Charts");
//loop through each chart
$('.myChart').each(function (index) {
var imageData = $(this).highcharts().createCanvas();
// add image to doc, if you have lots of charts,
// you will need to check if you have gone bigger
// than a page and do doc.addPage() before adding
// another image.
/**
* addImage(imagedata, type, x, y, width, height)
*/
doc.addImage(imageData, 'JPEG', 45, (index * chartHeight) + 40, 120, chartHeight);
//add.addImage();
});
//save with name
doc.save('demo.pdf');
};

I found the functionality that I was looking for here https://github.com/pablojim/highcharts-ng/issues/185.
--moe

Related

Apexcharts - correctly color the graphic columns

I'm putting the code to color the graphic in array, but it takes one color for the 3 columns, even having declared 3 colors for each column
options: {
chart: {
type: 'bar',
id: 'chart',
},
colors: ['#3366ff','#66ff66','#ff0000'],
dataLabels: {
enabled: false
},
series: [],
title: {
text: 'PRAZOS OS',
},
bar: {
columnWidth: '50%',
endingShape: 'rounded'
},
Data
this.$axios.get("/Operacional/GetRelatorio").then(res => {
this.prazos = res.data
this.$refs.chart1.updateSeries([{
name: 'PRAZOS OS',
data: [this.prazos.noPrazo, this.prazos.emDia, this.prazos.atrasadas ],
}])
})
how it looks
enter image description here
I declared in the code 3 colors for array, but only one color remains for the 3 columns
To achieve the effect you want, you need to set distributed: true in bar in plotOptions in your options.
Like this:
plotOptions: {
bar: {
distributed: true
}
}
Taken from Custom DataLabels Bar in the examples.
You can also find the description for distributed in the documentation.
distributed: Boolean
Turn this option to make the bars discrete. Each value indicates one bar per series.
Example:
var options = {
chart: {
type: 'bar',
id: 'chart',
},
colors: ['#3366ff', '#66ff66', '#ff0000'],
dataLabels: {
enabled: false
},
series: [{
data: [400, 430, 448, 470, 540, 580, 690, 1100, 1200, 1380]
}],
title: {
text: 'PRAZOS OS',
},
bar: {
columnWidth: '50%',
endingShape: 'rounded'
},
plotOptions: {
bar: {
distributed: true
}
}
};
var chart = new ApexCharts(document.querySelector("#chart"), options);
chart.render();
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<div id="chart"></div>

Extending Highmaps Side Effect

I am trying to create a dot density map of the state of Florida. While I know that Highmaps doesn't support color axis with mappoints. I extended it and it works but it comes with a side affect. When I click on one of the categories in the legend no hiding occurs. For example if I click on '>10', all values greater than 10 don't hide. When I open up the Chrome debugger it states that: a.setVisible is not a function What can I do to solve this problem. This is a requirement, while it may seem minor. I would appreciate any sort of tips or maybe some sort of example would be perfect. I can't show more code than what is shown. If you need me to explain more about the problem I will be glad to do so.
(function (H) {
H.seriesTypes.mappoint.prototype.axisTypes = [ 'xAxis', 'yAxis', 'colorAxis'];
H.wrap(H.seriesTypes.mappoint.prototype, "translate", function (p) {
p.call(this);
H.seriesTypes.mappoint.prototype.translateColors.call(this);
});
H.seriesTypes.mappoint.prototype.translateColors = H.seriesTypes.heatmap.prototype.translateColors;
H.seriesTypes.mappoint.prototype.colorKey = 'value';
})(Highcharts);
// Initiate the chart
$('#container').highcharts('Map', {
title: {
text: title
},
mapNavigation: {
enabled: false,
},
colorAxis: {
dataClasses: [{
from: 0,
to: 3,
color: "#66FFFF"
}, {
from: 4,
to: 9,
color: "#0099FF"
}, {
from: 10,
color: "#0000FF"
}
]
},
tooltip:
{
enabled: true
}
,
series: [{
mapData: Highcharts.maps['countries/us/us-fl-all'],
name: 'Basemap',
borderColor: '#A0A0A0',
nullColor: 'rgba(200, 200, 200, 0.3)',
showInLegend: false,
},
{
// Specify points using lat/lon
type: 'mappoint',
name: 'A',
turboThreshold: 2000000,
data: p_data,
dataLabels: {
enabled: false
}
},
{
// Specify points using lat/lon
type: 'mappoint',
name: 'B',
turboThreshold: 2000000,
data: m_data,
dataLabels: {
enabled: false
}
},
{
// Specify points using lat/lon
type: 'mappoint',
name: 'C',
turboThreshold: 2000000,
data: h_data,
dataLabels: {
enabled: false
}
}
]});
A sample to play with: http://jsfiddle.net/dlope073/4mabw6zr/2/
Use setVisible method from default map series. Like this: http://jsfiddle.net/4mabw6zr/3
(function (H) {
H.seriesTypes.mappoint.prototype.axisTypes = ['xAxis', 'yAxis', 'colorAxis'];
H.seriesTypes.mappoint.prototype.pointClass.prototype.setVisible = H.seriesTypes.map.prototype.pointClass.prototype.setVisible; // use the same setVisible method as map type.
H.wrap(H.seriesTypes.mappoint.prototype, "translate", function (p) {
p.call(this);
H.seriesTypes.mappoint.prototype.translateColors.call(this);
});
H.seriesTypes.mappoint.prototype.translateColors = H.seriesTypes.heatmap.prototype.translateColors;
H.seriesTypes.mappoint.prototype.colorKey = 'value';
})(Highcharts);

Highcharts issue updating chart type: not recognizing highcharts functions

I am trying to update my current highchart that I have to a new chart type, however I am having difficulty doing so.
I have embedded javascript in my page, the following is below
<script>
chart = $(function () {
$('#chart_example').highcharts({
chart: {
type: 'line'
},
title: {
text: 'Traffic'
},
xAxis: {
categories: ['November', 'December', 'January']
},
yAxis: {
title: {
text: 'Views'
}
},
series: [{
name: 'Hello',
data: [50, 30, 60]
}]
});
});
</script>
I have the following two scripts below at the bottom of the page
<script src="http://code.highcharts.com/highcharts.js"></script>
....
<script src="custom_script"></script>
</body>
</html>
Inside the custom script, I want to update the highcharts library from a line graph into a bar graph. I looked at the API and found an update method
that takes in new options. So I tried the following:
$(document).on('click' , '#button' , function() {
var options = new Object();
options.chart = new Object();
options.chart.type = 'bar';
options.chart.renderTo = 'container';
chart.update(options, true);
//the container the chart is in
$('#chart_example').show();
...
However I get
Uncaught TypeError: chart.update is not a function(anonymous function) # custom_script=1:41m.event.dispatch # jquery.min.js:3m.event.add.r.handle # jquery.min.js:3
My thought was that the order of the javascript is wrong but I seem to have the javascript in the right order. My questions are then:
1) Is this chart variable set correctly? My understanding is that a variable that is unset with var is automatically global.
2) What is the cause of this error and how do I fix it so that it updates properly?
Thank you in advance!
http://jsfiddle.net/2j1g200g/29/
var options = {
chart: {
type: 'line',
renderTo: 'chart_example'
},
title: {
text: 'Traffic'
},
xAxis: {
categories: ['November', 'December', 'January']
},
yAxis: {
title: {
text: 'Views'
}
},
series: [{
name: 'Hello',
data: [50, 30, 60]
}]
};
chart = new Highcharts.Chart(options);
options.chart.type = 'bar';
chart = new Highcharts.Chart(options);
Run this, it should get what you want. I included a button for demonstration.
chartOptions = {
chart: {
type: 'line'
},
title: {
text: 'Traffic'
},
xAxis: {
categories: ['November', 'December', 'January']
},
yAxis: {
title: {
text: 'Views'
}
},
series: [{
name: 'Hello',
data: [50, 30, 60]
}]
};
$('#chart_example').highcharts(chartOptions);
$(document).on('click' , '#button' , function() {
chartOptions.chart.type = 'bar';
$('#chart_example').highcharts(chartOptions);
});
<button id="button">rechart</button>
<div id="chart_example"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>

How do I make a Tornado Chart using Highcharts

I am trying to prepare a Tornado Chart using the column chart in Highcharts. Here is my fiddle.
My current code is:
$('#container').highcharts({
chart: {
type: 'columnrange',
inverted: true
},
title: {
text: 'Net Sales'
},
subtitle: {
text: 'MM $'
},
xAxis: {
categories: ['Annual Revenue', 'Number of Years', 'Annual Costs']
},
yAxis: {
title: {
text: 'MM $'
}
},
plotOptions: {
columnrange: {
dataLabels: {
enabled: true,
formatter: function () {
return this.y;
}
}
},
scatter:{
marker:{
symbol:'line',
lineWidth:11,
radius:8,
lineColor:'#f00'
}
}
},
legend: {
enabled: false
},
series: [{
name: 'Temperatures',
data: [
[12.15, 46.86],
[15.45, 42.28],
[27.77, 31.24]
]
},
{
name:'Base',type: 'scatter',data:[120],
}]
});
The problem is that the last series (Annual Costs) does not show, as it is in reversed order. Also, I'd like the Tornado Chart to look more like this:
Note that the labels in this chart are different from the actual values plotted. Also note that the bar in the center - in the example code, there would be a vertical line at 29.5. I would also like to support a combined uncertainty bar like the one at the bottom. Any suggestions would be greatly appreciated.
Your last bat is not showing, because first number is lower than second, see: http://jsfiddle.net/kErPt/1/
If you want to display another values at labels, then add that info first. Example:
data: [{
low: 12,
high: 15,
lowLabel: 35,
highLabel: 46
}, {
low: 2,
high: 35,
lowLabel: 15,
highLabel: 26
} ... ]
And then use dataLabels.formatter for series.
To add vertical line use plotLines.
I'm not sure what is the last bar called 'combined uncertainty'.
I've used Highcharts with separate series (thanks jlbriggs) to create a Tornado Chart: http://jsfiddle.net/uRjBp/
var baseValue = 29.5;
var outputTitle = "Net Sales";
var chart = new Highcharts.Chart({
chart: {
renderTo:'container',
//type:'column'
//type:'area'
//type:'scatter'
//type:'bubble'
},
credits: {},
exporting: {},
legend: {},
title: {
text: outputTitle
},
subtitle: {
text: "MM $"
},
tooltip: {
formatter: function() {
var msg = "";
var index = this.series.chart.xAxis[0].categories.indexOf(this.x);
var low = round(this.series.chart.series[0].data[index].y+baseValue);
var high = round(this.series.chart.series[1].data[index].y+baseValue);
if (this.x === "Combined Uncertainty") {
msg = "Combined Uncertainty in "+outputTitle+": "+low+" to "+high;
} else {
var lowLabel = this.series.chart.series[0].data[index].label;
var highLabel = this.series.chart.series[1].data[index].label;
msg = '<b>'+outputTitle+'</b> goes from '+ low +' to '+ high+'<br/> when '+this.x +
' goes from <br/> '+lowLabel+" to "+highLabel;
}
return msg;
}
},
plotOptions: {
series: {
dataLabels: {
enabled: true,
formatter: function () {
var index = this.series.chart.xAxis[0].categories.indexOf(this.x);
if (this.series.userOptions.labels === undefined) {
return this.y+baseValue;
}
return this.key === "Combined Uncertainty" ? "":this.series.userOptions.labels[index];
}
}
}
},
xAxis: {
title: {
text: 'Factor'
},
allowDecimals:false,
categories: ['Annual Revenue', 'Number of Years', 'Annual Costs', 'Combined Uncertainty']
},
yAxis: {
title: {
text: 'MM $'
},
labels: {
formatter:function() {
return this.value+baseValue;
}
}
},
series:[{
name: 'Low',
grouping:false,
type:'bar',
data:[{y:12.15-baseValue, label:10},{y:15.45-baseValue, label:1},{y:31.25-baseValue, label:2},{y:12.15-baseValue, color:'#99CCFF', label: ""}],
labels:[10,1,2,]
},{
name: 'High',
grouping:false,
type:'bar',
data:[{y:46.86-baseValue, label:30},{y:42.28-baseValue, label:3},{y:27.77-baseValue, label:4},{y:46.86-baseValue, color:'#99CCFF', label:""}],
labels:[30,3,4,]
},
{
name: 'Median',
type: 'scatter',
data: [null,null, null,27-baseValue],
marker: {
lineWidth: 2,
lineColor: Highcharts.getOptions().colors[3],
fillColor: 'white'
}
}]
});
function round(num) {
return Math.round(num*100)/100;
}
usually, this kind of chart is done using a separate series for the left and right portions
One way to do this is by setting one set of data as negative numbers, and then using the formatters to make the axis labels, datalabels, and tooltips display the absolute values
example:
http://jsfiddle.net/jlbriggs/yPLVP/68/
UPDATE:
to show a line as in your original chart, you can extend the marker symbols to include a line type, and use a scatter series to draw that point:
http://jsfiddle.net/jlbriggs/yPLVP/69/
If you don't want to have the extra code for the line marker type, you could use any of the other existing marker symbols for the scatter series.

Remove scrolled part of highcharts

Can the highlighted "green" part be removed?
code:
chart = new Highcharts.StockChart({
chart: {
renderTo: renderTo,
},
title: {
text: 'test - ' + title
},
zoomType: false,
subtitle: {
text: 'some text'
},
rangeSelector: {
selected: 4
},
yAxis: {
labels: {
formatter: function() {
return (this.value / 1000000) + "mil";
}
},
plotLines: [{
value: 0,
width: 2,
color: 'silver'
}]
},
credits: {
enabled:false
},
plotOptions: {
series: {
marker : {
enabled : true,
radius : 3
}
}
},
},
series: seriesOptions
});
Documentation is your friend.
Highstock Demo Gallery - Disabled navigator
http://www.highcharts.com/stock/demo/navigator-disabled
Necessary code:
navigator : {
enabled : false
},
Working Example: http://jsfiddle.net/gh/get/jquery/1.7.2/highslide-software/highcharts.com/tree/master/samples/stock/demo/navigator-disabled/
err...
quick and dirty
<div id="highchart">
highchart code here
</div>
<div style="background:white;display:block;position:relative;width:400px;margin-top:-150px;">
the rest of your site/content here
</div>
witht he limited amount of info you've provided this is all I can think of.

Categories

Resources