Chart JS - Group Array Results on y axis - javascript

I think I am close to solving this but I am missing something critical. I have an array of "new" items that I am trying to plot on a chart to indicate how old they are. I can get the chart to load and plot the data but like items are not grouping onto the same line. Is there a way I can force the chart to put like types onto the same axis line in the chart? i.e. the 2 SAFE AE results load onto the same line? Any guidance would be appreciated!
var whatsNewArray = [{
"type": "EAC",
"age": -16
},
{
"type": "EAC",
"age": -58
},
{
"type": "DSCC",
"age": -36
},
{
"type": "SAFE AE",
"age": -95
},
{
"type": "SAFE AE",
"age": -94
}
]
new Chart(document.getElementById("myWHATSNEWChart"), {
type: 'scatter',
data: {
datasets: [{
data: whatsNewArray.map(function(a) {
return a.age;
}),
backgroundColor: ["#acc6ff"],
label: "New Items",
pointRadius: 10,
fill: true
}]
},
options: {
indexAxis: 'y',
maintainAspectRatio: false,
responsive: true,
layout: {
padding: 20
},
scales: {
y: {
ticks: {
color: "#a3a3a3"
},
type: "category",
labels: whatsNewArray.map(function(a) {
return a.type;
}),
grid: {
color: "#a3a3a3",
borderColor: "#a3a3a3"
}
},
x: {
title: {
display: true,
text: "MINUTES AGO",
color: "#a3a3a3"
},
ticks: {
color: "#a3a3a3"
},
beginAtZero: true,
grid: {
color: "#a3a3a3",
borderColor: "#a3a3a3"
},
border: {
color: "#a3a3a3"
}
}
},
plugins: {
legend: {
display: false,
title: {
color: "#a3a3a3"
},
labels: {
color: "#a3a3a3"
}
},
title: {
display: false,
//text: 'What is New',
color: "#a3a3a3"
}
}
}
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/6.1.0/mdb.dark.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/6.1.0/mdb.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.2.0/chart.umd.js"></script>
<div class="chart-container mb-4" style="position: relative;width:100%;height:250px;background-color:#283044;">
<canvas id="myWHATSNEWChart"></canvas>
</div>

I've created this minimal example, for your problem. You can add your custom options as you wish.
You have to treat the y-axis as an index, so .findIndex(el => el.type == elem.type) is checking if the elem.type exists in an array and returns the index of the found element.
var whatsNewArray = [{
"type": "EAC",
"age": -16
},
{
"type": "EAC",
"age": -58
},
{
"type": "DSCC",
"age": -36
},
{
"type": "SAFE AE",
"age": -95
},
{
"type": "SAFE AE",
"age": -94
},
{
"type": "DSCC",
"age": -2
},
{
"type": "EL",
"age": -2
},
{
"type": "PSY",
"age": -20
},
{
"type": "CNGRO",
"age": -80
},
{
"type": "CNGRO",
"age": -69
},
];
let label = [...new Map(whatsNewArray.map(item =>
[item["type"], item["type"]])).values()];
let data = whatsNewArray.map(function(elem, index) {
return {
x: elem.age,
y: label.indexOf(elem.type)
}
});
const _data = {
datasets: [{
label: 'Scatter Dataset',
data: data,
backgroundColor: 'rgb(255, 99, 132)'
}],
};
const config = {
type: 'scatter',
data: _data,
options: {
responsive: true,
layout: {
padding: 20
},
pointRadius: 10,
fill: true,
scales: {
y: {
autofill: false,
labels: label,
ticks: {
callback: function(value, index, ticks) {
return value % 1 == 0 ? label[value] : ''
}
},
}
}
}
};
new Chart(document.getElementById("myWHATSNEWChart"), config);
<link href="https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/6.1.0/mdb.dark.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/6.1.0/mdb.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.2.0/chart.umd.js"></script>
<canvas id="myWHATSNEWChart"></canvas>
Explanation: So the index of an array label is being recognized as y-axis data [0,1,2....].
This returns distinct values:
[...new Map(whatsNewArray.map(item => [item["type"], item["type"]])).values()];
This checks if the value is an integer, for removing decimal values in this context.
value % 1 == 0

Related

chart js bar chart is not getting displayed correctly

Below is my configuration which i am using in chart js , but the bar is not getting displayed correctly . This is a payload which i am sending from external application to node js server which then renders the chart to an image
This is a payload which i am sending from external application to node js server which then renders the chart to an image
Wanted to know How can i display all the bars according to years.
var configuration = {
type: 'bar',
data: {
labels: ['2019', '2020', '2021', '2022', '2023', '2024', '2025'],
datasets: [{
label: "2019",
backgroundColor: "#E23D16",
data: [Math.random() * 100],
}, {
label: "2020",
backgroundColor: "#BF9810",
data: [Math.random() * 100],
}, {
label: "2021",
backgroundColor: "#C18D11",
data: [Math.random() * 100],
}, {
label: "2022",
backgroundColor: "#088B64",
data: [Math.random() * 100],
}, {
label: "2023",
backgroundColor: "#0F428D",
data: [Math.random() * 100],
}, {
label: "2024",
backgroundColor: "#AB290D",
data: [Math.random() * 100],
}, {
label: "2025",
backgroundColor: "#0F428D",
data: [Math.random() * 100],
}
]
},
options: {
interaction: {
intersect: true,
mode: 'nearest'
},
indexAxis: 'x',
//maintainAspectRatio: false,
legend: { display: true, position: 'right' },
title: { display: true, text: "" },
plugins: {
legend: {
display: true,
position: 'right'
},
tooltip: {
callbacks: {
title: () => null
}
},
datalabels: {
display: true,
color: "white",
labels: {
title: { color: "white", font: { weight: "bold" } },
value: { color: "white" }
},
formatter: (value) => {
return value + '%';
}
}
},
scales: {
y: {
beginAtZero: true,
scaleLabel: {
labelString: 'Month'
},
ticks: {
format: {
style: 'percent'
}
}
},
}
}
}
I think you could have 1 dataset with 7 data values instead of 7 datasets.
Furthermore, scaleLabel.labelString is changed in chart.js version 3 to title.text.
var configuration = {
type: 'bar',
data: {
labels: ['2019', '2020', '2021', '2022', '2023', '2024', '2025'],
datasets: [{
label: "Distribution",
backgroundColor: [
"#E23D16",
"#BF9810",
"#C18D11",
"#088B64",
"#0F428D",
"#AB290D",
"#0F428D",
],
data: [
Math.random() * 100,
Math.random() * 100,
Math.random() * 100,
Math.random() * 100,
Math.random() * 100,
Math.random() * 100,
Math.random() * 100
],
}]
},
options: {
interaction: {
intersect: true,
mode: 'nearest'
},
indexAxis: 'x',
//maintainAspectRatio: false,
legend: { display: true, position: 'right' },
title: { display: true, text: "" },
plugins: {
legend: {
display: true,
position: 'right'
},
tooltip: {
callbacks: {
title: () => null
}
},
datalabels: {
display: true,
color: "white",
labels: {
title: {
color: "white",
font: { weight: "bold" }
},
value: { color: "white" }
},
formatter: (value) => {
return value.toFixed(1) + '%';
}
}
},
scales: {
y: {
beginAtZero: true,
title: {
display: true,
text: 'Month'
},
ticks: {
format: {
style: 'percent'
}
}
},
}
}
}
Chart.register(ChartDataLabels);
const myChart = new Chart(
document.getElementById('myChart'),
configuration
);
.myChartDiv {
max-width: 600px;
max-height: 400px;
}
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.9.1/dist/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels#2.1.0/dist/chartjs-plugin-datalabels.min.js"></script>
<html>
<body>
<div class="myChartDiv">
<canvas id="myChart" width="600" height="400"/>
</div>
</body>
</html>

Highcharts not displaying chart but no errors

I'm working on data visualization with Highcharts but since I started fetching my data from an API, it doesn't display anymore.
Data is response from the API. The information is gotten from the array (trying to mimic an API here), but this still doesn't display after a lot of tweaking and it doesn't display any errors.
It be helpful if one could also point out how to display highchart errors.
$(document).ready(function() {
Highcharts.setOptions({
lang: {
numericSymbols: null
}
});
data = [{
"chart": {
"height": 500,
"renderTo": "chart_ID",
"type": "line"
},
"plotOptions": {
"line": {
"dataLabels": {
"enabled": true
},
"enableMouseTracking": false
}
},
"series": [{
"data": [5000.0, 4100.0, 1000.0, 7500.0, 5100.0, 5000.0],
"name": "Amount"
}, {
"data": [179, 86, 150, 393, 188, 322],
"name": "Millage"
}],
"title": {
"text": "Jhpiego Fuel Consumption"
},
"xAxis": {
"categories": ["3 Jul", "12 Jul", "13 Jul", "14 Jul", "15 Jul", "16 Jul"]
},
"yAxis": {
"max": 1000000,
"title": {
"text": "Fuel Price"
}
}
}]
apiData = data[0];
highChartInfo = {
chart: {
renderTo: apiData.chart.renderTo,
type: apiData.chart.type,
height: 500,
displayErrors: true
},
plotOptions: {
line: {
dataLabels: {
enabled: apiData.plotOptions.line.dataLabels.enabled
},
enableMouseTracking: apiData.plotOptions.line.enableMouseTracking
}
},
title: {
text: apiData.title.text
},
xAxis: {
categories: apiData.xAxis.categories
},
yAxis: {
title: {
text: apiData.yAxis.title.text
},
max: apiData.yAxis.max
},
series: [{
name: apiData.series[0].name,
data: apiData.series[0].data
},
{
name: apiData.series[1].name,
data: apiData.series[1].data
}
],
}
console.log(highChartInfo)
$(data[0].chart.renderTo).highcharts(highChartInfo);
});
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<div id="chart_ID" class="chart" style="height: 100%; width: 100%"></div>

How to make dynamic charts in Javascript with a JSON File

So, I am new to Javascript, but I have a code to make a stable bar chart, but I need to make it dynamic.
MY JSON File format is:
"valid_columns_counts": {
"Sr no.": 0,
"Domain": 37,
"Company Name": 0,
"Address": 36,
"Industry": 38,
"Phone Number": 30,
"Zipcode": 33,
"email": 14}
I ran this code:
window.onload = function () {
var dataPoints = [];
var chart = new CanvasJS.Chart("chartContainer", {
animationEnabled: true,
title:{
},
axisY: {
title: "Percentage",
titleFontColor: "#4F81BC",
},
toolTip: {
shared: true
},
legend: {
cursor:"pointer",
itemclick: toggleDataSeries
},
data:
{
type: "column",
name: "Consistency",
legendText: "Consistency",
axisYType: "secondary",
showInLegend: true,
dataPoints: dataPoints
}
});
function addData(data) {
for (var i = 0; i < data.length; i++) {
dataPoints.push({
x: data[i].valid_columns_counts
y: data[i].valid_columns_counts
});
}
}
chart.render();
$.getJSON("localhost/sample_output.json", addData);
}
But this code shows blank page when runned.Please if someone can help me.

eCharts stacked bar graph - Y axis

Playing around with eCharts and i'm trying to replicate the graph shown in this tutorial
https://medium.com/#mailjontay/make-a-dynamic-chart-with-react-and-echarts-a-simple-tutorial-92a5c3c053a2
I'm using my own data sets, and both of my .js files are identical format to the ones used in the tutorial.
I'm having an issue with rendering the number of workers on my Yaxis, I'm not receiving any error messages and my data is defined.
My code is as follows:
import React, { Component } from "react";
import ReactEcharts from "echarts-for-react";
import { workForceDataFemale } from "./WorkForceDataFemale";
import { workForceDataMale } from "./WorkForceDataMale";
class App extends Component {
getOption = () => {
let sectors = [];
let years = [];
let workforceObject = [];
let workers = [];
Object.entries(workForceDataFemale).forEach(entry => {
years = [...years, entry[0]];
workforceObject = [...workforceObject, entry[1]];
entry[1].forEach(e => {
workers = [...new Set([...workers, e.n_workers])]
console.log(e.n_workers, "number of workers")
sectors = [...new Set([...sectors, e.sector])];
});
});
let options = years.map(year => {
let obj = {};
obj["series"] = [
{
stack: "group",
data: workForceDataFemale[year]
},
{
stack: "group",
data: workForceDataMale[year]
}
];
obj["title"] = {
text: `Number of workers over time by gender`
};
return obj;
});
return {
baseOption: {
timeline: {
autoPlay: false,
axisType: "category",
bottom: 20,
data: years,
height: null,
inverse: true,
left: null,
orient: "vertical",
playInterval: 1000,
right: 0,
top: 20,
width: 55,
label: {
normal: {
textStyle: {
color: "#aaa"
}
},
emphasis: {
textStyle: {
color: "#333"
}
}
},
symbol: "none",
lineStyle: {
color: "#aaa"
},
checkpointStyle: {
color: "#354EF6",
borderColor: "transparent",
borderWidth: 2
},
controlStyle: {
showNextBtn: false,
showPrevBtn: false,
normal: {
color: "#354EF6",
borderColor: "#354EF6"
},
emphasis: {
color: "#5d71f7",
borderColor: "#5d71f7"
}
}
},
color: ["#e91e63", "#354EF6"],
title: {
subtext: "Data from Sweet Analytics",
textAlign: "left",
left: "5%"
},
tooltip: { backgroundColor: "#555", borderWidth: 0, padding: 10 },
legend: {
data: ["Female", "Male"],
itemGap: 35,
itemHeight: 18,
right: "11%",
top: 20
},
calculable: true,
grid: {
top: 100,
bottom: 150,
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow",
label: {
show: true,
formatter: function(params) {
return params.value.replace("\n", "");
}
}
}
}
},
xAxis: [
{
axisLabel: {
interval: 0,
rotate: 55,
textStyle: {
baseline: "top",
color: "#333",
fontSize: 10,
fontWeight: "bold"
}
},
axisLine: { lineStyle: { color: "#aaa" }, show: true },
axisTick: { show: false },
data: sectors,
splitLine: { show: false },
type: "category"
}
],
yAxis: [
{
axisLabel: {
textStyle: { fontSize: 10 }
},
axisLine: { show: false },
axisTick: { show: false },
name: "Population",
splitLine: {
lineStyle: {
type: "dotted"
}
},
type: "value"
}
],
series: [{ name: "Female", type: "bar", data: workers }, { name: "Male", type: "bar", data: workers }]
},
options: options
};
};
render() {
return (
<ReactEcharts
option={this.getOption()}
style={{ height: "85vh", left: 50, top: 50, width: "90vw" }}
opts={{ renderer: "svg" }}
/>
);
}
}
export default App;
This is how far i've gotten :
And I'm trying to get to here:
In the series you should add stack you have in each object to add stack: "stackbar" like this :
series: [
{ name: "Female", type: "bar", data: workers, stack: "stackbar" },
{ name: "Male", type: "bar", data: workers , stack: "stackbar"}
]

How to get all json values in line chart

I have many Json values, using them I am going to create a line chart but it shows only one value in the chart. I am a newbie to javascript and have an idea to plot all values in chart. please anybody give jsfiddle example for this issue.
HTML code
<div id="chartContainer" class="chart">
Script
$.getJSON('dashboard_summary.php?', function(data) {
var len = data.length
$.each(data, function(i, v) {
chart(v.Date,v.Tip,v.Revenue,len);
});
});
function chart (dates,Tip,Rev,len) {
var chart = new CanvasJS.Chart("chartContainer", {
title: {
text: "Revenue",
fontSize: 15
},
axisX: {
gridColor: "Silver",
tickColor: "silver",
valueFormatString: "DD/MMM"
},
toolTip: {
shared:true
},
theme: "theme2",
axisY: {
gridColor: "Silver",
tickColor: "silver"
},
legend: {
verticalAlign: "center",
horizontalAlign: "right"
},
data: [
{
type: "line",
showInLegend: true,
lineThickness: 2,
name: "Tip",
markerType: "square",
color: "#F08080",
dataPoints: [
{
x: new Date(dates),
y: parseInt(Tip)
}
]
},
{
type: "line",
showInLegend: true,
name: "Revenue",
color: "#20B2AA",
lineThickness: 2,
dataPoints: [
{
x: new Date(dates),
y: parseInt(Rev)
}
]
}
],
legend: {
cursor: "pointer",
itemclick: function(e) {
if (typeof(e.dataSeries.visible) === "undefined" || e.dataSeries.visible) {
e.dataSeries.visible = false;
} else {
e.dataSeries.visible = true;
}
chart.render();
}
}
});
chart.render();
};
Json data
{
"Date": "2014-01-30",
"CarsParked": "1",
"RevenueWithTip": "0",
"Revenue": "0",
"Tip": "0",
},
{
"Date": "2014-01-31",
"CarsParked": "10",
"RevenueWithTip": "10",
"Revenue": "7",
"Tip": "3",
},
{
"Date": "2014-02-28",
"CarsParked": "28",
"RevenueWithTip": "55",
"Revenue": "47",
"Tip": "8",
}
Based on your code, I can see why the chart shows only one point, which is the last data point of those points expected to be shown on the chart. Here is the problem:
var len = data.length;
/* Loop through each item in the data */
$.each(data, function(i, v) {
chart(v.Date,v.Tip,v.Revenue,len); /* Draw a chart with one point */
});
So you end up drawing many charts with the last chart which has the last data point to replace all the previous charts.
Instead, you should adjust the foreach block as follow and draw the chart once you've converted the data into an array of points.
$.getJSON('dashboard_summary.php?', function(data) {
var Tips = [];
var Revs = [];
$.each(data, function(i, v) {
Tips.push({ x: new Date(v.Date), y: parseInt(v.Tip) });
Revs.push({ x: new Date(v.Date), y: parseInt(v.Revenue) });
});
chart(Tips, Revs);
});
Also, you can format the x-axis to make the chart look prettier (The format of the x-axis here is designed for the data given above. In your application, you may have to use another format style depending on the actual data):
function chart (Tips, Revs) {
var chart = new CanvasJS.Chart("chartContainer", {
title: {
text: "Revenue",
fontSize: 15
},
axisX: {
gridColor: "Silver",
tickColor: "silver",
valueFormatString: "DD/MMM",
interval:14,
intervalType: "day"
},
toolTip: {
shared:true
},
theme: "theme2",
axisY: {
gridColor: "Silver",
tickColor: "silver"
},
legend: {
verticalAlign: "center",
horizontalAlign: "right"
},
data: [
{
type: "line",
showInLegend: true,
lineThickness: 2,
name: "Tip",
markerType: "square",
color: "#F08080",
dataPoints: Tips
},
{
type: "line",
showInLegend: true,
name: "Revenue",
color: "#20B2AA",
lineThickness: 2,
dataPoints: Revs
}
],
legend: {
cursor: "pointer",
itemclick: function(e) {
if (typeof(e.dataSeries.visible) === "undefined" || e.dataSeries.visible) {
e.dataSeries.visible = false;
} else {
e.dataSeries.visible = true;
}
chart.render();
}
}
});
chart.render();
}
A jsFiddle is made here for your review.
Updated codes. it Works >> Pastebin
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript" src = "http://canvasjs.com/wp-content/themes/bootstrap_child/assets/js/jquery-1.8.3.min.js"> </script>
<script type="text/javascript" src="http://canvasjs.com/assets/script/canvasjs.min.js"></script>
</head>
<body>
<div id="chartContainer" class="chart">
<script type="text/javascript">
data=[
{
"Date": "2014-01-30",
"CarsParked": "1",
"RevenueWithTip": "0",
"Revenue": "0",
"Tip": "0",
},
{
"Date": "2014-01-31",
"CarsParked": "10",
"RevenueWithTip": "10",
"Revenue": "7",
"Tip": "3",
},
{
"Date": "2014-02-28",
"CarsParked": "28",
"RevenueWithTip": "55",
"Revenue": "47",
"Tip": "8",
}];
var len = data.length;
$.each(data, function(i, v) {
chart(v.Date,v.Tip,v.Revenue,len);
});
function chart (dates,Tip,Rev,len) {
var chart = new CanvasJS.Chart("chartContainer", {
title: {
text: "Revenue",
fontSize: 15
},
axisX: {
gridColor: "Silver",
tickColor: "silver",
valueFormatString: "DD/MMM"
},
toolTip: {
shared:true
},
theme: "theme2",
axisY: {
gridColor: "Silver",
tickColor: "silver"
},
legend: {
verticalAlign: "center",
horizontalAlign: "right"
},
data: [
{
type: "line",
showInLegend: true,
lineThickness: 2,
name: "Tip",
markerType: "square",
color: "#F08080",
dataPoints: [
{
x: new Date(dates),
y: parseInt(Tip)
}
]
},
{
type: "line",
showInLegend: true,
name: "Revenue",
color: "#20B2AA",
lineThickness: 2,
dataPoints: [
{
x: new Date(dates),
y: parseInt(Rev)
}
]
}
],
legend: {
cursor: "pointer",
itemclick: function(e) {
if (typeof(e.dataSeries.visible) === "undefined" || e.dataSeries.visible) {
e.dataSeries.visible = false;
} else {
e.dataSeries.visible = true;
}
chart.render();
}
}
});
chart.render();
}
</script>
</body>
</html>
jsFiddle
Update Code:
dataRevenue=
[
{ x: new Date(2014, 00,30), y: 0 },
{ x: new Date(2014, 01,31), y: 7},
{ x: new Date(2014, 02,28), y: 47}
];
dataTip =[
{ x: new Date(2014, 00,30), y: 0 },
{ x: new Date(2014, 01,31), y: 3},
{ x: new Date(2014, 02,28), y: 8}
];
var chart = new CanvasJS.Chart("chartContainer",
{
theme: "theme2",
title:{
text: "line chart"
},
axisX: {
valueFormatString: "MMM",
interval:1,
intervalType: "month"
},
axisY:{
includeZero: false
},
data: [
{
type: "line",
//lineThickness: 3,
dataPoints: dataTip
},
{
type: "line",
//lineThickness: 3,
dataPoints: dataRevenue
}
]
});
chart.render();

Categories

Resources