Google charts save zoomed image as PNG - javascript

I'm using Google Charts to create a line chart, and I'm using
explorer: {actions: ['dragToZoom', 'rightClickToReset']
to allow the user to zoom in on a bounding box. I'd like to be able to save the zoomed image as a PNG. To do so, I'm trying to find the HAxis values at the left and right edges of the chart and the VAxis values at the top and bottom edges of the chart:
var cli = chart.getChartLayoutInterface();
var hl = cli.getHAxisValue(cli.getChartAreaBoundingBox().left);
var hr = cli.getHAxisValue(cli.getChartAreaBoundingBox().left + cli.getChartAreaBoundingBox().width);
var vt = cli.getVAxisValue(cli.getChartAreaBoundingBox().top);
var vb = ??
Then I'm using these in my options to replot the chart with these limits:
var options = {
width: 1430,
height: 563,
hAxis: {
title: 'X-Axis',
viewWindow: { min: hl, max: hr}
},
explorer: {actions: ['dragToZoom', 'rightClickToReset'], keepInBounds: true, maxZoomIn: .01 },
curveType: "function",
vAxis: {
logScale: log1,
title: "Y-Axis",
titleTextStyle: {color: '#0000FF'},
textStyle: {color: '#0000FF'},
baselineColor: '#0000FF',
viewWindow: { min: vb, max: vt}}
},
title: "Figure 1"
};
var chart = new google.visualization.LineChart(document.getElementById('plot'));
chart.draw(data, options);
drawpng = chart.getImageURI();
return drawpng;
My values for the left, right, and top edges are working correctly, but I can't figure out how to determine the bottom edge. I've already tried
var vb = cli.getVAxisValue(cli.getChartAreaBoundingBox().top - cli.getChartAreaBoundingBox().height)
and
var vb = cli.getVAxisValue(cli.getChartAreaBoundingBox().height)
and
var vb = cli.getVAxisValue(cli.getChartAreaBoundingBox().height - cli.getChartAreaBoundingBox().top)
but none of these are giving me the correct value.
Does anyone know how to make this work, or another way of saving the zoomed in chart?
Thanks!

I got it to work using
cli.getVAxisValue(cli.getChartAreaBoundingBox().top+cli.getChartAreaBoundingBox().height)
I hadn't realized that the position was being calculated from the top, not the bottom.

Related

Print pie chart in chartjs

I am having a problem with chartjs. I just
want to print what is inside div#browser with a pie chart. The chart
was fine and animated but the problem is during I print it the pie
chart disappears but when I refresh again it it was just fine. The
other charts works fine in printing except the pie chart. I believe
its reason is in the animation or something
The chartjs script
<script>
var pieChartCanvas = $("#pieChart").get(0).getContext("2d");
var pieChart = new Chart(pieChartCanvas);
var PieData = [
{
value: 700,
color: "#f56954",
highlight: "
#f56954",
label: "Chrome"
},
{
value: 500,
color: "#00a65a",
highlight: "#00a65a",
label: "IE"
},
{
value: 400,
color: "#f39c12",
highlight: "#f39c12",
label: "FireFox"
},
{
value: 600,
color: "#00c0ef",
highlight: "#00c0ef",
label: "Safari"
},
{
value: 300,
color: "#3c8dbc",
highlight: "#3c8dbc",
label: "Opera"
},
{
value: 100,
color: "#d2d6de",
highlight: "#d2d6de",
label: "Navigator"
}
];
var pieOptions = {
//Boolean - Whether we should show a stroke on each segment
segmentShowStroke: true,
//String - The colour of each segment stroke
segmentStrokeColor: "#fff",
//Number - The width of each segment stroke
segmentStrokeWidth: 1,
//Number - The percentage of the chart that we cut out of the middle
percentageInnerCutout: 50, // This is 0 for Pie charts
//Number - Amount of animation steps
animationSteps: 100,
//String - Animation easing effect
animationEasing: "easeOutBounce",
//Boolean - Whether we animate the rotation of the Doughnut
animateRotate: true,
//Boolean - Whether we animate scaling the Doughnut from the centre
animateScale: false,
//Boolean - whether to make the chart responsive to window resizing
responsive: true,
// Boolean - whether to maintain the starting aspect ratio or not when responsive, if set to false, will take up entire container
maintainAspectRatio: false,
//String - A legend template
legendTemplate: "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>",
//String - A tooltip template
tooltipTemplate: "<%=value %> <%=label%> users"
};
//Create pie or douhnut chart
// You can switch between pie and douhnut using the method below.
pieChart.Doughnut(PieData, pieOptions);
</script>
The html
<div id="browser">
<h3 class="box-title">Browser Usage</h3>
<a onclick="printContent('browser')">Print</a>
<div class="chart-responsive">
<canvas id="pieChart" height="150"></canvas>
</div>
</div>
Print script
<script>
function printContent(el){
var restorepage = document.body.innerHTML;
var printcontent = document.getElementById(el).innerHTML;
document.body.innerHTML = printcontent;
window.print();
document.body.innerHTML = restorepage;
}
</script>
Try using the .toDataURL() method on your canvas. This method returns a URL containing your chart as an image.
https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL
Grab your pie chart's canvas and convert it to an image: document.getElementbyId('pieChart').toDataURL;
Assign the generated chart image URL to a variable, let's keep using printContents in this case: let **printContents** = document.getElementbyId('pieChart').toDataURL;
Initiate an html document on the fly and append the previously created image URL as an <img> element's source, using template literals to embed the printContents variable: let html = <html><head><title></title></head><body><img src=${printContent}></body></html>
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
-Execute the print job (Chrome) by writing the previously constructed html doc to the print window on the fly:
let **printWindow** = window.open('', 'Print-Preview', 'height=900,width=200');
printWindow.document.open();
printwindow.document.write(html);
printWindow.document.close();
Yes, it has to do with the animation. You need to check for the animation being complete. Under options add:
animation: {
onComplete: done
}
and then create a function "done" where you handle the printing.
function done() {
}

How to change the bar chart orientation in Google Charts

I need to draw two bar charts facing each other in one page. (The chart on the left faces right, and the one on the right faces left).
But with Google Charts, I only managed to make both charts face right.
Is it possible to implement? What should I do?
using a 100% stacked chart, you can get the bars to align to the right
then color the first series transparent,
and manipulate the data to reveal the proper length
then when the chart's 'ready' event fires,
you can move around the chart elements,
such as the y-axis, and the order of the x-axis labels
first, you need to allow enough room on the left,
for the original y-axis labels to print
otherwise they will be cutoff, i.e.
Canis Major Dwarf vs. Canis Maj...
then need to leave enough room on the right,
by limiting the chartArea, otherwise cutoff and simply not visible, i.e.
Canis Major Dwarf vs. Canis M
might be easier, providing your own labels
this should give you something to tweak on...
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawStuff);
function drawStuff() {
var data = new google.visualization.arrayToDataTable([
['Galaxy', 'Distance', 'Brightness'],
['Canis Major Dwarf', 10, 20],
['Sagittarius Dwarf', 20, 40],
['Ursa Major II Dwarf', 40, 50],
['Lg. Magellanic Cloud', 60, 80],
['Bootes I', 80, 120]
]);
var options = {
isStacked: 'percent',
colors: ['transparent', 'magenta'],
legend: {
position: 'bottom'
},
chartArea: {
left: 200,
width: 400
},
width: 800
};
var container = document.getElementById('dual_x_div');
var chart = new google.visualization.BarChart(container);
google.visualization.events.addListener(chart, 'ready', function () {
var labels = container.getElementsByTagName('text');
var hAxisLabels = [];
Array.prototype.forEach.call(labels, function (text, index) {
switch (text.getAttribute('text-anchor')) {
// move y axis labels
case 'end':
text.setAttribute('x', parseFloat(text.getAttribute('x')) + 540);
break;
// save x axis labels
case 'middle':
// save x position here
// otherwise, x position will change
// before you know where the next should have been
hAxisLabels.push({
text: text,
x: parseFloat(text.getAttribute('x'))
});
break;
}
});
// swap label positions
hAxisLabels.forEach(function (label, index) {
label.text.setAttribute('x', hAxisLabels[hAxisLabels.length - index - 1].x);
});
});
chart.draw(data, options);
};
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="dual_x_div"></div>

jQPlot Horizontal Bar Graph - assign names to Y Axis

I figured it out:
I was not including the jqplot.CategoryAxisRenderer. Once I included that, I was able to get it working.
Thanks, everyone!
UPDATE:
My code works in JSFiddle, so it's a CSS problem I'm having. Please disregard.
I'm trying to create a fairly simple bar chart in jQPlot. I'm expecting two horizontal bars, one on top of the other. Both are equal to 1 on the X axis. I want the Y axis to have the labels 'In Progress' for the top bar, and 'Apr 2014' for the bottom bar. I have tried numerous combinations. If I do not specify Ticks, then I see the two bars. Specifying Ticks, or using the desired labels as the Y axis data point just shows both labels overlapping with no bars. (ignore the setTimeout) Thanks in advance.
Here's the code:
var data = [[1,1],[1,2]];
var ticks = ['In Progress','Mar 2014'];
$(function () {
setTimeout(function(){
var plot1 = jQuery.jqplot ('chartdiv', [data],
{
seriesDefaults: {
renderer:$.jqplot.BarRenderer,
rendererOptions: {
barDirection: 'horizontal'
},
},
axes: {
yaxis: {
renderer: $.jqplot.CategoryAxisRenderer,
ticks: ticks
}
}
});
},
100);
});
I have modified the JsFiddle given by Batu Zet previously adding following lines in order to label your bar chart here :
series: [
{
pointLabels:{
show:true,
labels:['Apr 2014', 'Apr 2014']
}
},
{
pointLabels:{
show:true,
labels:['In Progress', 'In Progress']
}
}
]
P.S : The labels are duplicated for each serie in order to display the same label for two points in a serie.

How to prevent popup in ColumnChart

I use a google maps ColumnChart to reprensent the elevation in a map.
I also use a mouseover to print info and show the correspondent position.
When a column in the chart is clicked, it popups an info balloon, like here:
http://4.bp.blogspot.com/-4I8oi3WqY5o/UIZnzbXql_I/AAAAAAAAAcE/GO4wl6I2-lM/s1600/Charts.png
This balloon is ok for desktops, but a pain for mobile (very hard to close, etc).
How can I completely disable it? It has to do with the second data column passed to the chart.
No balloons!
Thanks!
L.
EDIT
Code added by request:
var option = {
legend: 'none',
backgroundColor: 'transparent',
colors: ["#C9CFF5"],
titleColor: '#C9CFF5',
focusBorderColor: '#00AA00',
titleY: 'Elevation (m)',
tooltip: { trigger: 'none' },
bar: { groupWidth: '100%' }
}
// Build data
var data = new google.visualization.DataTable();
data.addColumn('string', 'Sample');
data.addColumn('number', 'Elevation (m):');
for (var i = 0; i < trackmarks.length; i++) {
data.addRow(['', trackaltis[i]]);
}
// Draw the chart using the data within its DIV.
chart = new google.visualization.ColumnChart(document.getElementById('elevation_chart'));
chart.draw(data, option);

How to add jqplot pie chart labels with lines?

I have a pie chart and I can add labels for it normal way.But I want to add labels with line as following.
I took this image from web as a example. here is my code ,
drawPieCharts = function(dev,title,data){
$('#'+dev).empty();
var plot = $.jqplot(dev, [data], {
title: {
text: title,
fontWeight: 'bold',
fontSize : '16',
show: true
},
grid: {
drawBorder: false,
drawGridlines: false,
background: '#ffffff',
shadow:false,
//diameter : 30
},
axesDefaults: {
},
highlighter: {
show: true,
formatString:'%s , P%',
tooltipLocation:'n',
useAxesFormatters:false
},
seriesDefaults:{
renderer:$.jqplot.PieRenderer,
rendererOptions: {
showDataLabels: true,
dataLabelThreshold: 0,
dataLabelPositionFactor: 1.05,
dataLabels : mapSeperater(data)[0],
padding: 2
}
},
});
}
And also I have another problem I want to bold the title of the chart and in this way it doesn't work. Is there a way to do that?
Thank you.
i'm looking for the same, not successful yet.
but for the title maybe you can try to style the div with the class "jqplot-title", that's where the title is rendered.
in jquery would be something like that:
$(".jqplot-title").wrap("<b></b>")
EDIT:
sorry i had no time to jsfiddle it, but you can try it and get the idea. looks a little awful but you can make it better.
what i did was putting labels of the slices outside the pie and draw some lines from the center to these labels.
..i came with something like this:
series: [{
renderer: $.jqplot.PieRenderer,
rendererOptions: {
diameter: 140,
showDataLabels: true,
dataLabelThreshold: 0, //minimum area to show a label, (i want all the labels)
dataLabelPositionFactor: 2.3, //in function of the radius, how far show the label
dataLabels: 'label',
dataLabelFormatString: '%s',
//(just more options, etc, etc)
plot = $.jqplot("myDivHere", [data], options).replot(); // <-- that's for me
// ******************************
// HERE COMES THE MAGIC:
//
var w = $("#myDivHere .jqplot-series-shadowCanvas").width();
var h = $("#myDivHere .jqplot-series-shadowCanvas").height();
x1 = (w/2);
y1 = (h/2);
var canvas = $("#myDivHere .jqplot-series-shadowCanvas")[0];
var context = canvas.getContext('2d');
$(".jqplot-pie-series.jqplot-data-label").each(
function(){
var l = $(this).position().left;
var t = $(this).position().top;
console.log("x1, y1 are: ["+x1+", "+y1+"]\n l, t are ["+l+", "+t+"]");
context.beginPath();
context.moveTo(x1, y1);
context.lineTo(l, t);
context.stroke();
});
I have no more time to work on this this week, so you could use it as awful it is and make it better. or wait for a better solution to show up.
Greetings!!
Ahh, and if you can make it better, please share it with me.

Categories