I'm trying to create a ChartJs Bar chart which contains date on labels.
The chart bars over lap with each other unevenly. Works well when the time scale is removed however, the labels are not date sorted. The labels and data are dynamically populated, so cannot sort it before rendering.
Below is the sample image,
And, if the scales (xAxis) is removed, it give proper output (but not sorted)
example: https://codepen.io/karthikkbala/pen/QWjVQqb
Sample data:
[ "2020-05-13", "2020-05-11", "2020-05-12", "2020-05-14", "2020-05-09", "2020-05-10", ]
[ 20, 11, 9, 22, 11, 9, ]
You can omit labels in the chart configuration and instead generate data as individual points through objects containing x and y properties as shown here.
const labels = ["2020-05-13", "2020-05-11", "2020-05-12", "2020-05-14", "2020-05-09", "2020-05-10"];
const baseData = [20, 11, 9, 22, 11, 9];
const data = labels.map((l, i) => ({ x: l, y: baseData[i] }));
This produces the following data.
[
{ "x": "2020-05-13", "y": 20 },
{ "x": "2020-05-11", "y": 11 },
{ "x": "2020-05-12", "y": 9 },
{ "x": "2020-05-14", "y": 22 },
{ "x": "2020-05-09", "y": 11 },
{ "x": "2020-05-10", "y": 9 }
]
The xAxis would then have to be defined as follows:
xAxes: [{
offset: true,
type: 'time',
time: {
unit: 'day',
source: 'data',
tooltipFormat: 'MMM DD'
}
}],
Please have a look at your amended code below.
const labels = ["2020-05-13", "2020-05-11", "2020-05-12", "2020-05-14", "2020-05-09", "2020-05-10"];
const baseData = [20, 11, 9, 22, 11, 9];
const data = labels.map((l, i) => ({ x: l, y: baseData[i] }));
var chartData = {
datasets: [{
label: "All Detections",
backgroundColor: "#02a499",
borderColor: "#ffffff",
borderWidth: 1,
hoverBackgroundColor: "#02a499",
hoverBorderColor: "#02a499",
data: data
}]
};
new Chart("ChartByDate", {
type: 'bar',
data: chartData,
options: {
scales: {
xAxes: [{
offset: true,
type: 'time',
time: {
unit: 'day',
source: 'data',
tooltipFormat: 'MMM DD'
}
}],
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script>
<canvas id="ChartByDate"></canvas>
Related
I want to create a BarChart on y-Axis with Chart.js.
Now I want to change the value to stepsize 1, but it creates a strange chart, where the key on x and y is the name.
Can you tell me why?
It should look like this with stepsize 1:
First
But if I set the ticks, it looks like this:
second
Greetings
Jannik
Data:
[
{
"name": "Finanzdienstleistungen, Finanzprodukte ...",
"id": 1,
"value": 80
},
{
"name": "Urheberrechtsverletzungen und Wettbewerbs...",
"id": 2,
"value": 0
},
{
"name": "Produktsicherheit und -konformität",
"id": 3,
"value": 0
},
{
"name": "Verkehrssicherheit und Umweltschutz",
"id": 4,
"value": 0
},
]
const ctx = document.getElementById('myChart');
const data = JSON.parse(document.getElementById('data-statistic').textContent);
let chart = new Chart(ctx, {
type: 'bar',
data: {
datasets: [{
label: 'Incidents',
data: data,
indexAxis: 'y',
backgroundColor: [
'rgb(255, 99, 132)',
'rgb(54, 162, 235)',
'rgb(255, 205, 86)'
],
borderWidth: 1,
}]
},
options:{
parsing: {
yAxisKey: 'name',
xAxisKey: 'value'
},
scales: {
x: {
ticks: {
type: 'value',
stepSize: 1
}
}
},
}
});````
The problem is not related to stepSize but you want to have a horizontal bar but you didn't configure indexAxis option. Without that, is a "vertical" bar and X scale is a category and not numeric one, as you need.
Add indexAxis option as following:
options:{
indexAxis: 'y',
parsing: {
yAxisKey: 'name',
xAxisKey: 'value'
},
...
I struggle to let my second y-Axis scale to my second data array.
The green data should be scaled according to the right y-Axis (not working).
The red data is correctly scaled to the left y-Axis.
<div id="chartWrapper" class="card-content column is-two-thirds">
<canvas id="myChart" height="250px"></canvas>
<script>
const ctx = document.getElementById('myChart').getContext('2d');
const myChart = new Chart(ctx, {
type: 'line',
data: {
labels: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23],
datasets: [{
label: 'Temperatur in C°',
yAxisID: 'A',
borderColor: "red",
data: 0
},
{
label: 'Niederschlagsmenge in mm',
yAxisID: 'B',
borderColor: "blue",
data: 0
}]
},
options: {
scales: {
A: {
type: 'linear',
beginAtZero: false,
position: 'left',
display: true
},
B: {
type: 'linear',
beginAtZero: false,
position: 'right',
display: true
}
}
}
});
</script>
</div>
Don't be confused with the data being 0, I add the data dynamically.
Thank you very much for any help.
This is because you are using V2 of chart.js in which the scales need to be configured as arrays like so:
new Chart(ctx, {
type: 'line',
data: {},
options: {
scales: {
yAxes: [{
id: 'A'
}, {
id: 'B'
}]
}
}
})
I'm wondering if it is possible to have a graph with multiple lines, but I want one of the lines to start from the middle of the graph, while the rest of the lines still start from all the way at the left. Is this possible? It'd look like this:
The green line is what I am talking about, whether it would be possible for a dataset to start from not all the way at the left
Yes this is possible, you can achieve this in 2 ways, 1 is to specify each datapoint using its x and y coordinate another one is to place some null values in the start of your data array:
var options = {
type: 'line',
data: {
labels: [1, 2, 3, 4, 5, 6],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderColor: 'pink'
},
{
label: '# of Points',
data: [{
x: 3,
y: 6
}, {
x: 4,
y: 8
}, {
x: 5,
y: 2
}, {
x: 6,
y: 12
}],
borderColor: 'orange'
},
{
label: '# of Points2',
data: [null, null, null, 9, 13, 15],
borderColor: 'lightblue'
}
]
},
options: {
scales: {
yAxes: [{
ticks: {
reverse: false
}
}]
}
}
}
var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.0/chart.js"></script>
</body>
You can quickly do this with offset option.
Example:
const options = {
...otherChartOptions,
scales: {
x: {
offset: true
},
y: {
offset: true
}
}
};
Reference: https://www.chartjs.org/docs/latest/axes/cartesian/linear.html
While plotting a chart in chart js with y axes steps like 0 573 675 900. When i plot it the spacing is between adjacent points are. can i bring the points evenly spaced?
Consider the image
chart
In this image i want the number 7 to appear exactly in the middle and the chart to scale between 1 and 7 and also 7 and 10 accordingly.
Following is a sample code iam working on:
////////////////////////////////////////////////////////
document.addEventListener("DOMContentLoaded", function() {
var
example = document.getElementById('example1'),
hot;
var headers = ["Red", "Blue", "Yellow", "Green", "Purple", "Orange", "Pink", 'Brown'];
var myData = [
[5, 10, 3, 5, 2, 3, 5, 1],
[9, 9, 3, 10, 8, 7, 7, 2],
[5, 1, 10, 6, 7, 9, 4, 8]
];
var StepValues = [1,7,10];
var rowheaders = ['Mark', 'Anna', 'Diana']
hot = new Handsontable(example, {
data: myData,
rowHeaders: rowheaders,
colHeaders: headers,
readOnly: true,
colWidths: 88,
licenseKey: 'non-commercial-and-evaluation',
fillHandle: {
autoInsertRow: false,
}
});
var options = {
type: 'bar',
data: {
labels: headers,
datasets: [{
label: rowheaders[0],
data: myData[0],
borderWidth: 1,
backgroundColor: 'rgb(255, 236, 217)'
}, {
label: rowheaders[1],
data: myData[1],
borderWidth: 1,
backgroundColor: 'rgb(235, 224, 255)'
}, {
label: rowheaders[2],
data: myData[2],
borderWidth: 1,
backgroundColor: 'rgb(219, 242, 242)'
}]
},
options: {
scales: {
yAxes: [{
ticks: {
reverse: false,
callback: (label) =>{
if(StepValues.includes(label)){
return label;
}
}
}
}]
}
}
}
var ctx = document.querySelector('.chartJSContainer').getContext('2d');
var myChart = new Chart(ctx, options);
});
//////////////////////////////////////////////////////////////////
I have three arrays that I am parsing in from an XML file, detailed below:
["x": "23.561799", "x": "-10.713591", "x": "-20.516543", "x": "27.352751", "x": "-21.090982"]
["y": "-5.777557", "y": "-24.425175", "y": "9.131939", "y": "7.052970", "y": "-26.059631"]
["r": "10.000000", "r": "10.000000", "r": "10.000000", "r": "10.000000", "r": "10.000000"]
Let's say these are called arrayX, arrayY and arrayR. How would I go about using these to render a bubble chart in Chart.js?
I have the code to create a simple bubble chart here:
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'bubble',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [
{
label: 'Gaze Map Month 1',
data: [
{
x: 23,
y: -10,
r: 10
},
{
x: -10.713591,
y: -24.425175,
r: 3
},
{
x: -20.516543,
y: 9.131939,
r: 36
},
{
x: 27.352751,
y: 7.052970,
r: 19
},
{
x: -21.090982,
y: -26.059631,
r: 2
}
],
backgroundColor:"#FF6384",
hoverBackgroundColor: "#FF6384",
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true,
min: -30,
max: 30
}
}],
xAxes: [{
ticks: {
beginAtZero:true,
min: -30,
max: 30
}
}]
}
}
});
Note the format of the arrays can be changed if need be, so that just the values are used.
Since your are getting data dynamically, just iterate over your data and build a chartData object in the format that chart.js requires. Once you have assembled your data, just use that in your chart definition. See the below example
var xArray = ["x": "23.561799", "x": "-10.713591", "x": "-20.516543", "x": "27.352751", "x": "-21.090982"];
var yArray = ["y": "-5.777557", "y": "-24.425175", "y": "9.131939", "y": "7.052970", "y": "-26.059631"];
var rArray = ["r": "10.000000", "r": "10.000000", "r": "10.000000", "r": "10.000000", "r": "10.000000"];
var chartData = [];
xArray.forEach(function(e, i) {
chartData.push({
x: parseFloat(e),
y: parseFloat(yArray[i]),
r: parseFloat(rArray[i]),
});
});
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'bubble',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [
{
label: 'Gaze Map Month 1',
data: chartData,
backgroundColor:"#FF6384",
hoverBackgroundColor: "#FF6384",
}
]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true,
min: -30,
max: 30
}
}],
}
}
}
});