Chartist line graphs animation starts from the bottom - javascript

I'm using Chartist.js to generate line graphs, It works great, but I notice lines animation starts at the beginning in a certain height from chart bottom by default:
How can I modify my code to start lines animation from the bottom of the chart like this:
This is my code:
function graph(month,shop,sale){
var data = {
labels: month,
series: [sale,shop]
};
var options = {
fullWidth:true,
height: 380,
showPoint: true,
low: 0,
showArea: true,
lineSmooth: false,
plugins: [
Chartist.plugins.legend({
legendNames: ['Sale', 'Shop'],
})
]
};
var chart = new Chartist.Line('.ct-chart', data, options);
chart.on('draw', function(data) {
if(data.type === 'point') {
var circle = new Chartist.Svg('circle', {
cx: [data.x], cy:[data.y], r:[5],
}, 'ct-circle');
data.element.replace(circle);
}
});
chart.on('draw', function(data) {
if(data.type === 'line' || data.type === 'area') {
data.element.animate({
d: {
begin: 1000 * data.index,
dur: 1000,
from: data.path.clone().scale(1, 0).translate(0, data.chartRect.height()).stringify(),
to: data.path.clone().stringify(),
easing: Chartist.Svg.Easing.easeOutQuint
}
});
}
});
}
var data = {
labels: ['Enero', 'Febrero', 'Marzo','Abril','Mayo','Junio']
};
var options = {
fullWidth:true,
height: 380
};
new Chartist.Line('.ct-chart', data, options);
$(document).ready(function(){
$.ajax({
url: "myfile.php",
type: "GET",
dataType: "json",
success: function(resp)
{
var month = resp[0];
var shop = resp[1];
var sale = resp[2];
graph(month,shop,sale);
}
});
});
I would like some help.

If you inspect the elements with the google developer tools, you will find out that the class "ct-series ct-series-b" from the chart, has an specific height that it doesn't go all the way down. If you then change in the animation when the chart is drawing to something like:
from: data.path.clone().scale(1, 0).translate(0, data.chartRect.height() + 15).stringify(),
The line will start from the height of the ct-series-b + 15px all the way up to the circle points.
Hope it helps, Leo.

Related

Chart.js bar chart is not rendering after updating data after ajax request

in my current project, a bar chart is to be updated dynamically, i.e. when a button is used to go forward or back a month, the data for that month is to be displayed.
First I load an empty chart and then load the data into the chart so that it can be displayed.
I use Chart.js and my Pie Charts, which I use, can be updated without further ado, but when I try to do this with this Bar Chart, the labels and data are read out and also displayed, but not rendered. If i load the page in the logs i got 60 time the error GET "http:://localhost/fitnesslaeufer-redesign/diary/undefined, but only with this code. If i add this all in one function everything is working fine.
What am i doing wrong?
Expacted Look / Output:
Current status:
Data and Labels will be loaded / updated but not rendered:
Error Messages:
Example Output from the Ajax call:
[{"training_date":"01.09.2021","distance":0},{"training_date":"02.09.2021","distance":0},{"training_date":"03.09.2021","distance":0},{"training_date":"04.09.2021","distance":0},{"training_date":"05.09.2021","distance":0},{"training_date":"06.09.2021","distance":0},{"training_date":"07.09.2021","distance":0},{"training_date":"08.09.2021","distance":0},{"training_date":"09.09.2021","distance":0},{"training_date":"10.09.2021","distance":0},{"training_date":"11.09.2021","distance":0},{"training_date":"12.09.2021","distance":0},{"training_date":"13.09.2021","distance":0},{"training_date":"14.09.2021","distance":0},{"training_date":"15.09.2021","distance":0},{"training_date":"16.09.2021","distance":0},{"training_date":"17.09.2021","distance":0},{"training_date":"18.09.2021","distance":0},{"training_date":"19.09.2021","distance":0},{"training_date":"20.09.2021","distance":0},{"training_date":"21.09.2021","distance":0},{"training_date":"22.09.2021","distance":0},{"training_date":"23.09.2021","distance":0},{"training_date":"24.09.2021","distance":0},{"training_date":"25.09.2021","distance":0},{"training_date":"26.09.2021","distance":0},{"training_date":"27.09.2021","distance":0},{"training_date":"28.09.2021","distance":0},{"training_date":"29.09.2021","distance":0},{"training_date":"30.09.2021","distance":0}]
userDiaryMonthTrainingDistanceStatsChart();
var userDiaryMonthTrainingDistanceStats = userDiaryMonthTrainingDistanceStatsChart();
userDiaryMonthTrainingDistanceStatsData(user_id, filtermonth, filteryear, userDiaryMonthTrainingDistanceStats);
function userDiaryMonthTrainingDistanceStatsChart() {
var options = {
legend: {
display: false,
position: 'top',
labels: {
fontSize: 16,
boxWidth: 40,
}
},
plugins: {
labels: {
render: 'value',
fontSize: 14,
fontStyle: 'bold'
}
},
layout: {
padding: {
left: 0,
right: 0,
top: 30,
bottom: 0
}
}
};
var ctx = $("#monthly_training_distance_stats");
var userDiaryMonthTrainingDistanceStats = new Chart(ctx, {
type: 'bar',
data: {
datasets: [{
backgroundColor: '#00a3ff',
borderColor: '#00a3ff',
hoverBackgroundColor: '#CCCCCC',
hoverBorderColor: '#666666',
}]
},
options: options
});
return userDiaryMonthTrainingDistanceStats
}
function userDiaryMonthTrainingDistanceStatsData(user_id, month, year, chart) {
$.ajax({
url: "../diary/includes/training/diary-training-monthly-training-distance-stats.php?user_id=" + user_id + "&month=" + month + "&year=" + year,
type: "GET",
success: function(monthly_training_distance_stats) {
var distance = [];
var training_date = [];
for(var i in monthly_training_distance_stats) {
distance.push(monthly_training_distance_stats[i].distance),
training_date.push(monthly_training_distance_stats[i].training_date)
}
var userMonthlyTrainingDistanceStatsDataLabels = [training_date];
var userMonthlyTrainingDistanceStatsData = [distance];
chart.data.labels[0] = [training_date];
chart.data.datasets[0].labels = [training_date];
chart.data.datasets[0].data = [distance];
chart.update();
}
})
}
After a lot of testing and researching, I found the solution.
In my code I have to update the chart data in the for loop of the function (userDiaryMonthTrainingDistanceStatsData()).
function userDiaryMonthTrainingDistanceStatsData(user_id, month, year, chart) {
$.ajax({
url: "../diary/includes/training/diary-training-monthly-training-distance-stats.php?user_id=" + user_id + "&month=" + month + "&year=" + year,
type: "GET",
success: function(monthly_training_distance_stats) {
var distance = [];
var training_date = [];
for(var i in monthly_training_distance_stats) {
distance.push(monthly_training_distance_stats[i].distance),
training_date.push(monthly_training_distance_stats[i].training_date)
chart.data.labels = training_date;
chart.data.datasets.labels = training_date;
chart.data.datasets[0].data = distance;
chart.update();
}
}
})
}

Bubble chart change X label values from a value in JSON response dynamically

I have a bubble chart using Chart.JS and getting my values dynamically from the database. The plotting of the data works absolutely fine, however I am trying to make a few formatting tweaks to the chart.
I want to change the X values to show the category (it is in my JSON output) on the horizontal axis rather than the i value. The JSON output contains category which is a string but I cant seem to do x: bubbleDatas[i].category?
The output currently shows on my x axis: 0,1,2,3,4,5 but i want it so show the value category from my JSON response which is in bubbleDatas?
data e.g.:
{
x: 0,
y: 60,
r: 10
}, {
x: 1,
y: 20,
r: 10
},
{
x: 2,
y: 40,
r: 10
}...
In my JSON response ajax request my X values i want it to be text:
e.g. 01_First, 02_Second
$(function () {
var bubbleData = [];
var xAxisLabels;
$.ajax({
type: "POST",
async: false,
url: "ExecView.aspx/ReturnData",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
var bubbleDatas = data.d;
bubbleData = new Array(bubbleDatas.length);
console.log(bubbleDatas);
for (i = 0; i < bubbleDatas.length; i++) {
if (bubbleDatas[i].score >= 60) {
rgbcolour = "#008000";
}
else if (bubbleDatas[i].score >= 50 && bubbleDatas[i].score < 60) {
rgbcolour = "#FFA500";
}
else {
rgbcolour = "#FF6347";
}
bubbleData[i] = { **x: i,** y: bubbleDatas[i].score, r: bubbleDatas[i].radius, backgroundcolor: rgbcolour };
console.log(bubbleData[i]);
}
}
});
var popData = {
datasets: [{
label: "Test",
data: bubbleData
}]
};
var bubbleOptions = {
responsive: true,
legend: {
display: false
},
tooltips: {
callbacks: {
label: function (t, d) {
return d.datasets[t.datasetIndex].label +
': (Category:' + t.xLabel + ', Score:' + t.yLabel + ')';
}
}
},
scales: {
yAxes: [{
ticks: {
// Include a % sign in the ticks
callback: function (value, index, values) {
return value + '%';
}
}
}]
}
};
var ctx5 = document.getElementById("bubble_chart").getContext("2d");
new Chart(ctx5, { type: 'bubble', data: popData, options: bubbleOptions });
});
Changing category to more meaning might be your specific requirement, check this fiddle if it helps bubble chartJS fiddle and check this labelling in chartJS
P.S. check out your condition for x-axis in the callback and print accordingly

Sum of visible Points in ChartJs Bar Chart

the chartjs has the option to hide datasets by clicking on the label. I want to sum up all points of the barchart, but only the visible ones. I know how to sum up all points, but don't know how to check if the dataset is Visible or not. To sum up the points I use the onComplete animation event:
animation: {
onComplete: function(animation) {
var sqm = 0;
this.data.datasets.forEach(function (dataset) {
dataset.data.forEach(function (points) {
sqm = sqm + points;
})
})
$("#SquareMeterSurface").val(sqm);
}
},
here is how it looks like:
How can I do the sum for visible datasets only (in the graph above the blue ones are not visible)? I use ChartJs 2.8
thanks
So I found the solution by myself. In the 'animation' variable passed to the onComplete callback is an array 'animation.chart.active' which can be looped to find the active dataset Indexes. The active array is only populated when hovering over the bars of the graph, thats why the sum of points are only displayed when hovering over the bars.
The whole code looks now like this:
function success_(data) {
var ctx = document.getElementById('canvas').getContext('2d');
window.myBar = new Chart(ctx, {
type: 'bar',
data: data,
options: {
title: {
display: true,
text: 'Square Meters done per day'
},
tooltips: {
mode: 'index',
intersect: false
},
maintainAspectRatio: false,
responsive: true,
scales: {
xAxes: [{
stacked: true
}],
yAxes: [{
stacked: true
}]
},
animation: {
onComplete: function(animation) {
//alert('onAnimationComplete');
if (typeof animation.chart !== 'undefined' && typeof animation.chart.active !== 'undefined') {
var active_datasets = new Array();
//loop through active dataset to get the dataset indexes
//which are visible to the user
animation.chart.active.forEach(function(active_ds) {
active_datasets.push(active_ds._datasetIndex);
})
//loop through datasets to get the points for active datasets
var sqm = 0;
var i = 0;
this.data.datasets.forEach(function (dataset) {
if (active_datasets.indexOf(i) != -1) {
dataset.data.forEach(function (points) {
sqm = sqm + points;
})
}
i = i + 1;
})
$("#SquareMeterSurface").val(parseFloat(sqm).toFixed(1) + ' m2');
}
}
},
}
});
};
and the ajax call to invoce a .Net Core MVC action is like this:
$.ajax({
url: '/YourController/YourActionForGraph/',
type: 'GET',
data: {
'param1': $('#param1').val(),
'param2': $('#param2').val()
},
dataType: 'json',
success: success_,
error: function (request, error) {
alert("Request: " + JSON.stringify(request));
}
});
Thanks for your hint. This one helped me, so I came up with the following solution:
`const options = {
radius: "100%",
cutout: "90%",
animation: {
onComplete: function (animation) {
console.log(animation.chart.getDatasetMeta(0));
},
},
};`
You can call getDatasetMeta(index) on the chart object and you will get an object with all current data used to construct the chart. Here you find the total property with the current sum.
See: https://www.chartjs.org/docs/latest/developers/api.html#getdatasetmeta-index

HighCharts : Tooltips exist but line is not drawn in the chart

I met with a problem on HighCharts.
I had to gather data from a xml content with ajax in order to draw it in a HighCharts chart.
I get my datas. I can see my points when I move my mouse over it but my chart is not displaying anything.
A picture to see the problem :
mouse over the third point
And some parts from my code if it can help :
var myData=[];
function makeChart() {
var chart;
$(document).ready(function () {
chart = new Highcharts.Chart({
chart: {
renderTo: 'container2',
type: 'spline',
borderColor: '#DC143C',
borderRadius: 20,
borderWidth: 2,
marginRight: 130,
marginBottom: 25
},
title: {
text: ''
},
xAxis: {
categories :[0,1,2,3,4,5]
},
yAxis: {
title: {
text: 'Values'
},
},
series: [{
color: '#FF00FF',
name: '',
data: myData
}]
});
});
}
$(function (){
$(document).ready(function ping(){
ChartDeOuf();
makeChart();
$.ajax({
type: "GET",
url: 'http://localhost:8080/SASI/runSimulation',
dataType: "xml",
success: function(result){
var i = 0;
var xmlDoc = $.parseXML(result);
var chart = $('#container2').highcharts();
$result = $(xmlDoc);
$(result).find('measure').each(function(){
var $value = $(this);
var attr = $value.attr("meanValue");
myData[i]=attr;
var html = '<p> '+myData[i]+'</p>';
chart.series[0].addPoint({y: myData[i]},false);
chart.redraw();
$('body').append($(html));
i++;
})
},
error: function(result){
alert('timeout/error');
}
});
});
});
Thanks for reading.
Got it, that line saved everything :
myData[i]=parseFloat(attr);

Highcharts - column chart redraw animation

I'm trying to update an existing data series with a new data array and invoke the redraw function when done. While this works perfectly, I'm not quite satisfied as I'd like to have a sort of grow/shrink transition. I have seen an example by Highcharts (fiddle around with the existing data set then click on the button "Set new data to selected series") but I can't replicate this behavior.
This is what code that I've written:
var series, newSeriesThreshold = this.chart.series.length * 2;
for (var i = 0; i < data.length; i += 2) {
series = {
name: this.data[i].title,
data: this.data[i].data,
color: this.data[i].color
};
if (i >= newSeriesThreshold) {
this.chart.addSeries(series, false);
} else {
var currentSeries = this.chart.series[i / 2];
currentSeries.setData(series.data, false);
}
}
this.chart.redraw();
These are the options when creating the chart:
var config = {
chart: {
renderTo: $(this.container).attr('id'),
type: this.settings.type,
animation: {
duration: 500,
easing: 'swing'
}
},
title: {
text: null
},
legend: {
enabled: this.settings.legend.show
},
tooltip: {
formatter: function() {
return this.x.toFixed(0) + ": <b>" + this.y.toString().toCurrency(0) + '</b>';
}
},
xAxis: {
title: {
text: this.settings.xaxis.title,
style: {
color: '#666'
}
}
},
yAxis: {
title: {
text: this.settings.yaxis.title,
style: {
color: '#666'
}
}
},
series: series,
plotOptions: {
column: {
color: '#FF7400'
}
},
credits: {
enabled: false
}
};
This yields an immediate update without transitioning effects. Any ideas what I might be doing wrong?
I have solved this problem by destroying and creating again the chart.
Here is the link on highcharts forum that helps me : http://forum.highcharts.com/highcharts-usage/animation-on-redraw-t8636/#p93199
The answer comes from the highcharts support team.
$(document).ready(function() {
var chartOptions = {
// Your chart options
series: [
{name: 'Serie 1' , color: '#303AFF', data: [1,1,1,1,1,1,1}
]
};
var chart = new Highcharts.Chart(chartOptions);
$("#my_button").click(function(){
chart.destroy();
chartOptions.series[0].data = [10,5,2,10,5,2,10];
chart = new Highcharts.Chart(chartOptions);
});
});
This remain a mystery. I managed to make the axis update which suggests that there is some kind of animation going on, but it's applied only to the axis, and not the columns.
In the end, I've settled with this behavior.
This might help:
var mychart = $("#mychart").highcharts();
var height = mychart.renderTo.clientHeight;
var width = mychart.renderTo.clientWidth;
mychart.setSize(width, height);
to update all charts
$(Highcharts.charts).each(function(i,chart){
var height = chart.renderTo.clientHeight;
var width = chart.renderTo.clientWidth;
chart.setSize(width, height);
});

Categories

Resources