Chart.js and HTML2PDF - charts

I really hope you will be able to help me...
I'm working with several pages...
In a first one, I created a radar chart with Chart.js. It worls perfectly well.
In a another part of my site, I want to summarize a certain number of information, including this chart. I'm creating my PDF with Html2pdf. And this doesn't work at all...
Chart is dynamic and the PDF is static, so not possible in this way...
I looked for other options, but not successfully at this point.
On of these options is converting the chart in image and call it in the PDF. I never found any example to really help me to do this. And I don't even know if this is feasable as the first page is not even issued at the same moment.
Does anybody could help me on this ?
Or is there any other option ?
Thanks
Here is the js code for the chart creation
<div class="holder">
<canvas id="myChart"></canvas>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.min.js"></script>
<!-- <script //src="https://parall.ax/parallax/js/jspdf.js"></script> -->
<script>
var ctx = document.getElementById('myChart');
var myChart = new Chart(ctx, {
type: 'radar',
data: {
labels: ['Point_A', 'Point_B', 'Point_C', 'Point_D', 'Point_E', 'Point_F', 'Point_G'],
datasets: [{
label: 'Drivers',
data: [<? echo $point_a; ?>, <? echo $point_b; ?>, <? echo $point_c; ?>, <? echo $point_d; ?>, <? echo $point_e; ?>, <? echo $point_f; ?>, <? echo $point_g; ?>],
backgroundColor: [
'rgba(254, 175, 57, 0.8)',
],
borderColor: [
'rgba(254, 175, 57, 1)',
],
borderWidth: 1
}]
},
options: {
scales: {
r:{
ticks: {
beginAtZero: true,
steps: 10,
stepValue: 6,
max: 60
}
}
}
}
});
</script>

Related

Google Line Chart - Show Data Values on Points by default

I want to show data values on the line chart, i.e. which appear on mouse over, i need them all displayed by default. I tried the solution here Google Charts API: Always show the Data Point Values in Graph
data.addColumn({type: 'number', role: 'annotation'});
I added this to my code (I'm not sure where to put it exactly) but It didn't make any change.
Here is part of my code:
<!DOCTYPE html>
<html>
<head>
<title>Week/Orders</title>
<script type="text/javascript" src="loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart(){
var data = new google.visualization.DataTable();
var data = google.visualization.arrayToDataTable([
['Week','Orders'],
<?php
while($row = mysqli_fetch_assoc($aresult)){
echo "['".$row["Week"]."', ".$row["Orders"]."],";
}
?>
]);
var options = {
title: 'Week Vs Orders',
'width':1700,
'height':600,
legend: { position: 'bottom' }
};
var chart = new google.visualization.LineChart(document.getElementById('curvechart'));
chart.draw(data, options);
}
</script>
</head>
<body>
<div id="curvechart" style="width: 900px; height: 400px"></div>
</body>
</html>
I have two values; Week and Orders. I need only the "Order" value displayed on the graph by default. How can I do this? Thanks.
you can use a DataView to add annotations to the chart
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
calc: 'stringify',
sourceColumn: 1,
type: 'string',
role: 'annotation'
}]);
see following working snippet...
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart(){
var data = google.visualization.arrayToDataTable([
['Week','Orders'],
['1', 5],
['2', 6],
['3', 4]
]);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
calc: 'stringify',
sourceColumn: 1,
type: 'string',
role: 'annotation'
}]);
var options = {
title: 'Week Vs Orders',
width: 1700,
height: 600,
legend: {position: 'bottom'}
};
var chart = new google.visualization.LineChart(document.getElementById('curvechart'));
chart.draw(view, options); // <-- use data view
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="curvechart"></div>

Highcharts - How to add background in bar series? And how to print page without lose quality?

I need your help, i try use "pattern" in Highcharts to use background in bars, but the images don't fill the space that i wanna.
Bar Chart Example
I wanna know, how i do to leave the image with -90° than the way that is? And how i do to leave the image with height 100% and width 25%?
And beyond that i wanna of know, how i print the screen without lose the quality in image, because when i press "ctrl+p" i see all all blurred.
Print blurred
Follow below the current code:
<!DOCTYPE html>
<html>
<head>
<title>HighCharts - Pattern Color</title>
<meta http-equiv="Content-Type" contetn="text/html;" charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="http://code.jquery.com/ui/1.9.1/themes/base/jquery-ui.css" />
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="https://code.jquery.com/ui/1.9.1/jquery-ui.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://highcharts.github.io/pattern-fill/pattern-fill.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
</head>
<body>
<script type="text/javascript">
$(document).ready(function() {
Highcharts.chart('container', {
chart: {
type: 'bar',
backgroundColor: null
},
title: {
text: 'Como você está?'
},
xAxis: {
categories: ['']
},
yAxis: {
min: 0,
title: {
text: ''
}
},
legend: {
reversed: true
},
plotOptions: {
series: {
stacking: 'percent',
dataLabels: {
enabled: true,
format: '<b>{point.percentage:.2f}%</b>',
//point.percentage:.1f
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white'
}
}
},
series: [{
name: 'Alegre',
data: [30],
color: {
pattern: 'http://emoticons.topfriends.biz/favicon.png',
width: '30',
height: '30'
}
// color: '#B22222'
}, {
name: 'Feliz',
data: [30],
color: {
pattern: 'https://t4.ftcdn.net/jpg/01/58/30/09/240_F_158300957_MhRWEx1vDO6SPVHdGS4dqNG7nLP8rdZ4.jpg',
width: '30',
height: '30'
}
// color: '#2E8B57'
}]
});
});
</script>
<div id="container" style="min-width: 80%; height: 200px; max-width: 80%; margin: 0 auto"></div>
</body>
</html>
Since now i thanks!
1. PATTERN FILL ADJUSTMENT
Refer to this live working example: http://jsfiddle.net/kkulig/opa73k8L/
Full code:
var redrawEnabled = true,
ctr = 0;
$('#container').highcharts({
chart: {
events: {
render: function() {
if (redrawEnabled) {
redrawEnabled = false;
var chart = this,
renderer = chart.renderer;
chart.series[0].points.forEach(function(p) {
var widthRatio = p.shapeArgs.width / p.shapeArgs.height,
id = 'pattern-' + p.index + '-' + ctr;
var pattern = renderer.createElement('pattern').add(renderer.defs).attr({
width: 1,
height: widthRatio,
id: id,
patternContentUnits: 'objectBoundingBox'
});
renderer.image('http://emoticons.topfriends.biz/favicon.png', 0, 0, 1, widthRatio).attr({
}).add(pattern);
p.update({
color: 'url(#' + id + ')'
}, false);
});
ctr++;
chart.redraw();
redrawEnabled = true;
}
}
}
},
series: [{
type: 'bar',
borderWidth: 1,
borderColor: '#000000',
data: [10, 29.9, 71.5]
}]
});
In the redraw event I iterate all the points, create a separate pattern for every point based on its width/height ratio, apply pattern and redraw the chart.
On every redraw new set of patters are created which is not an elegant solution (old ones should be replaced instead). ctr variable is used to create unique name for each pattern.
redrawEnabled serves to prevent infinite recursive loop because chart.redraw() also calls the render event.
In my opinion the easiest way to have the rotated image is to simply provide the already rotated one.
API references:
https://api.highcharts.com/highcharts/chart.events.render
https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#createElement
https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#image
2. PRINTING ISSUE
It seems to be a bug reported here: https://github.com/highcharts/pattern-fill/issues/20

google charts change background color

I saw some previous questions/answers here on StackOverflow
but none of the code provided in those answers seemed to work
with my chart:
Here is my code:
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1.1", {packages:["bar"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Month', 'Sales', 'Expenses'],
['January', 200, 150],
['February', 1170, 460],
['March', 660, 1120],
['April', 1030, 540],
['May', 1030, 540],
['June', 1030, 540]
]);
var options = {
chart: {
title: 'Company Performance',
subtitle: 'Sales, Expenses, and Profit: May-August',
backgroundColor: '#fcfcfc',
}
};
var chart = new google.charts.Bar(document.getElementById('columnchart_material'));
chart.draw(data, options);
}
</script>
The html div code:
<div id="columnchart_material" style="width: 650px; height: 500px;"></div>
The thing is I want to change the background from white to light gray
and I can't seem to make it work by declaring backgroundColor: "#fcfcfc'
inside options{}
Is there any other way to declare a background color on that chart
I'm thinking maybe the type of chart I'm using can't change it's
background color.
I also tried to specify the backgroundColor variable as a function (followed by curly brackets backgroundColor{ color: '#fcfcfc' }
but that didn't work on my chart either.
Any help would be higly appreciated.
Thank you
jsFiddle : http://jsfiddle.net/mtypsnqy/
First, you've placed your backgroundColor: '#fcfcfc', at the wrong place. You have defined it inside of chart:{}while you should do it either outside any object or inside of chartArea like:
var options = {
chart: {
title: 'Company Performance',
subtitle: 'Sales, Expenses, and Profit: May-August'
},
backgroundColor: '#fcfcfc'
};
which will cause your whole div containing the chart to be dark grey or like this:
var options = {
chart: {
title: 'Company Performance',
subtitle: 'Sales, Expenses, and Profit: May-August'
},
chartArea:{
backgroundColor: '#fcfcfc'
}
};
which will cause only the area contained within your two axes to be colored red.
And finally you have to change your
chart.draw(data, options);
to
chart.draw(data, google.charts.Bar.convertOptions(options));
as specified on the Bar Charts API page.
I made you a fiddle to play around in and see the difference: Link

$create(Sys.Extended.UI.ResizableControlBehavior, ...) fails with error "Unable to get property 'UI' of undefined..." unless a control already exists

There seems to be 2 separate issues behind this error. One is using scriptmanager instead of toolkitscriptmanager. I'm using toolkitscriptmanager but I get this error if I try to $create a control/behavior without already having one on the page. If I have a control on the page, without changing anything else, there's no error.
I'm using using the .net4.0 version of AjaxControlToolkit.
works:
<div id="divTest" style="height:500px; width:500px; background:#ccc">test</div>
<script>
Sys.Application.add_init(function () {
$create(
Sys.Extended.UI.ResizableControlBehavior,
{
"ClientStateFieldID": "ResizableControlExtender1_ClientState",
"HandleCssClass": "handle",
"HandleOffsetX": 0,
"HandleOffsetY": 0,
"MaximumHeight": 800,
"MaximumWidth": 800,
"MinimumHeight": 220,
"MinimumWidth": 478,
"ResizableCssClass": "resizing",
"id": "ResizableControlBehavior1"
}, null, null, $get("divTest"));
});
</script>
<div id="divWrapper" runat="server"></div>
<asp:ResizableControlExtender ID="divWrapper_ResizableControlExtender"
runat="server"
TargetControlID="divWrapper"
HandleCssClass="handle"
ResizableCssClass="resizing"
MaximumHeight="800"
MaximumWidth="800"
MinimumHeight="220"
MinimumWidth="478"
HandleOffsetX="0"
HandleOffsetY="0"></asp:ResizableControlExtender>
doesn't work:
<div id="divTest" style="height:500px; width:500px; background:#ccc">test</div>
<script>
Sys.Application.add_init(function () {
$create(
Sys.Extended.UI.ResizableControlBehavior,
{
"ClientStateFieldID": "ResizableControlExtender1_ClientState",
"HandleCssClass": "handle",
"HandleOffsetX": 0,
"HandleOffsetY": 0,
"MaximumHeight": 800,
"MaximumWidth": 800,
"MinimumHeight": 220,
"MinimumWidth": 478,
"ResizableCssClass": "resizing",
"id": "ResizableControlBehavior1"
}, null, null, $get("divTest"));
});
</script>
Problem solved!
All i needed to do was dig through the source of a working page and find this script tag and then copy it over to the broken version:
<script src="/myapp/mypage.aspx?_TSM_HiddenField_=ScriptManager1_HiddenField&_TSM_CombinedScripts_=%3b%3bAjaxControlToolkit%2c+Version%3d4.1.7.607%2c+Culture%3dneutral%2c+PublicKeyToken%3d28f01b0e84b6d53e%3aen-US%3afc974eef-02bb-4a84-98bd-02b839b496d1%3ade1feab2%3af9cec9bc%3a6beb6cd0" type="text/javascript"></script>
I'm just kidding. I switched to jquery.

jqGrid not displaying JSON data

I'm using asp.net mvc to create a webpage that renders a jqGrid for data in my azure table. The grid will callback into my controller and using the debugger, I can visually verify data is being generated correctly. The issue is that once the data is returned as a JSON string, the jqGrid throws this error:
b.jgrid.getAccessor(p, d.cell) is undefined
http://localhost:54758/jquery.jqGrid.min.js
Line 65
I've looked online for documentation but have been unsuccessful in returning anything except what appears to be repository snapshots. I've stripped down my code to only have one column of data (shown below) returned as a string and still nothing.
If I add the line "datatype: 'local'," to my jqGrid options, the error isn't thrown. However, data is still not being rendered either. None of the other questions suggested in "Similar Questions" solved my issue. The data is just an Id field and is a simple C# string.
Below is the aspx file contents used to render the jqGrid:
<asp:Content ID="Content2" ContentPlaceHolderID="HeadContent" runat="server">
<%--Must load language tag BEFORE script tag--%>
<script src="grid.locale-en.js" type="text/javascript"></script>
<script src="jquery.jqGrid.min.js" type="text/javascript"></script>
<script type="text/javascript">
jQuery(document).ready(function () {
jQuery("#list").jqGrid({
autowidth: true,
url: '/HouseData/GridData/',
datatype: 'local', <---instead of 'local' I also tried 'jsonstring'
mtype: 'POST',
colNames: ['House Name'],
colModel: [
{ name: 'houseName', index: 'houseName', key: true, width: 80, align: 'right', hidden: false }],
pager: jQuery('#pager'),
rowNum: 20,
rowList: [5, 10, 20, 50],
sortname: 'houseName',
sortorder: "desc",
height: 400,
viewrecords: true,
imgpath: ''
});
});
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<div id="main">
<h2>Show House Name</h2>
<div class="disignBoxFirst">
<div class="boxContent">
<%: Html.Partial("HouseDataSearch") %>
</div>
</div>
<hr />
<table id="list" class="scroll" cellpadding="0" cellspacing="0"></table>
<div id="pager" class="scroll" style="text-align:center;"></div>
</div>
</asp:Content>
The function used to compose the json string, contained in the C# file "HouseDataController.cs", is below (initially I didn't have the "datatype" option in the aspx file shown above for the jqGrid):
public JsonResult GridData(string sidx, string sord, int page, int rows, string houseName)
{
//Setup values to return to the view for display of user entered values
ViewData["HouseName"] = houseName;
//Get table data
CloudStorageAccount storageAccount = CloudStorageAccount.FromConfigurationSetting("ConnectionString");
ReportStorageDataServiceContext storageContext = new ReportStorageDataServiceContext(storageAccount.TableEndpoint.ToString(), storageAccount.Credentials);
int houseCount = 0;
IQueryable<HouseDataModel> houses = storageContext.CreateQuery<HouseDataModel>("HouseDataTable").Where(h => h.isAvailable == true);
List<HouseDataModel> queryDetails = new List<HouseDataModel>();
foreach (HouseDataModel house in houses)
{
queryDetails.Add(house);
houseCount++;
}
//Figure out paging
int pageIndex = Convert.ToInt32(page) - 1;
int pageSize = rows;
int totalRecords = houseCount;
int totalPages = (int)Math.Ceiling((float)totalRecords / (float)pageSize);
var jsonData = new
{
total = totalPages,
page,
records = totalRecords,
rows = (from house in queryDetails select new { User = house.houseName }).ToArray()
};
return Json(jsonData);
}
The error message was caught using Firebug. If this is not specific/detailed enough or if it was resolved in another thread please advise.
Thanks!
Try this:
jQuery("#list").jqGrid({
autowidth: true,
url: '/HouseData/GridData/',
datatype: 'local', <---instead of 'local' I also tried 'jsonstring'
mtype: 'POST',
colNames: ['House Name'],
colModel: [
{ name: 'houseName', index: 'houseName', key: true, width: 80, align: 'right', hidden: false }],
pager: jQuery('#pager'),
rowNum: 20,
rowList: [5, 10, 20, 50],
sortname: 'houseName',
sortorder: "desc",
height: 400,
viewrecords: true,
imgpath: '',
jsonReader : {
root: "rows",
page: "page",
total: "total",
records: "records",
repeatitems: false,
cell: "cell",
id: "id",
userdata: "userdata",
},
});
I added the jsonReader part. I had the same problem and this seems to fix it.
Try changing the jqgrid's mtype to 'GET' and datatype to 'json':
datatype: 'json'
mtype: 'GET'
and change your GridData controller action's return to:
return Json(data, JsonRequestBehavior.AllowGet);