I use chart.js 2.8 and chartjs-plugin-annotation.js
I have a bar type chart.
My labels are : [1.0 - 2.8], [2.8 - 4.6], [6.4 - 8.2], [8.2 - 10.0]
var ctx = document.getElementById("myChart").getContext("2d");
new Chart(ctx, {
type: "bar",
data: {
labels: labels,
datasets: [{
data: datas
}]
},
options: {
annotation: {
annotations: [{
type: "line",
mode: "vertical",
scaleID: "x-axis-0",
value: "2.8 - 4.6", //value must be equal a label :(
borderColor: "red",
label: {
content: "TODAY",
enabled: true,
position: "top"
}
}]
}
}
});
I want the vertical line to be drawn at exactly on 2.4 point. But the vertical line can be drawn only at the label value. How can i fix this?
Related
I have a project where I show the movements of the robot, I want to make this map so that the x and y scales are proportional to each other.
These data are real-time data, which, as I mentioned, shows the movement of a robot.
Can anyone help me with this?
This is the figure:
myChart = new Chart(ctx, {
type: 'scatter',
data: {
datasets: [{
label: '',
backgroundColor: "blue",
fill: false,
data: [],
}]
},
options: {
scales: {
xAxes: [{
ticks:{
suggestedMax:15,
}
}]
yAxes: [{
ticks:{
suggestedMax:15,
}
}]
}
}
});
You can define the desired dimension of your canvas through the width or height property.
<canvas id="chartContainer" width="400"></canvas>
...or using CSS.
canvas {
width: 400px;
}
Further you should also define responsive: false and aspectRatio: 1 within the chart options, latter represents a square canvas.
options: {
responsive: false,
aspectRatio: 1,
See Configuration Options at the Chart.js documentation
I have a bar chart using Chartjs, with a fixed y-axis max. Sometimes the data can exceed the max, but the hover tooltip is always anchored to the top of the bars so it cannot be seen. The tooltips' position option does not really work for me.
So, is there a way to display the tooltip at the bottom of the bars? Or can it follow the hovering mouse cursor like canvasjs?
var ctx = document.getElementById("chart").getContext("2d");
var barChart = new Chart(ctx, {
type: 'bar',
options: {
scales: {
yAxes: [{
display: true,
ticks: {
min: 0,
max: 120
},
}],
},
tooltips: {
// position: 'nearest',
position: 'average',
},
legend: {
display: false
}
},
data: {
labels: ["A", "B", "C", "D"],
datasets: [{
label: "Data Set 1",
backgroundColor: [
'#44b2d7',
'#44b2d7',
'#44b2d7',
'#44b2d7',
],
borderColor: [
'#44b2d7',
'#44b2d7',
'#44b2d7',
'#44b2d7'
],
borderWidth: 0,
data: [131, 65, 165, 85]
}]
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<canvas id="chart" height="180"></canvas>
New modes can be defined by adding functions to the Chart.Tooltip.positioners map.
You can create your custom postitioning like in the Doc of chartjs:
Chart.Tooltip.positioners.custom = function(elements, eventPosition) {
/** #type {Chart.Tooltip} */
var tooltip = this;
/* ... */
return {
x: eventPosition.x,
y: eventPosition.y
};
}
you need to set your custom function into your options when rendering your chart:
tooltips: {
position : 'custom', //<-- important same name as your function above
callbacks: {
label: function(tooltipItem, data) {
var label = Math.floor(tooltipItem.yLabel*100)/100+" "+data.datasets[tooltipItem.datasetIndex].label;
return label;
}
}
}
Look my full Fiddle example.
Just wondering if there is any way to set the horizontal bar labels for y-axis using chart.js. Here is how I set up the chart:
<div class="box-body">
<canvas id="chart" style="position: relative; height: 300px;"></canvas>
</div>
Javascript:
var ctx = document.getElementById('chart').getContext("2d");
var options = {
layout: {
padding: {
top: 5,
}
},
responsive: true,
animation: {
animateScale: true,
animateRotate: true
},
};
var opt = {
type: "horizontalBar",
data: {
labels: label,
datasets: [{
data: price,
}]
},
options: options
};
if (chart) chart.destroy();
chart= new Chart(ctx, opt);
chart.update();
As you all can see, the first and third labels are too long and cut off. Is there a way to make the label multi-line?
If you want to have full control over how long labels are broken down across lines you can specify the breaking point by providing labels in a nested array. For example:
var chart = new Chart(ctx, {
...
data: {
labels: [["Label1 Line1:","Label1 Line2"],["Label2 Line1","Label2 Line2"]],
datasets: [{
...
});
You can use the following chart plugin :
plugins: [{
beforeInit: function(chart) {
chart.data.labels.forEach(function(e, i, a) {
if (/\n/.test(e)) {
a[i] = e.split(/\n/);
}
});
}
}]
add this followed by your chart options
ᴜꜱᴀɢᴇ :
add a new line character (\n) to your label, wherever you wish to add a line break.
ᴅᴇᴍᴏ
var chart = new Chart(ctx, {
type: 'horizontalBar',
data: {
labels: ['Jan\n2017', 'Feb', 'Mar', 'Apr'],
datasets: [{
label: 'BAR',
data: [1, 2, 3, 4],
backgroundColor: 'rgba(0, 119, 290, 0.7)'
}]
},
options: {
scales: {
xAxes: [{
ticks: {
beginAtZero: true
}
}]
}
},
plugins: [{
beforeInit: function(chart) {
chart.data.labels.forEach(function(e, i, a) {
if (/\n/.test(e)) {
a[i] = e.split(/\n/);
}
});
}
}]
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="ctx"></canvas>
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
I am working on drowing a Gantt diagram like on Chartjs.
What am I trying to do is painting and HorizontalBarChart with time type, as a mixed type where I set a min value for each bar, however seems it does not work.
My code:
new Chart(document.getElementById("customChart"), {
type: 'horizontalBar',
data: {
labels: ['Item 1', 'Item 2'],
datasets: [
{
type: 'horizontalBar',
label: 'Bar Component1',
data: [new Date(2017,02,26) ],
options:{
scales:{
xAxes: [{
type: 'time',
unit: 'day',
unitStepSize: 1,
time: {
displayFormats: {
'day': 'YYYY-MM-DD'
},
min: new Date(2017,03,24)
}
}]
}
}
},
{
type: 'horizontalBar',
label: 'Bar Component2',
data: [new Date(2017,02,14)],
options:{
scales:{
xAxes: [{
type: 'time',
unit: 'day',
unitStepSize: 1,
time: {
displayFormats: {
'day': 'YYYY-MM-DD'
},
min: new Date(2017,02,10)
}
}]
}
}
}
]
}
});
Is there any workaround in order to implement this? Should I use another library?
Unfortunately, there is no way to configure chart.js to produce a gantt chart because each dataset that you plot on the graph either starts at the origin (the min value set on the scale) or is stacked right on top of each other. You cannot configure a chart to stack bars but show them in different "lanes" (which is what a gantt chart would require).
Even if you try to create multiple scales (which is looks like you are attempting), it will not work because the 2nd bar will still start at the origin (however the 2nd scale's origin would be the min value you specified). In other words, both bars will still touch the y axis.
You had several problems with you chart.js configuration. First, you cannot define scale config in a dataset. Second, you tried to use several time scale options, but they must be inside the time object.
I cleaned up everything just so you can see how to correctly define a chart. Here is a codepen demonstrating this.
Currently [November 2018] chart.js is not able todo so.
However if you are willing to apply a patch, there is a pull request pending, which would implement exactly this feature: https://github.com/chartjs/Chart.js/pull/5262
For my purposes I adapted the code of https://github.com/chartjs/Chart.js/blob/master/src/controllers/controller.bar.js
## -453,10 +453,12 ## module.exports = function(Chart) {
helpers.canvas.clipArea(chart.ctx, chart.chartArea);
- for (; i < ilen; ++i) {
- if (!isNaN(scale.getRightValue(dataset.data[i]))) {
- rects[i].draw();
- }
+ if (dataset.label != 'noshow') {
+ for (; i < ilen; ++i) {
+ if (!isNaN(scale.getRightValue(dataset.data[i]))) {
+ rects[i].draw();
+ }
+ }
}
helpers.canvas.unclipArea(chart.ctx);
Utilizing bar chart like this:
var gapdemo= new Chart(ctx, {
type: 'horizontalBar',
data: {
labels: ["todo1", "todo2", "todo3", "todo4"],
datasets: [{
type: 'horizontalBar',
label: 'noshow',
data: [1,2,4,3],
},{
type: 'horizontalBar',
label: 'showme',
data: [3,2,2,1],
},{
type: 'horizontalBar',
label: 'noshow',
data: [1,5,3,4],
},{
type: 'horizontalBar',
label: 'showme',
data: [2,2,1,4],
}]
},
options: {
scales: {
xAxes: [{
id: 'x-axis-1',
stacked: true
}],
yAxes: [{
id: 'y-axis-1',
stacked: true,
ticks: {beginAtZero: true}
}]
}
}
});
This results in a chart like that:
barchart with gaps
Since version 2.9.0, Chart.js supports floating bars. Individual bars can now be specified with the syntax [min, max].
This makes it possible to draw a Gantt chart.
var dates = [new Date("2019-12-24"), new Date("2019-12-26"), new Date("2019-12-30"), new Date("2020-1-2"), new Date("2020-1-4"), new Date("2020-1-9"), new Date("2020-1-10") ];
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'horizontalBar',
data: {
labels: dates.map((d, i) => "Task " + i).splice(1),
datasets: [
{
label: 'Tasks',
data: dates.map((d, i) => i == 0 ? null : [dates[i - 1], d]).slice(1),
backgroundColor: 'lightblue',
borderWidth: 1
}
]
},
options: {
responsive: true,
scales: {
xAxes: [{
type: 'time',
time: {
displayFormats: {
day: 'YYYY-MM-DD'
}
},
ticks: {
min: dates[0].getTime(),
max: dates[dates.length - 1].getTime()
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.1.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="myChart"></canvas>