Relative bar chart overlay on line chart in chart.js - javascript

I'm trying to build a chart in chart.js, showing price data of a virtual item, with a line chart showing pricing, and a backlay bar chart, showing sales volume, like this:
My issue is, the y-axis is the same for both, meaning the price data is shown at the bottom with unnoticeable differences, since the volume is in the hundreds.
I want the price data to be on the y-axis, with the bars shown relatively, with the highest volume being shown as 100% height, not the values on the y-axis, something more like this:
Is this possible, and how would it be done? Thanks!
Code:
let marketData = [["Nov 28 2018 20: +0",30.332,"103"],["Nov 28 2018 21: +0",25.801,"188"],["Nov 28 2018 22: +0",25.451,"262"],["Nov 28 2018 23: +0",12.484,"693"]];
let lineData = [];
let barData = [];
let labels = [];
marketData.forEach(function(thing) {
labels.push(thing[0].replace(' +0', '00'));
lineData.push(thing[1]);
barData.push(thing[2]);
});
new Chart(document.getElementById("mixed-chart"), {
type: 'bar',
data: {
labels: labels,
datasets: [
{
label: "Price",
type: "line",
borderColor: "#3e95cd",
data: lineData,
fill: false
},
{
label: "Sold",
type: "bar",
backgroundColor: "rgba(0,0,0,0.2)",
data: barData
}
]
},
options: {
title: {
display: true,
text: 'Sale price vs sale volume'
},
legend: { display: false }
}
});

use a second y-axis to give the bar series a different scale
assign each data set to its own axis by using property --> yAxisID
then set the matching id of the y-axis in the scales.yAxes option
see following working snippet...
$(document).ready(function() {
let marketData = [["Nov 28 2018 20: +0",30.332,"103"],["Nov 28 2018 21: +0",25.801,"188"],["Nov 28 2018 22: +0",25.451,"262"],["Nov 28 2018 23: +0",12.484,"693"]];
let lineData = [];
let barData = [];
let labels = [];
marketData.forEach(function(thing) {
labels.push(thing[0].replace(' +0', '00'));
lineData.push(thing[1]);
barData.push(thing[2]);
});
new Chart(document.getElementById("mixed-chart"), {
type: 'bar',
data: {
labels: labels,
datasets: [
{
label: "Price",
type: "line",
borderColor: "#3e95cd",
data: lineData,
fill: false,
yAxisID: 'A' // <-- set y-axis id
},
{
label: "Sold",
type: "bar",
backgroundColor: "rgba(0,0,0,0.2)",
data: barData,
yAxisID: 'B' // <-- set y-axis id
}
]
},
options: {
title: {
display: true,
text: 'Sale price vs sale volume'
},
legend: {display: false},
scales: {
yAxes: [{
id: 'A', // <-- set y-axis id
position: 'left',
}, {
id: 'B', // <-- set y-axis id
position: 'right',
// hide grid lines and labels
gridLines: {
display: false
},
ticks: {
display: false
}
}]
}
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js"></script>
<canvas id="mixed-chart"></canvas>

Related

In APEX zoomable Timeseries graph while selecting particular date , its showing last day data and and from selected date , only 10 hrs,

U can see in this image , i have selected 7th but its shows 6th date days hours anf 7th also, Im expecting 24hrs from same date , can anyone help me in this, I'm very new in apex library
U can see in this image , i have selected 7th but its shows 6th date days hours anf 7th also, Im expecting 24hrs from same date , can anyone help me in this, I'm very new in apex library
let options1 = {
chart: {
id: "chart2",
type: "line",
height: 230,
stacked: true,
},
colors: ["#EE4B2B", "#e1ad01", "#027bc7"],
stroke: {
width: 3,
},
dataLabels: {
enabled: false,
},
fill: {
opacity: 1,
},
markers: {
size: 0,
},
series: [
{
name: "Current_R",
data: currentR,
},
{
name: "Current_Y",
data: currentY,
},
{
name: "Current_B",
data: currentB,
},
],
xaxis: {
type: "datetime",
tickPlacement: "on",
},
yaxis: {
min: 0,
tickAmount: 2,
},
};
var chart1 = new ApexCharts(
document.querySelector("#chart-area"),
options1
);
chart1.render();
}, [currentR]);

Chart.js identification of min and max value before rendering

I am using chart.js for my project. As you can see in the following code, chart.js uses different minimum and maximum values for y-axis for line and bar graphs for same data. In the given code, 1100-1700 is the value range for line graph whereas 0-2000 is the value range used for bar graph.
I like to make same minimum and maximum values for both line and bar graphs. One option is to find minimum, maximum and step-size values my own and use the properties min, max and ticks.stepSize under scales. But finding minimum, maximum and step-size for a given data data is a serious task.
For my requirement, default minimum ,maximum and stepSize used by chart.js for line graph is fine and I would like to use the same values for bar graph also.
I could first render line graph, get these values from this graph (like scales.y.min) and then use it for bar graph, which is perfectly working
Is there a way I could get the default min, max, stepSize values used by chart.js for line graph before actually drawing the graph? Any answers or pointers are really appreciated. Thanks
var chart1 = new Chart(document.getElementById('chart1'),
{
type: 'line',
data:
{
labels: ['a','b','c'],
datasets:
[
{
label: 'A',
data: [1212,1122, 1188, 1617, 1116],
borderColor: 'green',
}
]
}
});
var chart2 = new Chart(document.getElementById('chart2'),
{
type: 'bar',
data:
{
labels: ['a','b','c'],
datasets:
[
{
label: 'A',
data: [1212,1122, 1188, 1617, 1116],
backgroundColor: 'green',
}
]
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script>
<div style="width:300px;height:200px"><canvas id="chart1"></canvas></div>
<div style="width:300px;height:200px"><canvas id="chart2"></canvas></div>
The first thing you could do is to set beginAtZero to false to Y axis of bar chart because is set to true by default:
https://github.com/chartjs/Chart.js/blob/v3.9.1/src/controllers/controller.bar.js#L636-L650
Then you can set the same scale config to both charts.
options: { // options of charts
scales: {
y: {
beginAtZero: false,
}
}
}
var chart1 = new Chart(document.getElementById('myChart1'),
{
type: 'line',
data:
{
labels: ['a','b','c'],
datasets:
[
{
label: 'A',
data: [1212,1122, 1188, 1617, 1116],
borderColor: 'green',
}
]
},
options: {
scales: {
y: {
beginAtZero: false,
}
}
}
});
var chart2 = new Chart(document.getElementById('myChart2'),
{
type: 'bar',
data:
{
labels: ['a','b','c'],
datasets:
[
{
label: 'A',
data: [1212,1122, 1188, 1617, 1116],
backgroundColor: 'green',
}
]
},
options: {
scales: {
y: {
beginAtZero: false,
}
}
}
});
.myChartDiv {
max-width: 300px;
max-height: 200px;
}
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.9.1/dist/chart.min.js"></script>
<html>
<body>
<div class="myChartDiv">
<canvas id="myChart1" width="300" height="200"/>
</div>
<div class="myChartDiv">
<canvas id="myChart2" width="300" height="200"/>
</div>
</body>
</html>

Unable to display dates and values on Chart.js

I have the following data stored in array:
var labelItems= ["3/27/20", "3/28/20", "3/29/20", "3/30/20", "3/31/20", "4/1/20", "4/2/20", "4/3/20", "4/4/20", "4/5/20", "4/6/20", "4/7/20", "4/8/20", "4/9/20", "4/10/20"]
var dataSets= [27198, 30652, 33925, 37582, 42107, 46809, 52983, 58787, 64606, 69374, 74565, 81865, 88338, 95455, 102525]
I have initialzed my line chart as follows:
var ctx = document.getElementById('lineChart').getContext('2d');
var chart = new Chart(ctx, {
// The type of chart we want to create
type: 'line',
// The data for our dataset
data: {
labels: labelItems,
datasets: [{
label: 'Deaths',
borderColor: 'rgb(255, 99, 132)',
data: dataSets
}]
},
// Configuration options go here
options: {}
});
My issue is that the dates, that is the labels are not displaying on the x-axis nor the datasets on the y-axis. Can someone please help with this?
As the documentation say, you have to add the parser and tooltipFormat properties to the axis (x or y) in order to display the value.
var ctx = document.getElementById('lineChart').getContext('2d');
var chart = new Chart(ctx, {
// The type of chart we want to create
type: 'line',
// The data for our dataset
data: {
labels: labels,
datasets: [{
label: 'Deaths',
borderColor: 'rgb(255, 99, 132)',
data: dataSets
}]
},
// Configuration options go here
options: {
scales: {
xAxis: [
display: true,
type: 'time'
time: {
parser: 'MM/DD/YYYY HH:mm',
tooltipFormat: 'll HH:mm',
unit: 'day',
unitStepSize: 1,
displayFormats: {
'day': 'MM/DD/YYYY'
}
}
]
}
}
});

How to draw a vertical line in chart.js2 without label

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?

Chartjs - Set start and end value into a Bar Chart

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>

Categories