I have a dataset in which the last value is always very high. This causes an issue with my bar chart; almost all the other values are hard to get a feeling for without hovering over them.
Here is a screenshot:
This is what I am trying to achieve;
So my question; is this possible within vanilla Chart.js or do I need a plugin? And if so; is there an existing plugin or do I need to write one myself?
I am also open for alternative solutions to the initial problem.
I've looked all over the internet for something like this but unfortunately without much luck.
You can use logarithmic type yAxis
Default: linear
https://www.chartjs.org/docs/latest/axes/cartesian/logarithmic.html
var ctx = document.getElementById('myChart');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["January", "February", "March", "April", "May", "June"],
datasets: [{
label: "Series 1",
backgroundColor: "rgba(255,99,132,0.2)",
borderColor: "rgba(255,99,132,1)",
borderWidth: 2,
hoverBackgroundColor: "rgba(255,99,132,0.4)",
hoverBorderColor: "rgba(255,99,132,1)",
data: [65, 59, 43, 81, 56, 950],
}]
},
options: {
scales: {
yAxes: [{
type: 'logarithmic',
ticks: {
callback: function(tick, index, ticks) {
return tick.toLocaleString();
}
}
}]
}
}
});
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.8.0"></script>
<canvas id="myChart" width="400" height="200"></canvas>
Optimized ticks
50 * (Math.floor(i / 50)), // lower 50
50 * (Math.ceil(i / 50)) // higer 50
var ctx = document.getElementById('myChart');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["January", "February", "March", "April", "May", "June"],
datasets: [{
label: "Series 1",
backgroundColor: "rgba(255,99,132,0.2)",
borderColor: "rgba(255,99,132,1)",
borderWidth: 2,
hoverBackgroundColor: "rgba(255,99,132,0.4)",
hoverBorderColor: "rgba(255,99,132,1)",
data: [65, 59, 43, 81, 56, 950],
}]
},
options: {
scales: {
yAxes: [{
type: 'logarithmic',
ticks: {
callback: function(tick, index, ticks) {
return tick.toLocaleString();
}
},
afterBuildTicks: function(pckBarChart) {
pckBarChart.ticks = pckBarChart.chart.data.datasets[0].data.flatMap(i => [
50 * (Math.floor(i / 50)), // lower 50
50 * (Math.ceil(i / 50)) // higer 50
])
}
}]
}
}
});
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.8.0"></script>
<canvas id="myChart" width="400" height="200"></canvas>
Related
I want to create a chart from chart js library. The code of script of bar chart is written in some .js file means its not in html now I want to add that script inside my html when i do it then chart not get prepared then I tried window.onload=function(){Here is the code snippet of chartjs dataset}. This working fine one chart prepared but I want it 4 times same chart with different ids then it not work it only print chart in last div
window.onload = function () {
window.myBar = new Chart(document.getElementById("bars1"), {
type: "bar",
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [
{
label: "Bags",
backgroundColor: "#7e3af2",
// borderColor: window.chartColors.blue,
borderWidth: 1,
data: [66, 33, 43, 12, 54, 62, 84, 100],
},
],
},
options: {
responsive: true,
legend: {
display: false,
},
},
});
};
<div class="min-w-0 p-4 bg-white rounded-lg shadow-xs dark:bg-gray-800">
<h4 class="mb-4 font-semibold text-gray-800 dark:text-gray-300">
Bars
</h4>
<canvas id="bars1"></canvas>
<div class="flex justify-center mt-4 space-x-3 text-sm text-gray-600 dark:text-gray-400">
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
same chart i want 4 times if i paste this same div below this div with different id in canavs tag and getelementbyid then it wont work only last div chart get printed
Explained
does this solve your problem? if not please provide more details
let ids = ['bars1', 'bars2', 'bars3', 'bars4']
ids.forEach(id => {
window.myBar = new Chart(document.getElementById(id), {
type: "bar",
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [
{
label: "Bags",
backgroundColor: "#7e3af2",
// borderColor: window.chartColors.blue,
borderWidth: 1,
data: [66, 33, 43, 12, 54, 62, 84, 100],
},
],
},
options: {
/* to remove the legend */
plugins: {
legend: {
display: false,
},
},
responsive: true,
},
});
})
<canvas id="bars1"></canvas>
<canvas id="bars2"></canvas>
<canvas id="bars3"></canvas>
<canvas id="bars4"></canvas>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
you can just store the ids of all the canvas elements and loops over that array while adding a chart to the respective element with the id
<canvas id="bars1"></canvas>
<canvas id="bars2"></canvas>
<canvas id="bars3"></canvas>
<canvas id="bars4"></canvas>
<script>
window.onload = function(){
const ids = ['bars1', 'bars2', 'bars3', 'bars4']
ids.forEach((id) => {
window.myBar = new Chart(document.getElementById(id),
{
type: 'bar',
data: {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
datasets: [
{
label: 'Bags',
backgroundColor: '#7e3af2',
// borderColor: window.chartColors.blue,
borderWidth: 1,
data: [66, 33, 43, 12, 54, 62, 84,100],
},
],
},
options: {
responsive: true,
legend: {
display: false,
},
},
}
)
}
})
</script>
I have two datasets in datasets array and they have labels like My first dataset and My second dataset.I only want to show My first dataset label.I researched on the internet and only could find how to remove all or not.
Here jsFiddle : http://jsfiddle.net/yj6mqu4r/
In the options, add the following:
options: {
legend: {
labels: {
filter: function(label) {
if (label.text == 'My first dataset') return true;
}
}
}
}
See the following snippet:
var config = {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My first dataset",
data: [65, 0, 80, 81, 56, 85, 40],
fill: false
}, {
label: "My second dataset",
data: [60, 20, 50, 41, 36, 25, 80],
fill: false
}]
},
options: {
legend: {
labels: {
filter: function(label) {
if (label.text == 'My first dataset') return true;
}
}
}
}
};
var ctx = document.getElementById("myChart").getContext("2d");
new Chart(ctx, config);
<canvas id="myChart"></canvas>
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.9.3/dist/Chart.js"></script>
I'm building a realtime Chart JS chart which is meant to show data and update every few seconds, I attach my chart JS code below, which randomises data on page load, I have a labels array which I need to change to whatever the current date/time is, and after every X number of items it removes the previous so that the graph is essentially a timeline showing real time stats, I'm first trying to figure out how to get my chart to update data every few seconds and aren't sure how to do this:
$(document).ready(function(){
// Random data on page load
var datasetValue = [];
var count = 70;
for (var j = 0; j < count; j++) {
datasetValue[j] = {
data: [
Math.round(Math.random() * 100),
Math.round(Math.random() * 100)-10,
Math.round(Math.random() * 100),
Math.round(Math.random() * 100)-10,
Math.round(Math.random() * 100),
Math.round(Math.random() * 100)-10,
Math.round(Math.random() * 100)
]
}
}
var mydata = {
datasets: datasetValue
}
// Our chart
var ctx = document.getElementById('status-chart').getContext('2d');
var chart = new Chart(ctx, {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "Max",
fill: false,
borderColor: '#f44336',
data: mydata.datasets[1].data,
}, {
label: "Free",
fill: false,
borderColor: '#4CAF50',
data: mydata.datasets[3].data,
}, {
label: "Total",
fill: false,
borderColor: '#607D8B',
data: mydata.datasets[2].data,
}, {
label: "Used",
fill: false,
borderColor: '#2196F3',
data: mydata.datasets[4].data,
}]
},
options: {
legend: {
display: true,
labels: {
fontColor: '#000'
}
}
}
});
});
you can use chart.update() method with assigning a new dataset
<canvas id="myChart" width="400" height="250"></canvas>
<input type="button" value="New Data" onclick="RandomData()">
var canvas = document.getElementById('myChart');
var data = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [
{
label: "My dataset",
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: [65, 59, 80, 0, 56, 55, 40],
}
]
};
function RandomData(){
var newData=[];
for(var i=0;i<7;i++){
newData.push(Math.round(Math.random() * 100))
}
myLineChart.data.datasets[0].data =newData;
myLineChart.update();
}
var option = {
showLines: true
};
var myLineChart = Chart.Line(canvas,{
data:data,
options:option
});
please see a demo here
I want to draw a chart with opposite bars like this (please ignore the yellow part):
This is my attempt using Chart.js:
You can see that there are 2 things need to be fixed:
The blue and red bar should be stacked
Both ends of the y-axis should show positive numbers
How can I achieve those ?
You can use the stacking and custom ticks feature to produce the result you want.
Sample JS Fiddle
var ctx = document.getElementById('wrapper').getContext('2d');
var chart = new Chart(ctx, {
// The type of chart we want to create
type: 'bar',
// The data for our dataset
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
backgroundColor: 'rgb(255, 99, 132)',
borderColor: 'rgb(255, 99, 132)',
data: [0, 10, 5, 2, 20, 30, 45],
stack: 'a'
}, {
label: "My Second dataset",
backgroundColor: 'rgb(2, 99, 132)',
borderColor: 'rgb(2, 99, 132)',
data: [-10, -110, -15, -12, -120, -130, -145],
stack: 'b'
}]
},
// Configuration options go here
options: {
scales: {
xAxes: [{
stacked: true
}],
yAxes: [{
stacked: true,
ticks: {
callback: function (value, index, values) {
return value < 0 ? -value : value;
}
}
}]
}
}
});
Using Chart.js you can create line charts and for that you have to privde labels and datasets. for example:
var data = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [
{
label: "My First dataset",
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: 1,
pointHitRadius: 10,
data: [65, 59, 80, 81, 56, 55, 40],
}
]
};
The Problem here is that you have a fix amount of labels (7 in this case) and you also need to provide 7 data entries for each dataset. Now what if you have an unknown amount of labels and data entries?
What if one data entry contains a number and a time:
Entry {
number: 127
time: 10:00
}
What if you want to show all times on the X-Axis and all Numbers on the Y-Axis sorted by the time on the X-Axis. Is that possible with Chart.js?
I had a battle with this today too.
You need to get a bit more specific with your dataset. In a line chart "datasets" is an array with each element of the array representing a line on your chart. Chart.js is actually really flexible here once you work it out. You can tie a line (a dataset element) to an x-axis and/or a y-axis, each of which you can specify in detail.
In your case if we stick with a single line on the chart and you want the "time" part of the entry to be along the bottom (the x-axis) then all your times could go into the "labels" array and your "number" would be pin-pointed on the y-axis. To keep it simple without specifying our own scales with x and y axes and given this data:
var MyData = [{time:"10:00", number: "127"},
{time:"11:00", number: "140"},
{time:"12:00", number: "135"},
{time:"13:00", number: "122"}];
You could set up the "data" property of your chart to be:
var data = {
labels: ["10:00", "11:00", "12:00", "13:00"],
datasets: [
{
label: "My First dataset",
// Insert styling, colors etc here
data: [{x: "10:00", y: 127},
{x: "11:00", y: 140},
{x: "12:00", y: 135},
{x: "13:00", y: 122}]
}
]};
Note that the data array is now a bit more specific with each element of data plotting itself on the x-axis by referencing one of the labels rather than just being a raw number. You can now put another dataset object in the datasets array following this pattern and have two lines, obviously give your lines different colours and names ("label").
Hope this helps.
I found a really good solution here: https://github.com/chartjs/Chart.js/issues/3953
Basically, you can add in your own 'labels' property to each dataset and leverage it in the callbacks for the xAxes labels, tooltips, or whatever you like.
var ctx = $("#myChart");
var myChart = new Chart(ctx, {
type: 'doughnut',
data: {
datasets: [{
data: [1, 2, 3, 4, 5],
backgroundColor: [
'green',
'yellow',
'red',
'purple',
'blue',
],
labels: [
'green',
'yellow',
'red',
'purple',
'blue',
]
}, {
data: [6, 7, 8],
backgroundColor: [
'black',
'grey',
'lightgrey'
],
labels: [
'black',
'grey',
'lightgrey'
],
},]
},
options: {
responsive: true,
legend: {
display: false,
},
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var dataset = data.datasets[tooltipItem.datasetIndex];
var index = tooltipItem.index;
return dataset.labels[index] + ': ' + dataset.data[index];
}
}
}
}
});
What's important here is this piece:
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var dataset = data.datasets[tooltipItem.datasetIndex];
var index = tooltipItem.index;
return dataset.labels[index] + ': ' + dataset.data[index];
}
}
}
Since there's a number of questions in your post, I'll try to help out with at least some of them. In the case of your Entry model with a number and a time you should create a scattered graph. Here you define data objects with x and y values as shown in my example below. It requires that each entry x has a corresponding y.
Have a look at the scatter chart.
http://www.chartjs.org/docs/#line-chart-scatter-line-charts
var d = new Date();
var scatterChart = new Chart(ctx, {
type: 'line',
data: {
datasets: [{
label: 'Scatter Dataset',
data: [{
x: new Date().setDate(d.getDate()-5),
y: 0
}, {
x: new Date(),
y: 10
}, {
x: new Date().setDate(d.getDate()5),
y: 5
}]
}]
},
options: {
scales: {
xAxes: [{
type: "time",
time: {
format: "HH:mm",
unit: 'hour',
unitStepSize: 2,
displayFormats: {
'minute': 'HH:mm',
'hour': 'HH:mm'
},
tooltipFormat: 'HH:mm'
},
gridLines: {
display: false
}
}],
}
}
});