Update chart.js after form submission and page reload - ajax

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();"

Related

how to display multiple sum with chart js and laravel?

I have three table
Table drics
Table country_dric
Table Countries
I just display country name with sum legal from table drics.
I want to display sum column legal, illegal, applicant and mandatory from table drics with country name.
How to display the sum of each column from table drics?
my controller
$drics =DB::table('countries')
->join('country_dric','countries.id','country_dric.country_id')
->join('drics','drics.id','country_dric.dric_id')
->select('name',\DB::raw('sum(legal) as sum'))->groupby('name')
->whereYear('drics.created_at', $year)->get();
$dric_title=[];
$dric=[];
foreach ($drics as $key => $value) {
$dric_title[$key]=$value->name;
$dric[$key]=$value->sum;
}
return view('home.home', compact(' 'dric', 'dric_title'));
js Code
<script>
var ctx = document.getElementById('dric').getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: #json($dric_title),
datasets: [{
label: '# ',
data: #json($dric),
backgroundColor: "rgba(0,31,68,0.8)",
borderColor: "rgb(167, 105, 0)",
borderWidth: 1,
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
</script>
Try this
Your controller:
$drics =DB::table('countries')
->join('country_dric','countries.id','country_dric.country_id')
->join('drics','drics.id','country_dric.dric_id')
->select('name',\DB::raw('sum(legal) as legal_sum')
,\DB::raw('sum(ilegal) as ilegal_sum')
,\DB::raw('sum(applicant) as applicant_sum')
,\DB::raw('sum(mandatory) as mandatory_sum'))->groupby('name')
->whereYear('drics.created_at', $year)->get();
$dric_title=[];
$dric=[];
foreach ($drics as $key => $value) {
$dric_title[$key]=$value->name;
$dric['legal'][$key]=$value->legal_sum;
$dric['ilegal'][$key]=$value->ilegal_sum;
$dric['applicant'][$key]=$value->applicant_sum;
$dric['mandatory'][$key]=$value->mandatory_sum;
}
return view('home.home', compact(' 'dric', 'dric_title'));
js code:
<script>
var ctx = document.getElementById('dric').getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: #json($dric_title),
datasets: [{
label: 'Legal',
data: #json($dric['legal']),
backgroundColor: "rgba(0,31,68,0.8)",
borderColor: "rgb(167, 105, 0)",
borderWidth: 1,
}, {
label: 'Ilegal',
data: #json($dric['ilegal']),
backgroundColor: "rgba(0,31,68,0.8)", // Change the color to make it different
borderColor: "rgb(167, 105, 0)",
borderWidth: 1,
}, {
label: 'Applicant',
data: #json($dric['applicant']),
backgroundColor: "rgba(0,31,68,0.8)", // Change the color to make it different
borderColor: "rgb(167, 105, 0)",
borderWidth: 1,
}, {
label: 'Mandatory',
data: #json($dric['mandatory']),
backgroundColor: "rgba(0,31,68,0.8)", // Change the color to make it different
borderColor: "rgb(167, 105, 0)",
borderWidth: 1,
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
</script>
You can use #foreach loop if you want too

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.

How to pass data in Laravel with Chart.js

I want to display total of men and woman from learnings table in chart using Chartjs in Laravel.
My controller
public function index()
{
$men_learning = DB::table('learnings')->where('active', 1)->whereYear('created_at', $year)->sum('men');
$women_learning = DB::table('learnings')->where('active', 1)->whereYear('created_at', $year)->sum('women');
$learning = $men_learning + $women_learning ;
return view('home', compact('learning'));
}
My script in blade view.
<script>
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['total'],
datasets: [{
label: '# of Votes',
data: [12],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
],
borderColor: [
'rgba(255, 99, 132, 1)',
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
</script>
How can I propagate loaded statistic from my script to the chart?
public function index()
{
$men_learning = DB::table('learnings')->where('active', 1)->whereYear('created_at', $year)->sum('men');
$women_learning = DB::table('learnings')->where('active', 1)->whereYear('created_at', $year)->sum('women');
return view('home', compact('men_learning', 'women_learning'));
}
<script type="text/javascript">
$(function(){
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Men', 'Women'],
datasets: [{
label: 'Men',
data: [{!!$men_learning!!}],
borderWidth: 2,
backgroundColor: 'rgba(40,167,69,1)',
borderWidth: 0,
borderColor: 'transparent',
pointBorderWidth: 0 ,
pointRadius: 3.5,
pointBackgroundColor: 'transparent',
pointHoverBackgroundColor: 'rgba(254,86,83,.8)',
},
{
label: 'Women',
data: [{!!$women_learning!!}],
borderWidth: 2,
backgroundColor: 'rgba(220,53,69,.8)',
borderWidth: 0,
borderColor: 'transparent',
pointBorderWidth: 0,
pointRadius: 3.5,
pointBackgroundColor: 'transparent',
pointHoverBackgroundColor: 'rgba(63,82,227,.8)',
}]
},
options: {
legend: {
display: false
},
scales: {
yAxes: [{
gridLines: {
display: true,
drawBorder: false,
color: '#f2f2f2',
},
ticks: {
beginAtZero: true,
stepSize: 100,
callback: function(value, index, values) {
return value;
}
}
}],
xAxes: [{
gridLines: {
display: false,
tickMarkLength: 15,
}
}]
},
}
});
});
</script>

Draw same google chart on the same page MVC

Hi there I am trying to display the same google chart on the same page. Here is my current code
<script type="text/javascript"
src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
// Bar chart
google.charts.load('current', { packages: ['corechart', 'bar'] });
google.charts.setOnLoadCallback(Mygraph);
function Mygraph() {
$.ajax({
async: false,
url: "GetGraph",
dataType: "json",
success: function (jsonData) {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Question');
data.addColumn('number', 'My Perfomance');
data.addColumn('number', 'Peers Performance');
for (var i = 0; i < jsonData.length; i++) {
data.addRow([jsonData[i].rateName, jsonData[i].myRate, jsonData[i].peerRate]);
}
var view = new google.visualization.DataView(data);
view.setColumns([0, 1,
{
calc: "stringify",
sourceColumn: 1,
type: "string",
role: "interval",
},
2, {
calc: "stringify",
sourceColumn: 2,
type: "string",
role: "interval"
}]);
var options = {
title: '',
chartArea: { width: '50%' },
backgroundColor: '#ffffff ',
hAxis: {
title: 'Rating',
minValue: 0,
textStyle: {
bold: true,
fontSize: 12,
color: '#4d4d4d'
},
titleTextStyle: {
bold: true,
fontSize: 18,
color: '#4d4d4d'
}
},
vAxis: {
title: 'Performance',
textStyle: {
fontSize: 14,
bold: true,
color: '#848484'
},
titleTextStyle: {
fontSize: 14,
bold: true,
color: '#848484'
}
}
};
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(view, options);
}
});
}
</script>
Question is how to I display the same graph twice. Currently the graph is only showing once. I want it to display twice. I am using Google graphs api Please help. Looking forward to hearing from you. Thanks for your help

Can't change color line with chart.js

I use chart.js to make a line chart but I can't change the color line of my chart, I saw it grey.
My code is...
$(document).ready(function(){
$.ajax({
url: "chart/maderas_Chart.php",
method: "GET",
success: function(data) {
console.log(data);
var hora = [];
var valor = [];
for(var i in data) {
hora.push("Hora " + data[i].hora_nueva);
valor.push(data[i].valor);
}
var chartdata = {
labels: hora,
datasets : [
{
label: 'Dique Las Maderas',
fill: false,
boderColor: "#bae755",
borderDash: [5, 5],
strokeColor: "#e755ba",
pointColor: "#55bae7",
pointStrokeColor: "#55bae7",
pointHighlightFill: "#55bae7",
pointHighlightStroke:"#55bae7",
data: valor
}
]
};
var ctx = document.getElementById("maderas_Chart");
var LineGraph = new Chart(ctx, {
type: 'line',
data: chartdata,
options: {
responsive: true,
title:{
display:true,
text:'Dique Las Maderas'
},
tooltips: {
mode: 'index',
intersect: false
},
hover: {
mode: 'nearest',
intersect: true
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Hora'
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Valor'
}
}]
}
}
});
},
error: function(data) {
console.log(data);
}
});
});
When I first confgure the chart I can change the colors but when I add more code I can't anymore, I delete all code and still can't change the line color.
I'm using chart.js version 2.7, and jquery.
Thanks in advance...
This is because, you are using deprecated properties (used in ChartJS 1.x) for setting colors. Use the following properties instead (which is applicable for ChartJS 2.7) :
datasets: [{
label: 'Dique Las Maderas',
fill: false,
borderColor: "#bae755",
borderDash: [5, 5],
backgroundColor: "#e755ba",
pointBackgroundColor: "#55bae7",
pointBorderColor: "#55bae7",
pointHoverBackgroundColor: "#55bae7",
pointHoverBorderColor: "#55bae7",
data: valor
}]

Resources