Chart.JS: How to make sharp lines to smooth curved lines - javascript

Hi I'm new at charts and this is my chartjs chart, it's working currently, but it's showing in sharp lines and I want to make it smooth curve lines on this chart. Any ideas?
function statistics(data) {
if ($('#stats-currency').length > 0) {
if (typeof(stats_currency) !== 'undefined') {
stats_currency.destroy();
}
if (typeof(data) == 'undefined') {
var currency = $('select[name="currency"]').val();
$.get(admin_url + 'home/stats_currency/' + currency, function(response) {
stats_currency = new Chart($('#stats-currency'), {
type: 'line',
data: response,
options: {
responsive:true,
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
}
}]
},
},
});
}, 'json');
} else {
stats_currency = new Chart($('#stats-currency'), {
type: 'line',
data: data,
options: {
responsive: true,
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
}
}]
},
},
});
}

This can be done through the option lineTension that needs to be defined on your dataset. Choose a value below 1.
datasets: [{
...
lineTension: 0.8
}]
By default, you should however already see curved smooth lines since accoring to Chart.js documentation, the default value is 0.4.
lineTension: Bezier curve tension of the line. Set to 0 to draw straight lines.
Please note that if the steppedLine value is set to anything other than false, lineTension will be ignored.

you can do it by adding tension value to your charts options
<canvas id="myChart"></canvas>
JS
const config = {
type: 'line', // your chart type
data: data, // pass here your data
options: {
elements: {
line: {
tension : 0.4 // smooth lines
},
},
},
};
// pass it like
const myChart = new Chart(
document.getElementById('myChart'),
config
);

Related

How to add percentage after value data in chart

I need after each value to be a percent symbol ( % ) For example: 12% instead of 12
The below code in write in laravel php for the chartpie.
<script src="{{asset('assets/admin/js/vendor/apexcharts.min.js')}}"></script>
<script src="{{asset('assets/admin/js/vendor/chart.js.2.8.0.js')}}"></script>
<script>
var ctx = document.getElementById('tokenomi');
var myChart = new Chart(ctx, {
type: 'doughnut',
data: {
labels:<?=$label?>,
datasets: [{
data:<?=$values?>,
],
borderColor: [
'rgba(231, 80, 90, 0.75)'
],
borderWidth: 0,
}]
},
options: {
aspectRatio: 1,
responsive: true,
maintainAspectRatio: true,
elements: {
line: {
tension: 0 // disables bezier curves
}
},
scales: {
xAxes: [{
display: false
}],
yAxes: [{
display: false
}]
},
legend: {
display: false,
}
}
});
</script>
Check the current chart pie below, I tried a lot but I can't find a solution.
How do I add percent sign (%) behind of all values
Thanks
You need to define a tooltips.callback.label function as shown below. For further details please consult Chart.js v. 2.8.0 documentation here.
options: {
...
tooltips: {
callbacks: {
label: (tooltipItem, data) => data.datasets[0].data[tooltipItem.index] + '%'
}
},
...
Please note that you're using a rather old version of Chart.js, the today latest stable version is 3.7.0.

ChartJS Separate Labels for each dataset/independent datasets?

I'm essentially attempting to create a bar chart with 2-8 items where the label on the bottom/legend is the short product code(ex: 4380) and mousing over the bar shows the full SKU/product name.
I have gotten it mostly working but my implementation goes one of two undesirable ways.
The data points all combine into the first product number/chart label.
The blank spots make the bars tiny/not fill up the full width.
My code for rendering the chart is as follows:
var myBarChart2;
$.ajax({
url: "chartdata.php",
data: {
"skugroup": group
},
method: 'GET',
dataType: 'json',
success: function (d) {
Chart.defaults.global.defaultFontFamily = '-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif';
Chart.defaults.global.defaultFontColor = '#292b2c';
var ctx = document.getElementById("inventorybarchart");
myBarChart2 = new Chart(ctx, {
type: 'bar',
data: {
labels: d.labels,
datasets: d.datasets,
},
options: {
scales: {
xAxes: [{
gridLines: {
display: false
},
ticks: {
display: true
}
}],
yAxes: [{
ticks: {
min: 0,
beginAtZero: true
},
gridLines: {
display: true
}
}],
},
legend: {
display: false
}
}
});
}
});
The ajax response for the two versions is as follows:
Version 1:
{"datasets":[{"labels":"GRAY-DARK-GRAY","backgroundColor":"rgba(164,222,164,1)","borderColor":"rgba(164,222,164,1)","data":[5996]},{"labels":"CANARY-YELLOW","backgroundColor":"rgba(35,148,58,1)","borderColor":"rgba(35,148,58,1)","data":[4605]},{"labels":"PINK-WHITE-GRAY","backgroundColor":"rgba(101,24,125,1)","borderColor":"rgba(101,24,125,1)","data":[1288]},{"labels":"SEAFOAM-WHITE-GRAY","backgroundColor":"rgba(129,74,64,1)","borderColor":"rgba(129,74,64,1)","data":[3463]},{"labels":"YELLOW-WHITE-GRAY","backgroundColor":"rgba(91,216,70,1)","borderColor":"rgba(91,216,70,1)","data":[1537]},{"labels":"WHITE-YELLOW","backgroundColor":"rgba(101,225,237,1)","borderColor":"rgba(101,225,237,1)","data":[152]}],"labels":["4380","4311","4571","4588","4557","4373"]}
Version 2:
{"datasets":[{"label":"GRAY-DARK-GRAY","backgroundColor":"rgba(1,1,235,1)","borderColor":"rgba(1,1,235,1)","data":[5996,null,null,null,null]},{"label":"CANARY-YELLOW","backgroundColor":"rgba(12,87,184,1)","borderColor":"rgba(12,87,184,1)","data":[null,4605,null,null,null]},{"label":"PINK-WHITE-GRAY","backgroundColor":"rgba(85,107,126,1)","borderColor":"rgba(85,107,126,1)","data":[null,null,1288,null,null]},{"label":"SEAFOAM-WHITE-GRAY","backgroundColor":"rgba(181,150,65,1)","borderColor":"rgba(181,150,65,1)","data":[null,null,null,3463,null]},{"label":"YELLOW-WHITE-GRAY","backgroundColor":"rgba(132,66,28,1)","borderColor":"rgba(132,66,28,1)","data":[null,null,null,null,1537]},{"label":"WHITE-YELLOW","backgroundColor":"rgba(49,195,217,1)","borderColor":"rgba(49,195,217,1)","data":[null,null,null,null,null]}],"labels":["4380","4311","4571","4588","4557","4373"]}
The only difference is either I always use the 0 indexes for datasets[index].data or I fill in null depending on where it should be.
Should I be changing the way the chart is rendered or should I change the way the data is passed in?
For the record, the mouseover shows the proper sku/full name.
I would define the data in a single dataset and keep the full product names in a separate property.
const data = {
"labels": ["4380", "4311", "4571", "4588", "4557", "4373"],
"productNames": ["GRAY-DARK-GRAY", "CANARY-YELLOW", "PINK-WHITE-GRAY", "SEAFOAM-WHITE-GRAY", "YELLOW-WHITE-GRAY", "WHITE-YELLOW"],
"datasets": [{
"data": [5996, 4605, 1288, 3463, 1537, 152],
...
}]
};
To get the product names displayed in the tooltip, you would have to define a label callback function as follows:
tooltips: {
callbacks: {
label: (tooltipItem, data) => {
let i = tooltipItem.index;
return data.productNames[i] + ': ' + data.datasets[0].data[i];
}
}
}
Please take a look at your amended code and see how it works.
const data = {
"labels": ["4380", "4311", "4571", "4588", "4557", "4373"],
"productNames": ["GRAY-DARK-GRAY", "CANARY-YELLOW", "PINK-WHITE-GRAY", "SEAFOAM-WHITE-GRAY", "YELLOW-WHITE-GRAY", "WHITE-YELLOW"],
"datasets": [{
"data": [5996, 4605, 1288, 3463, 1537, 152],
"backgroundColor": ["rgba(1,1,235,1)", "rgba(12,87,184,1)", "rgba(85,107,126,1)", "rgba(181,150,65,1)", "rgba(132,66,28,1)", "rgba(49,195,217,1)"],
"borderColor": ["rgba(1,1,235,1)", "rgba(12,87,184,1)", "rgba(85,107,126,1)", "rgba(181,150,65,1)", "rgba(132,66,28,1)", "rgba(49,195,217,1)"]
}]
};
var ctx = document.getElementById("inventorybarchart");
myBarChart2 = new Chart(ctx, {
type: 'bar',
data: data,
options: {
scales: {
xAxes: [{
gridLines: {
display: false
}
}],
yAxes: [{
ticks: {
beginAtZero: true
}
}],
},
legend: {
display: false
},
tooltips: {
callbacks: {
label: (tooltipItem, data) => {
let i = tooltipItem.index;
return data.productNames[i] + ': ' + data.datasets[0].data[i];
}
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.0/Chart.min.js"></script>
<canvas id="inventorybarchart" height="90"></canvas>

chart.js dynamically adjust gap between vertical bars

I am working on a webpage that presents dashboard on th basis of invoice processing project.
using below code i am populating bar chart.
function loadVolumeChart()
{
var pieChartContent = document.getElementById('chartAreaWrapper');
pieChartContent.innerHTML = '';
$('#chartAreaWrapper').append('<canvas id="line-chart" height="300" width="1500px"><canvas>');
//getData For Volume Analysis Chary
var url_string = document.referrer;;
var url = new URL(url_string);
var name = url.searchParams.get("name");
var user=url.searchParams.get("user");
var team=url.searchParams.get("team");
var date=url.searchParams.get("date");
var dates = [];
var count = [];
var from = date.split("-")[0];
var to = date.split("-")[1];
var re=$.ajax({
url: 'getTotalCounts.php',
type: 'POST',
data: {
from:from,
to:to,
team:team,
totalVolume: '00'
},
async:false,
success: function(data) {
var result =data;
var json = JSON.parse(result);
dates=json[0].data;//json[0].data;
count=json[1].data;
//alert(dates);
}
}).done(function(data){
// openPage(data);
}).fail(function(data){
alert(data.responseText);
});
//volume chart
new Chart(document.getElementById("line-chart"), {
type: 'bar', //line
data: {
labels:dates,
datasets: [{
data:count,
label: "Total Inward",
backgroundColor: "#0E6655", //borderColor
fill: true
},
]
},
options: {
responsive:false,
maintainAspectRatio: true,
legend: {
display: false
},
tooltips: {
enabled: true
},
scales: {
xAxes: [{
gridLines: {
display:false
},
barThickness: 15,
}],
yAxes: [{
barPercentage: 1.0,
categoryPercentage: 1.0,
gridLines: {
display:false
},
ticks: {
min: 0,
max:10,
stepSize: 1
}
}]
},
}
});
//end of volume chart
}
But the problem is when data is low, means if the x axis data contains only 2 dates, then the gap between two bars is too large, like the image below,
but if i add more dates then the gap reduces.i want to set gap between two bars even if their are only two bars. the gap between both should not increase if the dates (bars) according to the size of x axis data. if the data is large then it should only scroll. thats why i have added scroll bar.
the div of chart is as:
<div class="parentDiv" >
<div class="chartAreaWrapper" id="chartAreaWrapper" style="height:80%;width:70%;margin-left: 20px; margin-top: 10px;float: left;">
<canvas id="line-chart" height="300" width="1500px"></canvas>
</div>
</div>
In your code, the option xAxis.barThickness defines that the width of individual bars has to be of 15 pixels. Simply remove this option.
You should also consider to use the latest stable version of Chart.js (currently v2.9.3) where the option xAxis.barThickness is deprecated. The options barThickness, barPercentage and categoryPercentage are now part of the dataset configuration.

ChartJS, Primeng, Gap first and end of line chart

I am using primeng chart component which uses chartjs. We are using chartjs 2.5.0 alongside primeng 4.0 and angular 4.
I created a dynamic chart and I put the data into chart after it came to us through some services. The problem is, after a while chartjs will put a gap at first and end of the chart.
Here is our options for chartjs:
this.options = {
responsive: true,
tooltips: {
mode: 'index',
intersect: false, // all points in chart to show tooltip
callbacks: { // adding labels as title in tooltip
title: function(tooltipItems, data) {
let date = tooltipItems[0].xLabel;
return me._rhDatePipe.transform(date, 'time');
}
}
},
hover : {
mode: 'index',
intersect: false
},
scales: {
xAxes: [{
type: 'time',
display: false, // preventing labels from being displayed
max: 20
}],
yAxes: [{
ticks: {
maxTicksLimit: 3
}
}]
}
}
and here is our first data settings:
this.data = {
labels: this.labels, // current time as label
datasets: [
{
label: me._messageService.translate('chart-label-buy'),
data: this.buyingData,
fill: false,
borderColor: "#2453db",
lineTension: 0,
borderWidth: 1.5,
radius: 0 // removing dot points on chart
},
{
label: me._messageService.translate('chart-label-sale'),
data: this.sellingData,
fill: false,
borderColor: "#f44336",
borderWidth: 1.5,
lineTension: 0,
radius: 0 // removing dot points on chart
},
{
label: me._messageService.translate('chart-label-last-trade'),
data: this.lastPriceData,
fill: false,
borderColor: "#000000",
lineTension: 0,
borderWidth: 1.5,
radius: 0 // removing dot points on chart
}
]
}
and here is the loop which will update the chart:
if(sortedKeysList != null) {
for(let key in sortedKeysList) {
let currentTime: number = sortedKeysList[key];
// just add new points
if(!this.currentTimes.includes(currentTime)) {
let date = new Date(currentTime);
this.labels.push(date);
this.currentTimes.push(currentTime);
this.buyingData.push(this.bestLimitsChart[currentTime].buy);
this.sellingData.push(this.bestLimitsChart[currentTime].sale);
if(this.bestLimitsChart[currentTime].price != 0)
this.lastPriceData.push(this.bestLimitsChart[currentTime].price);
else
this.lastPriceData.push(null);
this.updateChart();
}
}
}
and the picture of chart:
I do not know what is going on. Any helps will greatly appreciated.
I finally found the problem,
for other people facing this issue, you can add unit to your axis:
xAxes: [{
type: 'time',
time: {
displayFormats: {
minute: 'h:mm', // formatting data in labels
},
unit: 'minute' // destroy first and end gaps
},
display: false, // preventing labels from being displayed
}],
similar issue on github:
https://github.com/chartjs/Chart.js/issues/2277#issuecomment-314662961

Chart.js how define max tick of polarArea?

I look for way to use polarArea but with limit scale (line of tick) defined at 100. Actualy the scale display scale based in max value, but I want max fixed.
var data = {
datasets: [{
data: [10,20,30,40],
}],
labels: ["Red","Green","Yellow","Grey","Blue"]
};
var polarArea = new Chart(ctx, {
data: data,
type: 'polarArea',
options: {
scale: {
ticks: {
beginAtZero: true
}
}
}
});
This marked with arrow green as I want the graph.
Can you help me?
var data = {
datasets: [{
data: [10,20,30,40],
}],
labels: ["Red","Green","Yellow","Grey"]
};
var polarArea = new Chart(ctx, {
data: data,
type: 'polarArea',
options: {
scale: {
ticks: {
min: 0,
max: 100
}
}
}
});
A JSFiddle would be super helpful for your exact situation, but based on the information provided, this should do it for you. http://jsfiddle.net/andrewborem/vup9o5fx/

Categories