highcharts render does not match grid in docraptor rendered pdf - laravel

Bottom of highcharts rendered chart in pdf
I am attempting to render a highcharts chart inside a blade template and then pass the resulting view/html to DocRaptor in order to turn it into a pdf. The view is rendered with Laravel's View::make and then the render() function. Everything is working as expected except the rendered bars do not match up to the tick marks on the yAxis (horizontal).
I've included an image of what I'm referring to. In the image 2 of the bars (Saturn and Lexus) should be past the 1M tick and I would expect Acura to be further right towards the 1M tick mark. The image only contains the last 3 bars in the graph, but the same holds true for the series as whole.
Less relevent is that I've essentially split up the series data into small enough chunks such that the chart would fit on a page (hence the jQuery $.each()).
The code that produces the chart is below. The code inside the load and render functions are both executed as the document.write debug statements. Any help/ideas would be appreciated.
$("div[id^='Chart_chunk_count_']").each(function() {
var myChart = Highcharts.chart($(this).attr("id"), {
chart: {
borderWidth: 0,
events: {
load: function(event) {
document.write('In load event');
},
render: function(event) {
document.write('In render event');
}
},
height: j_audience_chart_chunks['metadata']['page'][$(this).data("chart-page")]['height'],
type: 'bar',
width: 650
},
credits: {
enabled: false
},
legend: {
enabled: false
},
plotOptions: {
bar: {
borderRadius: 3,
borderWidth: 0,
color: j_audience_chart_chunks['metadata']['count_chart']['color'],
pointWidth: 30,
turboThreshold: 0
},
series: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
/* allowOverlap: true, */
/* backgroundColor: '#FA9005', */
color: '#606060',
crop: false,
defer: false,
enabled: true,
format: '{point.y:,.0f}',
inside: true,
/* overflow: 'none', */
style: {
fontSize: "11px",
fontWeight: "normal",
textOutline: 'none'
}
}
}
},
title: {
text: (type == "index") ? "Index Against Profiled Audience" : "Audience Count"
},
tooltip: {
enabled: false
},
xAxis: {
categories: j_audience_chart_chunks['audience_data'][$(this).data("chart-page")]['categories'],
minorTickInterval: null,
title: {
text: null
}
},
yAxis: {
min: (type == 'count') ? 0 : -100,
max: j_audience_chart_chunks['metadata']['count_chart']['max'],
title: {
text: null
},
labels: {
/* format: '{point.y:,.0f}', */
overflow: 'justify'
/*
style: {
color: '#fa9005'
}
*/
}
},
series: j_audience_chart_chunks['audience_data'][$(this).data("chart-page")]['series']
});
});

What's happening is that the JavaScript finishes and DocRaptor/Prince begins building the PDF, but the default Highcharts animations haven't finished running. Disabling animations chart wide fixes this.
You need set chart.animation to false like:
chart: {
animation: false
}

Related

How to show values on the bar vertically in apex bar chart

I am using apex bar chart in which i want to show values on the bar vertically but it shows horizontally.
I search alot to show value vertically but not find any solution. Please help me to solve this issue. I also share the code.
Here is The script of graph:
<script type="text/javascript">
$(document).ready(function() {
// custom datalabelBar
var options = {
chart: {
height: 350,
type: 'bar',
toolbar: {
show: true
}
},
plotOptions: {
bar: {
horizontal: false,
dataLabels: {
position: 'top',
},
}
},
dataLabels: {
enabled: true,
position: 'top',
formatter: function (val) {
return val ;
},
horizontal: true,
offsetX: 0,
style: {
fontSize: '10px',
colors: ['#000']
}
},
stroke: {
show: false,
width: 1,
colors: ['#fff'],
lineCap: 'round',
curve: 'smooth',
},
series: [{
name: 'Packing',
data: <?php echo json_encode($wd_packing) ?>
}, {
name: 'Dispatch',
data: <?php echo json_encode($wd_dispatch) ?>
},
{
name: 'Remaning',
data: <?php echo json_encode($wd_reaming) ?>
}],
xaxis: {
categories: <?php echo json_encode($wd_week) ?>,
},
}
var chart = new ApexCharts(
document.querySelector("#weekly_dispatch_graph"),
options
);
chart.render();
});
Here is the screenshot of graph:
Please Help me to solve this issue. Thanks in advance.
It is possible! Your question is about dataLabels. ApexCharts give us a common dataLabels option and a dataLabels option depended on chart type. There are options.dataLabels and options.plotOptions.bar.dataLabels respectively.
In the first one you can play with offsetY and in the second one you can configure this labels orientation and their position.
Try to play with this values, good luck :)
var options = {
chart: {
type: 'bar'
},
series: [{
name: 'Packing',
data: [300000, 300000, 500000, 800000]
}, {
name: 'Dispatch',
data: [46577, 296948, 153120, 0]
},
{
name: 'Remaning',
data: [252962, 2382, 235143, 800000]
}
],
xaxis: {
categories: ['Week 1', 'Week 2', 'Week 3', 'Week 4'],
},
plotOptions: {
bar: {
dataLabels: {
orientation: 'vertical',
position: 'center' // bottom/center/top
}
}
},
dataLabels: {
style: {
colors: ['#000000']
},
offsetY: 15, // play with this value
},
}
var chart = new ApexCharts(document.querySelector("#chart"), options);
chart.render();
<div id="chart"></div>
<script src="https://cdn.jsdelivr.net/npm/apexcharts#3.18.1/dist/apexcharts.min.js"></script>
dataLabels: {
position: 'top',
enabled: true,
textAnchor: 'start',
style: {
fontSize: '10pt',
colors: ['#000']
},
offsetX: 0,
horizontal: true,
dropShadow: {
enabled: false
}
},
Note the offsetX: 0 and horizontal: true.

Update chart.js after form submission and page reload

I have a chart.js bar chart that pulls data via an ajax call to a Django APIView. The ajax call returns one dictionary with a stack of data inside I use to customize the chart. Here's the chart.js code:
var current_year = '{% url "saveskore:api-current-year-savings" %}'
$.ajax({
url: current_year,
type: 'GET',
cache: false,
dataType: 'json',
success: function(data) {
var ctx = document.getElementById('current-year-chart');
var chart = new Chart(ctx, {
type: 'bar',
data: {
labels: data['dates'],
datasets: [
{
label: data['income_label'],
backgroundColor: "#8e5ea2",
data: data['income'],
},
{
label: data['expense_label'],
backgroundColor: 'green',
data: data['expenses'],
},
{
label: data['savings_label'],
backgroundColor: "#3e95cd",
data: data['savings_goal'],
},
{
label: data['avail_label'],
backgroundColor: "#pink",
data: data['avail_to_spend'],
},
]
},
options: {
legend: { display: false },
title: {
display: true,
text: 'Savings for ' + data['year']
}
}
});
}
});
Works great. Looks great.
But! I have a django formset on a separate page that updates the table data that the chart pulls from.
When I update the data in the formset and submit, redirecting to the chart page ... NO UPDATE OCCURS.
If I make some code change or otherwise reload the browser, VOILA, the chart updates.
I have read about either cache=false and chart.update(), but find i have not been able to make either work, mainly because the exact details on their use are not clear.
I would really appreciate input on this.
Have you tried chart.destroy() method ? and then build again the chart with the new data .. that works for me.. take a look at my example
let flag = 0;
var xChart = "";
function dibujar(valor, meses) {
try {
if (valor.length > 0) {
$('#grafico').fadeIn('fast');
var canvas = document.getElementById('chart');
let tipGra = $('#slcTipGra').val();
if (flag !== 0) {
xChart.destroy();
}
//rgba(54, 162, 235, 0.2)
if (tipGra === "bar" || tipGra === "horizontalBar") {
var data = {
labels: meses,
datasets: [
{
label: "Dólares($)",
backgroundColor: "#3e95cd",
borderColor: "#3e95cd",
borderWidth: 2,
hoverBackgroundColor: "#3e95cd",
hoverBorderColor: "#3e95cd",
data: valor,
}
]
};
var option = {
title: {
display: true,
fontSize: 20,
fontFamily: 'Helvetica',
text: 'Reporte Mensual de Ventas'
},
plugins: {
datalabels: {
color: 'white',
anchor: 'end',
align: 'start',
font:
{
weight: 'bold'
}
}
},
scales: {
yAxes: [{
stacked: true,
gridLines:
{
display: true,
color: "rgba(255,99,132,0.2)"
}
}],
xAxes: [{
gridLines: {
display: true
}
}]
}
};
}
if (tipGra === 'line') {
var data = {
labels: meses,
datasets: [
{
label: "Dólares($)",
fill: false,
lineTension: 0.1,
backgroundColor: "rgba(75,192,192,0.4)",
borderColor: "rgba(75,192,192,1)",
borderCapStyle: 'butt',
borderDash: [],
borderDashOffset: 0.0,
borderJoinStyle: 'miter',
pointBorderColor: "rgba(75,192,192,1)",
pointBackgroundColor: "#fff",
pointBorderWidth: 1,
pointHoverRadius: 5,
pointHoverBackgroundColor: "rgba(75,192,192,1)",
pointHoverBorderColor: "rgba(220,220,220,1)",
pointHoverBorderWidth: 2,
pointRadius: 5,
pointHitRadius: 10,
data: valor,
}
]
};
var option = {
title: {
display: true,
fontSize: 20,
fontFamily: 'Helvetica',
text: 'Reporte Mensual de Ventas'
},
plugins: {
datalabels: {
backgroundColor: function (context) {
return context.dataset.borderColor;
},
borderRadius: 4,
color: 'white',
anchor: 'end',
align: 'end',
}
},
showLines: true
};
}
xChart = new Chart(canvas,
{
type: tipGra,
data: data,
options: option
});
flag = 1;
}
else {
$('#grafico').fadeOut('fast');
$('#graficoMessage').fadeIn('slow');
}
} catch (err) {
console.log(err);
}
}
I declare "xChart" as a global variable and a flag to know if it's the first chart to build. The example build 3 different types of charts (Vertical Bar, Horizontal Bar and Line) depending on the selection of the chart type "let tipGra = "$('#slcTipGra').val();"

How to change the labels to the image (icon) in bar chart.js

Help me, please.
How to change the labels to the image (icon) in bar chart.js ?
I mean, change from this
change labels: "LifeWall_files/logo.png","Bodily Functions","Sleep"
to this
bottom icons
The easiest way to do this would be to get a font that includes these icons and then set the font family for the ticks
...
options: {
scales: {
xAxes: [{
ticks: {
fontFamily: 'FontAwesome'
}
}]
}
}
};
and then specify the appropriate character codes in your labels
labels: ["\uf24e", "\uf1b9", "\uf242", "\uf0fc", "\uf236"],
With the FontAwesome CSS, the above would give you
The Plugin Core API offers a range of hooks that may be used for performing custom code. You can use the afterDraw hook to draw images (icons) instead of tick labels directly on the canvas using CanvasRenderingContext2D.
You'll also have to instruct Chart.js not to display the default tick labels. This can be done through the following definition inside the chart options.
scales: {
xAxes: [{
ticks: {
display: false
}
}],
Further you need to define some padding at the bottom of the chart, otherwise you'll see only part of the images.
layout: {
padding: {
bottom: 30
}
},
Please have a look at the runnable code snippet below.
const labels = ['red vans', 'blue vans', 'green vans', 'gray vans'];
const images = ['https://i.stack.imgur.com/2RAv2.png', 'https://i.stack.imgur.com/Tq5DA.png', 'https://i.stack.imgur.com/3KRtW.png', 'https://i.stack.imgur.com/iLyVi.png'];
const values = [48, 56, 33, 44];
new Chart(document.getElementById("myChart"), {
type: "bar",
plugins: [{
afterDraw: chart => {
var ctx = chart.chart.ctx;
var xAxis = chart.scales['x-axis-0'];
var yAxis = chart.scales['y-axis-0'];
xAxis.ticks.forEach((value, index) => {
var x = xAxis.getPixelForTick(index);
var image = new Image();
image.src = images[index],
ctx.drawImage(image, x - 12, yAxis.bottom + 10);
});
}
}],
data: {
labels: labels,
datasets: [{
label: 'My Dataset',
data: values,
backgroundColor: ['red', 'blue', 'green', 'lightgray']
}]
},
options: {
responsive: true,
layout: {
padding: {
bottom: 30
}
},
legend: {
display: false
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}],
xAxes: [{
ticks: {
display: false
}
}],
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="myChart" height="90"></canvas>

In kendo UI how to draw vertical line in a line chart

How to draw a vertical line in a line chart using Html5 and kendo UI ? can anyone help me out to solve this problem ?
Try this:
// let chart be the id
$("#chart").kendoChart({
categoryAxis: {
notes: {
line: {
length: 300
},
data: [{
value: new Date(2012, 0, 3),
label: {
text: "-" //text you want to show
}
}]
}
}
});
Demo: http://jsbin.com/obuweca/26
/* WITHOUT CIRCLE */
$("#chart").kendoChart({
categoryAxis: {
notes: {
line: {
length: 300
},
icon: {
border: {
width: 0
}
},
// Initial notes
data: [{
value: new Date(2012, 0, 3)
}]
}
}
});
DEMO: http://jsbin.com/obuweca/29/
In kendo documentation is example how do draw custom lines on chart. Horizontal and vertical.
http://docs.telerik.com/kendo-ui/controls/charts/how-to/custom-plot-bands
You can customize lines by editing stroke:
stroke: {
color: "red",
width: 1,
dashType:"dash"
}
You can also try to use the column-Chart.
Just extend the series:
series: [{
type: "line",
field: "value",
categoryField: "date"
},
{
type:"column",
field: "valueColumn",
gap: 300
}]
and the dataSource.data with a new field like: valueColumn.
See also the Example.

Rerender funnel highcharts with new data

I am using highcharts in my MVC3 application and I am trying to refresh once the data is modified but the chart doesnot refresh.
I am drawing the chart as follows:-
function initializeChart() {
chart1 = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'funnel'
},
title: {
text: 'Deal Funnel Stats',
x: -50
},
legend: {
enabled: false
},
exporting: {
buttons: {
exportButton: {
enabled:false
},
printButton: {
enabled:false
}
}
},
plotOptions: {
series: {
dataLabels: {
enabled: true,
format: '<b>{point.name}</b> ({point.y:,.0f})',
color: 'black',
softConnector: true
},
neckWidth: '0%',
neckHeight: '0%'
//-- Other available options
// height: pixels or percent
// width: pixels or percent
}
},
series: [{
data: #Html.Raw(Model.seriesData)
}]
});
}
Model.seriesData is coming from the the class.
Once the data is refreshed i want to reinitialize the chart with new data but it is again drawing the same chart.
Update:
The data I am having first time is:
The data I am having second time is:
Please help.
Thanks.

Resources