I'm using the HorizontalBar option of the Chartjs plugin and I have values between -15 and 115. When my percentage value is 0.75 I'd like the bar to fill from -15 to 0.75.
I have set the properties beginAtZero false (which I believe it only works in Y axis..) and fill as true but it does not work.
datasets: [
{
data: [percentage],
fill: true,
backgroundColor: 'rgba(0, 0, 0, 1)'
}]
....
options:
{
scales:
{
xAxes: [
{
ticks:
{
beginAtZero: false,
min: min,
max: max
}
}],
}
}
As you may see in this JSFiddle the black bar starts at 0 and should start at -15.
This can be done with a floating bar since Chart.js v2.9.0, a feature that was merged into chartjs:master with pull request #6056. Individual bars can now be specified with the syntax [min, max].
<html>
<head>
<title>Floating Bar</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div>
<canvas id="canvas" height="50"></canvas>
</div>
<script>
var percentage = 0.92;
var min = -15;
var max = 115;
window.onload = function() {
var ctx = document.getElementById('canvas').getContext('2d');
window.myBar = new Chart(ctx, {
type: 'horizontalBar',
data: {
datasets: [{
data: [[min, percentage]],
fill: true,
backgroundColor: 'rgba(0, 0, 0, 1)'
}]
},
options: {
title: {
display: false
},
tooltips: {
mode: 'index',
intersect: false
},
legend: {
display: false
},
responsive: true,
scales: {
xAxes: [{
ticks: {
min: min,
max: max
}
}],
}
}
});
};
</script>
</body>
</html>
Related
I'm trying to create a bar chart using Chart.js. I'm trying to have the chart display bars above one going upward, whereas values below 1 (e.g. 0.8) point downward. The same as the chart would be displayed if it contained values below zero. Essentially I'm trying to change the base line to 1 rather than 0 for the Y-axis.
Something like this:
The best way to do this (and obviously more work) would be to create a custom axes. Chart.js explains how to do this here:
https://www.chartjs.org/docs/latest/developers/axes.html
I've also create a fiddle where the datavalues are modified by a set baseline. I've modified the tooltip and y-axis label as well so that everything shows based on the baseline. It's not as elegant as a custom axis, but it's quick and gets the job done (assuming the baseline is known). You can check out the fiddle here:
https://jsfiddle.net/tkngc02h/1/
And, in case you just want to see the code, here it is:
<!doctype html>
<html>
<head>
<title>Line Styles</title>
<script src="https://www.chartjs.org/dist/2.9.3/Chart.min.js"></script>
<script src="https://www.chartjs.org/samples/latest/utils.js"></script>
<style>
canvas{
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width:75%;">
<canvas id="canvas"></canvas>
</div>
<script>
var baseline = 1;
var config = {
type: 'bar',
data: {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
datasets: [{
label: 'TestData',
fill: false,
backgroundColor: window.chartColors.blue,
borderColor: window.chartColors.blue,
data: [
0 - baseline,
1.8 - baseline,
2.1 - baseline,
-0.2 - baseline,
1.3 - baseline,
-0.5 - baseline,
-0.23 - baseline,
0 - baseline
],
}]
},
options: {
responsive: true,
title: {
display: true,
text: 'Chart.js Line Chart',
},
tooltips: {
mode: 'index',
intersect: false,
callbacks: {
// Use the footer callback to display the sum of the items showing in the tooltip
label: function(tooltipItem, data) {
var label = data.datasets[tooltipItem.datasetIndex].label || '';
if (label) {
label += ': ';
}
label += tooltipItem.yLabel + baseline;
return label;
},
},
},
hover: {
mode: 'nearest',
intersect: true
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Month'
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Value',
},
ticks: {
// Include a dollar sign in the ticks
callback: function(value, index, values) {
return value + baseline;
}
}
}]
}
}
};
window.onload = function() {
var ctx = document.getElementById('canvas').getContext('2d');
window.myLine = new Chart(ctx, config);
};
</script>
</body>
</html>
I have these bar charts that will sometimes show zero values to the user. I'd like to show a bit of the bar chart so it does not look completely empty, but the data is connected to the visual representation of the bar. Is there any way I could have the top number say zero but the value be 3(or something small) in each column? Here is the code and a screenshots. One screenshot has data, the other is zero. I'd like the zero graph to show just a bit of the orange and green when at zero. Thanks
<canvas id="bar-chart" width="900" height="350"></canvas>
<script type="text/javascript">
var ctx = document.getElementById("bar-chart");
debugger;
var data = {
labels: ["Page Views", "Data Requests"],
datasets: [{
data: [<?php echo $databaseClass->totalViewsSelectedMonth($user_id, $year, 1);
?>, <?php
echo $databaseClass->isRfYearMonth($user_id, $year, 1);
?>],
backgroundColor: ["orange", "green"]
}]
}
var myChart = new Chart(ctx, {
type: 'bar',
data: data,
options: {
"hover": {
"animationDuration": 0
},
"animation": {
"duration": 1,
"onComplete": function() {
var chartInstance = this.chart,
ctx = chartInstance.ctx;
ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, Chart.defaults.global.defaultFontStyle, Chart.defaults.global.defaultFontFamily);
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
this.data.datasets.forEach(function(dataset, i) {
var meta = chartInstance.controller.getDatasetMeta(i);
meta.data.forEach(function(bar, index) {
var data = dataset.data[index];
ctx.fillText(data, bar._model.x, bar._model.y - 5);
});
});
}
},
legend: {
"display": false
},
tooltips: {
"enabled": false
},
scales: {
yAxes: [{
display: false,
gridLines: {
display: false
},
ticks: {
max: Math.max(...data.datasets[0].data) + 20,
display: false,
beginAtZero: true
}
}],
xAxes: [{
gridLines: {
display: false
},
ticks: {
beginAtZero: true
}
}]
}
}
});
</script>
It looks like you can update the axes of your charts to a new default. So, using a modified form of their example, something like the following (modified to fit your code):
// ...
scales: {
yAxes: [{
display: false,
gridLines: {
display: false
},
ticks: {
max: Math.max(...data.datasets[0].data) + 20,
min: -3, // ADDED
display: false,
beginAtZero: true
}
}],
// ...
... would do what you're looking for - with the side benefit that 0 and 3 wouldn't look like the same value, the relative bar size should stay accurate.
I have a large data set which, when graphed have several vertical sections as shown below. Chart.js formats these sections with thin, semi-transparent coloring. I want to format these to match the regular, thicker and solid line style.
The dataset itself is normally in a separate file called data.js, but I linked a portion of it from a CodePen.
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.js"></script>
<!--
NOT USED FOR THIS EXAMPLE
<script src="data.js"></script>
-->
<script src="https://codepen.io/EtherealBug/pen/wjOdoa.js"></script>
</head>
<body>
<canvas id="myChart"></canvas>
</body>
<style>
canvas {
width: 100% !important;
max-width: 2000px;
height: auto !important;
}
</style>
<script>
var labels = jsonfile.jsonarray.map(function(e) {
return e.Time;
});
var data = jsonfile.jsonarray.map(function(e) {
return e.Speed;
});
var ctx = myChart.getContext('2d');
var config = {
options: {
legend: {
position: 'bottom',
},
scales: {
xAxes: [{
scaleLabel: {
fontSize: 12,
fontStyle: 'bold',
display: true,
labelString: 'Y(1)'
},
ticks: {
autoSkip: true,
maxTicksLimit: 30,
},
}],
},
},
type: 'line',
data: {
labels: labels,
datasets: [{
fill: false,
label: 'Graph Line',
data: data,
backgroundColor: 'rgba(0, 119, 204, 0.3)'
}]
}
};
var chart = new Chart(ctx, config);
</script>
</html>
I figured it out, what you're seeing when you look at the graph is actually mostly just the individual points. Due to the large number of point data, it wasn't apparent at first, but the lines were thinner than the points width.
The vertical lines being so much thinner are actually because those are formatted with the line settings. By setting the transparency of the points color and border to 0, and by reformatting the line settings, I got was able to format it the way I intended. Sample below for reference should anyone else have a similar issue in the future.
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.js"></script>
<!--
NOT USED FOR THIS EXAMPLE
<script src="data.js"></script>
-->
<script src="https://codepen.io/EtherealBug/pen/wjOdoa.js"></script>
</head>
<body>
<canvas id="myChart"></canvas>
</body>
<style>
canvas {
width: 100% !important;
max-width: 2000px;
height: auto !important;
}
</style>
<script>
var labels = jsonfile.jsonarray.map(function(e) {
return e.Time;
});
var data = jsonfile.jsonarray.map(function(e) {
return e.Speed;
});
var ctx = myChart.getContext('2d');
var config = {
options: {
legend: {
position: 'bottom',
},
scales: {
xAxes: [{
scaleLabel: {
fontSize: 12,
fontStyle: 'bold',
display: true,
labelString: 'Y(1)'
},
ticks: {
autoSkip: true,
maxTicksLimit: 30,
},
}],
},
},
type: 'line',
data: {
labels: labels,
datasets: [{
lineTension: 0.4, //defaul val = 0.4
pointBackgroundColor: 'rgba(0,0,0,0)',
pointBorderColor: 'rgba(0,0,0,0)',
borderColor: 'black',
borderWidth: 4,
fill: false,
label: 'Graph Line',
data: data,
}]
}
};
var chart = new Chart(ctx, config);
</script>
</html>
Note: I'll accept this answer when it allows me in 2 days since it's my own.
I have used a Bubble Chart on Chart.js to create sliders to show comparable performance and they currently look a bit like this:
What am I trying to do
I want to add data labels just above / in my 'bubbles' with my values in. Much like the '10' you can see on each bubble here.
What have I done to achieve this
This is not standard Chart.js functionality but I found this post which was discussing a similar issue for bar / line charts.
I've installed the plugin that post suggested but the data label it shows is for the radius of the bubble and I want to it to be the x-axis of the bubble.
I've also tried to use the code from some of the answers on that post, but with absolutely no luck.
My Code
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.0/Chart.bundle.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels"></script>
<div class="container" >
<h2>Chart.js — Line Chart Demo</h2>
<div>
<canvas id="myChart"></canvas>
</div>
</div>
<script>
var ctx = document.getElementById('myChart').getContext('2d');
ctx.height = 1000;
var myChart = new Chart(ctx, {
type: 'bubble',
data: {
datasets: [
{
label: 'Your Data',
data: [
{x: 78.7, y: 0, r: 10, name: "Performance"}
],
backgroundColor: "rgba(153,255,51,0.6)"
},
{
label: 'Average',
data: [
{x: 100.7, y: 0, r: 10, name: "Performance"} // The labe needs to be X. not R.
],
backgroundColor: "rgba(255,0,128,0.6)"
}
]
},
options: {
maintainAspectRatio: false,
scales: {
yAxes: [{
id: 'first-y-axis',
type: 'linear',
ticks: {
min: 0,
max: 1,
stepSize: 1,
display: false
},
gridLines: {
display: false,
drawBorder: false
}
}],
xAxes: [{
ticks: {
min: 50, // Controls where axis starts
max: 120 // Controls where axis finishes
},
gridLines: {
display: false,
lineWidth: 3 // Width of bottom line
}
}]
}
}
});
</script>
Thanks in advance
I've managed to find the answer to this question, basically by taking apart the bubble chart example from the chartjs-plugin-datalabels plugin.
Below is a working example. Pay attention to the section in options that says 'plugin'.
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.0/Chart.bundle.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels"></script>
<div class="container" >
<h2>Chart.js — Line Chart Demo</h2>
<div>
<canvas id="myChart"></canvas>
</div>
</div>
<script>
var ctx = document.getElementById('myChart').getContext('2d');
ctx.height = 1000;
var myChart = new Chart(ctx, {
type: 'bubble',
data: {
datasets: [
{
label: 'Your Data',
data: [
{x: 78.7, y: 0, r: 10, name: "Performance"}
],
backgroundColor: "rgba(153,255,51,0.6)"
},
{
label: 'Average',
data: [
{x: 100.7, y: 0, r: 10, name: "Performance"} // The labe needs to be
],
backgroundColor: "rgba(255,0,128,0.6)"
}
]
},
options: {
plugins: { // Look at this bit
datalabels: {
anchor: function(context) {
var value = context.dataset.data[context.dataIndex];
return value.x < 50 ? 'end' : 'center';
},
align: function(context) {
var value = context.dataset.data[context.dataIndex];
return value.x < 50 ? 'end' : 'center';
},
color: function(context) {
var value = context.dataset.data[context.dataIndex];
return value.x < 50 ? context.dataset.backgroundColor : 'white';
},
font: {
weight: 'bold'
},
formatter: function(value) {
return Math.round(value.x);
},
offset: 2,
padding: 0
}
},
maintainAspectRatio: false,
scales: {
yAxes: [{
id: 'first-y-axis',
type: 'linear',
ticks: {
min: 0,
max: 1,
stepSize: 1,
display: false
},
gridLines: {
display: false,
drawBorder: false
}
}],
xAxes: [{
ticks: {
min: 50, // Controls where axis starts
max: 120 // Controls where axis finishes
},
gridLines: {
display: false,
lineWidth: 3 // Width of bottom line
}
}]
}
}
});
</script>
If all you want to do is changing the label, there is an easier solution. From the docs of chartjs-plugin-datalabels:
Data values are converted to string ('' + value). If value is an object, the following rules apply first:
value = value.label if defined and not null
else value = value.r if defined and not null
else value = 'key[0]: value[key[0]], key[1]: value[key[1]], ...'
Therefore, it is sufficient to specify a label in your data points:
data: [{ x: 78.7, y: 0, r: 10, name: "Performance", label: `${Math.round(x)}` }],
The low and high points on this chart are getting cut off, is there any way to fix this without knowing what numbers will be in the data?
I've seen other people create some padding with the chart's minimum and maximum values, but I don't know what the values will be beforehand.
Chart:
A similar example suffering from the same problem is shown here: http://codepen.io/erose/pen/LNwdQO/
Here's the HTML:
<div class="chart-container">
<canvas id="chart"></canvas>
</div>
Here's the CSS:
.chart-container {
width: 493px;
height: 83px;
}
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
and here the JS used to create the above chart:
var ctx = $("#chart");
Chart.defaults.global.responsive = true;
Chart.defaults.global.maintainAspectRatio = false;
Chart.defaults.global.legend.display = false;
Chart.defaults.global.tooltips.backgroundColor = "lightblue";
Chart.defaults.global.tooltips.bodyFontFamily = "sans-serif";
Chart.defaults.global.tooltips.bodyFontSize = 20;
Chart.defaults.global.tooltips.bodyColor = "#95989a";
Chart.defaults.global.tooltips.bodyAlign = "left";
Chart.defaults.global.tooltips.titleFontSize = 0;
Chart.defaults.global.tooltips.titleMarginBottom = 0;
Chart.defaults.global.tooltips.footerMarginTop = 0;
Chart.defaults.global.tooltips.cornerRadius = 12;
Chart.defaults.global.tooltips.caretSize = 10;
Chart.defaults.global.tooltips.xPadding = 20;
Chart.defaults.global.tooltips.yPadding = 10;
Chart.defaults.scale.gridLines.color = 'white';
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: [" ", "", "", "", "", "", "", "", "", " "],
datasets: [{
label: '$',
data: [100,100,100,100,0,100,100,100,100,100],
fill: false,
borderWidth: 1,
borderColor: "#2f75c1",
borderCapSytle: "round",
pointBorderColor: "#2f75c1",
pointBackgroundColor: "#2f75c1",
pointBorderWidth: 5,
pointHoverRadius: 10,
}]
},
options: {
scales: {
yAxes: [{
gridLines: {
display: false
},
scaleLabel: {
display: false
},
scaleLkneColor: 'white',
ticks: {
display: false
}
}],
xAxes: [{
gridLines: {
display: false
},
scaleLabel: {
display: false
},
// ticks: {
// display: false
// }
}]
}
}
});
From reading your question I believe you not only want the for the circle to not be cut off but you would like some extra padding inside the chart.
For that I would structure this a little different:
var ctx = $("#chart");
Chart.defaults.global.responsive = true;
Chart.defaults.global.maintainAspectRatio = false;
Chart.defaults.global.legend.display = false;
Chart.defaults.global.tooltips.backgroundColor = "lightblue";
Chart.defaults.global.tooltips.bodyFontFamily = "sans-serif";
Chart.defaults.global.tooltips.bodyFontSize = 20;
Chart.defaults.global.tooltips.bodyColor = "#95989a";
Chart.defaults.global.tooltips.bodyAlign = "left";
Chart.defaults.global.tooltips.titleFontSize = 0;
Chart.defaults.global.tooltips.titleMarginBottom = 0;
Chart.defaults.global.tooltips.footerMarginTop = 0;
Chart.defaults.global.tooltips.cornerRadius = 12;
Chart.defaults.global.tooltips.caretSize = 10;
Chart.defaults.global.tooltips.xPadding = 20;
Chart.defaults.global.tooltips.yPadding = 10;
Chart.defaults.scale.gridLines.color = 'white';
var getData = [100,100,100,100,0,100,100,100,100,100];
var getLabels = ["", "", "", "", "", "", "", "", "", ""];
var minNum = function(array){
return Math.min.apply( Math, array )-10;
}
var maxNum = function(array){
return Math.max.apply( Math, array )+10;
}
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: getLabels,
datasets: [{
label: '$',
data: getData,
fill: false,
borderWidth: 1,
borderColor: "#2f75c1",
borderCapSytle: "round",
pointBorderColor: "#2f75c1",
pointBackgroundColor: "#2f75c1",
pointBorderWidth: 5,
pointHoverRadius: 10,
}]
},
options: {
scales: {
yAxes: [{
gridLines: {
display: false
},
scaleLabel: {
display: false
},
scaleLkneColor: 'white',
ticks: {
suggestedMin: minNum(getData),
suggestedMax: maxNum(getData),
}
}],
xAxes: [{
gridLines: {
display: false
},
scaleLabel: {
display: false
},
// ticks: {
// display: false
// }
}]
}
}
});
.chart-container {
width: 493px;
height: 83px;
}
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.3/Chart.bundle.min.js"></script>
<div class="chart-container">
<canvas id="chart"></canvas>
</div>
2 Important changes
I create a getData var to hold the array this way the array can be formatted however you like the function does not care it just looks for getData and expects an array.
I created a minNum and maxNum function to go through the array and select either the lowest or highest number then call that inside the ticker you can find more on this at ChartJS Scales