apexcharts draw line chart on top of scatter chart - apexcharts

Currently using "Scatter Charts" to display my xy coordinates, working great. Another requirement is to draw a line chart based on average numbers on top of the scatter chart. Is this possible?
Link to Scatter Charts - https://apexcharts.com/angular-chart-demos/scatter-charts/basic/
Sample graph -

Yes, you can draw mixed charts with ApexCharts. You even have a demo of what you are looking for: Line Scatter – ApexCharts.js
I put the demo here for convenience:
let options = {
series: [{
name: 'Points',
type: 'scatter',
data: [{
x: 1,
y: 2.14
}, {
x: 1.2,
y: 2.19
}, {
x: 1.8,
y: 2.43
}, {
x: 2.3,
y: 3.8
}, {
x: 2.6,
y: 4.14
}, {
x: 2.9,
y: 5.4
}, {
x: 3.2,
y: 5.8
}, {
x: 3.8,
y: 6.04
}, {
x: 4.55,
y: 6.77
}, {
x: 4.9,
y: 8.1
}, {
x: 5.1,
y: 9.4
}, {
x: 7.1,
y: 7.14
},{
x: 9.18,
y: 8.4
}]
}, {
name: 'Line',
type: 'line',
data: [{
x: 1,
y: 2
}, {
x: 2,
y: 3
}, {
x: 3,
y: 4
}, {
x: 4,
y: 5
}, {
x: 5,
y: 6
}, {
x: 6,
y: 7
}, {
x: 7,
y: 8
}, {
x: 8,
y: 9
}, {
x: 9,
y: 10
}, {
x: 10,
y: 11
}]
}],
chart: {
height: 350,
type: 'line'
},
fill: {
type: 'solid'
},
markers: {
size: [6, 0]
},
tooltip: {
shared: false,
intersect: true
},
legend: {
show: false
},
xaxis: {
type: 'numeric',
min: 0,
max: 12,
tickAmount: 12
}
};
let chart = new ApexCharts(document.querySelector('#chart'), options);
chart.render();
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<div id="chart"></div>
This particular example has not been integrated using Angular, but I think you can do it quite easily. Take a look at this page if you need additional inspiration: Angular Mixed Chart / Combination Chart Examples – ApexCharts.js

Related

How to plot a line with (x,y) points?

Noob question, apologies, but reading through the docs it was not obvious, and doing the obvious thing is resulting all points on x==0 !?
Many thanks in advance!
My current code is
new Chart(canvasId,{
type: 'line',
data: {
datasets: [
{
label: 'Some Data',
data: [
{ x: 0, y: 2.344317674636841 },
{ x: 9, y: 2.2913742065429688 },
{ x: 19, y: 2.2962939739227295 },
{ x: 29, y: 2.26206374168396 },
{ x: 39, y: 2.2287118434906006 },
{ x: 49, y: 2.1946732997894287 },
{ x: 59, y: 2.192193031311035 },
{ x: 69, y: 2.1846773624420166 },
{ x: 79, y: 2.122765064239502 },
{ x: 89, y: 2.1172447204589844 },
{ x: 99, y: 2.125208616256714 },
]
},
]
}
});
You are using a line chart which uses a catagory scale by default for the x axes and as you can read in this section of the docs that does not work with integers https://www.chartjs.org/docs/3.9.1/general/data-structures.html#object
So you will need to set options.scales.x.type to 'linear'

ChartJs days of the week from numbers

I have a chart were the data looks like this where X represents days of the week:
{x: 1, y: 18, r: 4.7614}
{x: 6, y: 17, r: 4.7619}
{x: 0, y: 16, r: 4.7657}
I'd like to rename the numbers to weekdays on the X axis (0: "Sunday", 1: "Monday") etc., but I can't figure it out.
My config looks like this: (but obviously not working).
Any help would be appreciated, thank you.
const config = {
type: "bubble",
data: data,
options: {
responsive: true,
scales: {
x: ["Sun", "Mon", "Thu", "Wen", "Tru", "Fri", "Sat"],
},
},
}
You can use the tickCallback to transform the value to whatever you like, easyest thing to do is make an array with all the weekDays and then use the value as an index like so:
const weekDays = ["Sun", "Mon", "Thu", "Wen", "Tru", "Fri", "Sat"];
const options = {
type: 'bubble',
data: {
datasets: [{
label: '# of Votes',
data: [{
x: 0,
y: 1,
r: 4
}, {
x: 1,
y: 1,
r: 4
}, {
x: 2,
y: 1,
r: 4
}, {
x: 3,
y: 1,
r: 4
}, {
x: 4,
y: 1,
r: 4
}, {
x: 5,
y: 1,
r: 4
}, {
x: 6,
y: 1,
r: 4
}],
backgroundColor: 'pink'
}]
},
options: {
scales: {
x: {
ticks: {
callback: (val) => (weekDays[val])
}
}
}
}
};
const 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>

Render bars from multiple datasets at full-width when there is no overlapping data in ChartJS

Examples within. For reference, I am using the latest version of ChartJS (3.2.1) and the latest version of react-chartjs-2 (3.0.3).
I want to know how to make my bar chart display in a specific way given multiple, varying datasets. I'd like for the bars on the chart to render at their standard widths, while also allowing side-by-side overlapping where necessary.
ChartJS will handle this in my "ideal" way when you're using one dataset which may have two values that fall on the same X-Axis coordinate, but I can't seem to mimic this behavior when using multiple datasets.
It seems as though whenever two datasets share an axis, the bar widths either adjust to accommodate both sets of data even if they don't occupy the same space, or they stack on top of one another when should they occupy the same space. My goal is to only have the bars "shrink" their width when necessary, and keep their full-width otherwise.
Here is an example of what I would like to see with multiple datasets (this is how ChartJS handles the rendering when there is one dataset with barThickness: "flex" set):
In the middle, you'll notice the bar widths automatically adjusted to make room for one another.
Here is an example of what I get when I use two datasets that do not have any points where they overlap (barThickness: "flex" is set on both):
And, lastly, here is an example with some points of overlap when using two datasets:
So far the only way I've even sniffed a way around this is by creating multiple x-axes, one for one dataset, one for the other, and one for overlap. Then, by manipulating my data structures, creating datasets for each axis that contain exactly the datapoints that correspond to the desired bar widths.
That's certainly a solution, but I am dealing with a production codebase, thousands of rows of data, and several additional datasets (all of which have varying states, conditions for visibility, and rules). It becomes next-to-impossible to manage all of them together like this, let alone in a maintainable way. I've gone through the vast majority of StackOverflow questions and ChartJS documentation trying to find a cleaner solution, but have come up short thus far and would appreciate your help.
A simplified version of the code below. I've included some unused bits and pieces (mostly commented out) just to show the things I've tried thus far:
var ctx1 = document.getElementById("canvas1").getContext("2d");
var ctx2 = document.getElementById("canvas2").getContext("2d");
var ctx3 = document.getElementById("canvas3").getContext("2d");
function getBackgroundColor(data) {
const bar = data.dataset.data[data.dataIndex];
return bar.projection ? "green" : "black";
}
const dataset1Labels = ['Mar 2021', 'Apr 2021', 'May 2021', 'Jun 2021', 'Jul 2021', 'Aug 2021']
const dataset2Labels = ['Jan 2020', 'Feb 2020', 'Mar 2020', 'Apr 2020', ...dataset1Labels]
const dataset3Labels = ['Jan 2020', 'Feb 2020', 'Mar 2020', 'Apr 2020', 'May 2020', 'Jun 2020', 'Jul 2020', 'Aug 2020', ...dataset1Labels]
const dataset1 = [
{ x: "Mar 2021", y: 1, projection: false },
{ x: "Apr 2021", y: 4, projection: false },
{ x: "May 2021", y: 6, projection: false },
{ x: "May 2021", y: 9, projection: true },
{ x: "Jun 2021", y: 11, projection: true },
{ x: "Jul 2021", y: 13, projection: true },
{ x: "Aug 2021", y: 16, projection: true },
]
const dataset2 = [
{ x: "Jan 2020", y: 1 },
{ x: "Feb 2020", y: 4 },
{ x: "Mar 2020", y: 6 },
{ x: "Apr 2020", y: 8 },
{ x: "Mar 2021", y: 6 },
{ x: "Apr 2021", y: 8 },
]
const dataset3 = [
{ x: "Jan 2020", y: 1 },
{ x: "Feb 2020", y: 4 },
{ x: "Mar 2020", y: 6 },
{ x: "Apr 2020", y: 8 },
{ x: "May 2020", y: 10 },
{ x: "Jun 2020", y: 12 },
{ x: "Jul 2020", y: 12 },
{ x: "Aug 2020", y: 16 },
{ x: "Mar 2021", y: 1 },
{ x: "Apr 2021", y: 4 },
{ x: "May 2021", y: 6 },
]
var myChart = new Chart(ctx1, {
type: 'bar',
data: {
labels: dataset1Labels,
datasets: [{
label: "2 data types, distinguished by color",
data: dataset1,
backgroundColor: getBackgroundColor,
barThickness: "flex",
}]
},
options: {
plugins: {
title: {
display: true,
text: '1 dataset. Can Overlap. Full width bars.'
},
legend: {
position: "bottom",
},
},
scales: {
x: {
id: "dates",
offset: true,
},
}
}
});
var myChart2 = new Chart(ctx2, {
type: 'bar',
data: {
labels: dataset2Labels,
datasets: [
{
label: "previous year",
data: dataset2,
backgroundColor: "blue",
xAxisID: "dates",
},
{
label: "current year",
data: dataset1,
backgroundColor: "green",
},
]},
options: {
plugins: {
title: {
display: true,
text: '2 datasets. Cannot Overlap. Full width bars.'
},
legend: {
position: "bottom",
},
},
scales: {
x: {
id: "dates2",
display: false,
stacked: false,
bounds: "ticks",
grid: {
offset: true,
},
},
}
}
});
var myChart3 = new Chart(ctx3, {
type: 'bar',
data: {
labels: dataset3Labels,
datasets: [
{
label: "previous year",
data: dataset3,
backgroundColor: "blue",
// group: false,
// barThickness: "flex",
// categoryPercentage: 1,
// barPercentage: 1,
},
{
label: "current year",
data: dataset1,
backgroundColor: "green",
// group: false,
// categoryPercentage: 1,
// barThickness: "flex",
// barPercentage: 1,
},
]},
options: {
plugins: {
title: {
display: true,
text: '2 datasets. Can overlap. Half-width bars.'
},
legend: {
position: "bottom",
},
},
scales: {
x: {
id: "dates3",
display: false,
grid: {
offset: true,
},
},
}
}
});
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.2.1/dist/chart.min.js"></script>
<h2>Chart #1</h2>
<canvas id="canvas1"></canvas>
<h2>Chart #2</h2>
<p>Note that March and April 2021 both have data from both datasets, but only one dataset is visible</p>
<canvas id="canvas2"></canvas>
<h2>Chart #3</h2>
<canvas id="canvas3"></canvas>

Chartjs create chart with big data and fixed labels

I want to create chart of type line with chatjs. The problem is, I have date formatted: { x: real number from 0 to 1, y: integers from 0 to infinite }, and I want fixed labels to the chart in x-axis, something like: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1].
This is how I'd like to set the chart configuration:
type: 'line',
data: {
labels: ['0', '0.1', '0.2', '0.3', '0.4', '0.5', '0.6', '0.7', '0.8', '0.9', '1'],
datasets: [{
label: 'data',
data: [
{ x: 0.3, y: 446 },
{ x: 0.3331, y: 6863 },
{ x: 0.874, y: 12 },
{ x: 0.2244, y: 1565 },
{ x: 0.38899, y: 32221 },
{ x: 0.23685545, y: 3112324 },
{ x: 0.11332, y: 444423 },
{ x: 0.97694, y: 21212334 },
],
}]
},
But this is obviously not working, How can I do it?
So I found out there is another chart type of scatter. This is typically used to only points on axes chart, but it can configured to have lines between the points. Also, if marking the points on graph is unneccessary there is a configuration option to set those points' radius to 0 and this makes those hidden.
https://www.chartjs.org/docs/latest/charts/scatter.html#scatter-chart

ChartJS large data range

I have a dataset which has large range between the largest and the smallest. My problem is that the smallest bar becomes invisible when the largest bar has too much data. Take a look at the screenshot below.
In the screenshot, the second, third, fifth and sixth bars all have one data point but they are being invisible. So my question is,
1) Is there anyway to make small data point visible for bar chart such as by setting min-height property on them?
2) If not, how can I make the chart so that hovering works on whole y-axis for a particular bar when the data is too small so that when I hover over the y-axis it shows label with data?
I've tried setting different styles on the bars to no avail.
Since you haven't provided your code, I can only tell you to use a logarithmic scale for your chart.
See this example for reference:
var dataPoints = [
{ x: 1994, y: 25437639 },
{ x: 1995, y: 44866595 },
{ x: 1996, y: 77583866 },
{ x: 1997, y: 120992212 },
{ x: 1998, y: 188507628 },
{ x: 1999, y: 281537652 },
{ x: 2000, y: 414794957 },
{ x: 2001, y: 502292245 },
{ x: 2002, y: 665065014 },
{ x: 2003, y: 781435983 },
{ x: 2004, y: 913327771 },
{ x: 2005, y: 1030101289 },
{ x: 2006, y: 1162916818 },
{ x: 2007, y: 1373226988 },
{ x: 2008, y: 1575067520 },
{ x: 2009, y: 1766403814 },
{ x: 2010, y: 2023202974 },
{ x: 2011, y: 2231957359 },
{ x: 2012, y: 2494736248 },
{ x: 2013, y: 2728428107 },
{ x: 2014, y: 2956385569 },
{ x: 2015, y: 3185996155 },
{ x: 2016, y: 3424971237 }
];
var chart = new CanvasJS.Chart("chartContainer", {
animationEnabled: true,
zoomEnabled: true,
theme: "dark2",
title:{
text: "Growth in Internet Users Globally"
},
axisX:{
title: "Year",
valueFormatString: "####",
interval: 2
},
axisY:{
logarithmic: true, //change it to false
title: "Internet Users (Log)",
titleFontColor: "#6D78AD",
lineColor: "#6D78AD",
gridThickness: 0,
lineThickness: 1,
includeZero: false,
labelFormatter: addSymbols
},
axisY2:{
title: "Internet Users",
titleFontColor: "#51CDA0",
logarithmic: false, //change it to true
lineColor: "#51CDA0",
gridThickness: 0,
lineThickness: 1,
labelFormatter: addSymbols
},
legend:{
verticalAlign: "top",
fontSize: 16,
dockInsidePlotArea: true
},
data: [{
type: "line",
xValueFormatString: "####",
showInLegend: true,
name: "Log Scale",
dataPoints: dataPoints
},
{
type: "line",
xValueFormatString: "####",
axisYType: "secondary",
showInLegend: true,
name: "Linear Scale",
dataPoints: dataPoints
}]
});