Chartjs! How to remove datalabel when value is 0 - javascript

I have a graph with some values ​​from the database (2,1,0 ...). I would like that when the value was "0" the number would not appear on the graph, more than it would be hidden.
I tried to use this function within the yAxes ticks but it didn't work:
callback: function (datalabels) {
if (datalabels <= 0) {
style.display = 'none';
}
return datalabels;
}
How can I do this?
Obs: Sorry for English.
async function grMeioEmpregado() {
let agressaoFisica = 0;
let armaBranca = 0;
let armaFogo = 0;
let asfixia = 0;
let fogo = 0;
let objetoContundente = 0;
let veneno = 0;
let outro = 0;
let nCI = 0;
const url = `/Crime/AjaxAgressaoFisica`
const url2 = `/Crime/AjaxArmaBranca`
const url3 = `/Crime/AjaxArmaFogo`
const url4 = `/Crime/AjaxAsfixia`
const url5 = `/Crime/AjaxFogo`
const url6 = `/Crime/AjaxObjetoContundente`
const url7 = `/Crime/AjaxVeneno`
const url8 = `/Crime/AjaxOutroMeioEmpregado`
const url9 = `/Crime/AjaxNCIMeioEmpregado`
try {
const resposta = await fetch(url);
const resposta2 = await fetch(url2);
const resposta3 = await fetch(url3);
const resposta4 = await fetch(url4);
const resposta5 = await fetch(url5);
const resposta6 = await fetch(url6);
const resposta7 = await fetch(url7);
const resposta8 = await fetch(url8);
const resposta9 = await fetch(url9);
const resultado = await resposta.json();
const resultado2 = await resposta2.json();
const resultado3 = await resposta3.json();
const resultado4 = await resposta4.json();
const resultado5 = await resposta5.json();
const resultado6 = await resposta6.json();
const resultado7 = await resposta7.json();
const resultado8 = await resposta8.json();
const resultado9 = await resposta9.json();
agressaoFisica = resultado;
armaBranca = resultado2;
armaFogo = resultado3;
asfixia = resultado4;
fogo = resultado5;
objetoContundente = resultado6;
veneno = resultado7;
outro = resultado8;
nCI = resultado9;
} catch (e) {
console.error(e);
}
const label = ['Agressão Física', 'Arma Branca', 'Arma de Fogo', 'Asfixia', 'Fogo',
'Objeto Contundente', 'Veneno', 'Outro', 'NCI - Não Consta Informação'];
const datasArr = [agressaoFisica, armaBranca, armaFogo, asfixia, fogo, objetoContundente, veneno, outro, nCI];
const sortedData = datasArr.map((v, i) => ({
rate: v,
tipos: label[i]
})).sort((o2, o1) => o1.rate - o2.rate);
var ctx = document.getElementById('grMeioEmpregado').getContext('2d');
var chart = new Chart(ctx, {
type: 'horizontalBar',
data: {
labels: sortedData.map(o => o.tipos),
datasets: [{
label: 'Nº de Meios empregado',
backgroundColor: [
'RGBA(178,235,242,0.56)',
'RGBA(178,235,242,0.56)',
'RGBA(178,235,242,0.56)',
'RGBA(178,235,242,0.56)',
'RGBA(178,235,242,0.56)',
'RGBA(178,235,242,0.56)',
],
borderWidth: 1,
borderColor: 'RGBA(0,172,193,0.48)',
hoverBackgroundColor: 'RGBA(0,172,193,0.22)',
hoverBorderColor: 'RGBA(0,172,193,0.48)',
data: sortedData.map(o => o.rate),
}]
},
options: {
scales: {
xAxes: [{
ticks: {
autoSkip: false,
min: 0,
max: 10,
callback: function (value) {
return value + "%"
}
},
scaleLabel: {
display: true,
labelString: "Porcentagem"
}
}],
yAxes: [{
ticks: {
beginAtZero: true,
}
}],
},
responsive: true,
legend: {
labels: {
fontSize: 15,
}
},
animation: {
animateScale: true,
duration: 2000,
},
plugins: {
datalabels: {
color: '#616161',
}
}
}
});
}
grMeioEmpregado();

You can use formatter instead of callback like below.
plugins: {
datalabels: {
color: '#616161',
formatter: (value) => {
return value > 0 ? value : '';
}
}
}
One of the examples is as follows.
https://jsfiddle.net/opgk246j/

Related

Javascript not pushing data to the dataArray

Im not a javascript guy but I had some help getting my chart working with chart js here, but since then I had to change the data structure from just 2 tables to 3 (with oneToMany - manyToOne). I feel Im pretty close but can I get some help with pushing the employeeProjectMonths to the dataArray?
The listEmployees looks like this:
var listEmployees = [
{"id":1,"name":"Bill Turner","contractedFrom":"2022-09-01","contractedTo":"2022-10-30",
"employeeProjects":[
{"id":14,"project":{"id":7,"projectNumber":12345,"name":"Project 7","startDate":"2020-01-01","endDate":"2022-12-31","projectLengthInMonths":30.0,"currentBookedMonths":28.0,"remainingBookedMonths":2.0,"numberOfEmployees":5},"employeeBookedMonths":7.7},
{"id":2,"project":{"id":6,"projectNumber":66666,"name":"Project 6","startDate":"2020-10-01","endDate":"2021-12-31","projectLengthInMonths":35.0,"currentBookedMonths":60.0,"remainingBookedMonths":6.0,"numberOfEmployees":6},"employeeBookedMonths":6.0},
{"id":7,"project":{"id":7,"projectNumber":12345,"name":"Project 7","startDate":"2020-01-01","endDate":"2022-12-31","projectLengthInMonths":30.0,"currentBookedMonths":28.0,"remainingBookedMonths":2.0,"numberOfEmployees":5},"employeeBookedMonths":8.0},
{"id":5,"project":{"id":9,"projectNumber":56789,"name":"Project 9","startDate":"2020-10-01","endDate":"2021-12-31","projectLengthInMonths":35.0,"currentBookedMonths":30.0,"remainingBookedMonths":5.0,"numberOfEmployees":3},"employeeBookedMonths":8.0},
{"id":15,"project":{"id":8,"projectNumber":54321,"name":"Project 8","startDate":"2020-05-01","endDate":"2022-06-31","projectLengthInMonths":40.0,"currentBookedMonths":32.0,"remainingBookedMonths":8.0,"numberOfEmployees":4},"employeeBookedMonths":8.8}]},
{"id":2,"name":"Kate Miller","contractedFrom":"2022-01-01","contractedTo":"2022-05-30",
"employeeProjects":[
{"id":3,"project":{"id":4,"projectNumber":44444,"name":"Project 4","startDate":"2020-01-01","endDate":"2022-12-31","projectLengthInMonths":30.0,"currentBookedMonths":40.0,"remainingBookedMonths":4.0,"numberOfEmployees":4},"employeeBookedMonths":14.0},
{"id":6,"project":{"id":7,"projectNumber":12345,"name":"Project 7","startDate":"2020-01-01","endDate":"2022-12-31","projectLengthInMonths":30.0,"currentBookedMonths":28.0,"remainingBookedMonths":2.0,"numberOfEmployees":5},"employeeBookedMonths":5.0},
{"id":8,"project":{"id":9,"projectNumber":56789,"name":"Project 9","startDate":"2020-10-01","endDate":"2021-12-31","projectLengthInMonths":35.0,"currentBookedMonths":30.0,"remainingBookedMonths":5.0,"numberOfEmployees":3},"employeeBookedMonths":5.0},
{"id":13,"project":{"id":8,"projectNumber":54321,"name":"Project 8","startDate":"2020-05-01","endDate":"2022-06-31","projectLengthInMonths":40.0,"currentBookedMonths":32.0,"remainingBookedMonths":8.0,"numberOfEmployees":4},"employeeBookedMonths":6.6}]},
{"id":3,"name":"John Smith","contractedFrom":"2022-06-01","contractedTo":"2022-12-30","employeeProjects":[
{"id":12,"project":{"id":1,"projectNumber":12345,"name":"Project 1","startDate":"2020-01-01","endDate":"2022-12-31","projectLengthInMonths":30.0,"currentBookedMonths":28.0,"remainingBookedMonths":2.0,"numberOfEmployees":5},"employeeBookedMonths":2.5}]}];
and this is the chart
const labels = listEmployees.reduce(function(result, item) {
result.push(item.name);
return result;
}, []);
const randomColorGenerator = function () {
return '#' + (Math.random().toString(16) + '0000000').slice(2, 8);
};
const projects = listEmployees.reduce(function(result, item) {
item.employeeProjects.forEach(function(prj){
const prjId = prj.project.id;
if (!result[prjId]) {
result[prjId] = {
label: prj.project.name,
data: [],
backgroundColor: randomColorGenerator()
};
}
});
return result;
}, {});
listEmployees.forEach(function(item) {
for (const prjId of Object.keys(projects)) {
const prj = projects[prjId];
const empPrj = item.employeeProjects.filter(el => el.project.id === prjId);
if (empPrj.length) {
prj.data.push(empPrj[0].employeeBookedMonths);
} else {
prj.data.push(0);
}
}
});
const ctx = document.getElementById("myChart");
const myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: Object.values(projects)
},
options: {
scales: {
x: {
stacked: true
},
y: {
stacked: true
}
}
}
});
The issue is here:
const empPrj = item.employeeProjects.filter(el => el.project.id === prjId);
because you are comparing a string with a number.
Change it in
const empPrj = item.employeeProjects.filter(el => el.project.id === parseFloat(prjId));
and it should work. See snippet.
var listEmployees = [
{"id":1,"name":"Bill Turner","contractedFrom":"2022-09-01","contractedTo":"2022-10-30",
"employeeProjects":[
{"id":14,"project":{"id":7,"projectNumber":12345,"name":"Project 7","startDate":"2020-01-01","endDate":"2022-12-31","projectLengthInMonths":30.0,"currentBookedMonths":28.0,"remainingBookedMonths":2.0,"numberOfEmployees":5},"employeeBookedMonths":7.7},
{"id":2,"project":{"id":6,"projectNumber":66666,"name":"Project 6","startDate":"2020-10-01","endDate":"2021-12-31","projectLengthInMonths":35.0,"currentBookedMonths":60.0,"remainingBookedMonths":6.0,"numberOfEmployees":6},"employeeBookedMonths":6.0},
{"id":7,"project":{"id":7,"projectNumber":12345,"name":"Project 7","startDate":"2020-01-01","endDate":"2022-12-31","projectLengthInMonths":30.0,"currentBookedMonths":28.0,"remainingBookedMonths":2.0,"numberOfEmployees":5},"employeeBookedMonths":8.0},
{"id":5,"project":{"id":9,"projectNumber":56789,"name":"Project 9","startDate":"2020-10-01","endDate":"2021-12-31","projectLengthInMonths":35.0,"currentBookedMonths":30.0,"remainingBookedMonths":5.0,"numberOfEmployees":3},"employeeBookedMonths":8.0},
{"id":15,"project":{"id":8,"projectNumber":54321,"name":"Project 8","startDate":"2020-05-01","endDate":"2022-06-31","projectLengthInMonths":40.0,"currentBookedMonths":32.0,"remainingBookedMonths":8.0,"numberOfEmployees":4},"employeeBookedMonths":8.8}]},
{"id":2,"name":"Kate Miller","contractedFrom":"2022-01-01","contractedTo":"2022-05-30",
"employeeProjects":[
{"id":3,"project":{"id":4,"projectNumber":44444,"name":"Project 4","startDate":"2020-01-01","endDate":"2022-12-31","projectLengthInMonths":30.0,"currentBookedMonths":40.0,"remainingBookedMonths":4.0,"numberOfEmployees":4},"employeeBookedMonths":14.0},
{"id":6,"project":{"id":7,"projectNumber":12345,"name":"Project 7","startDate":"2020-01-01","endDate":"2022-12-31","projectLengthInMonths":30.0,"currentBookedMonths":28.0,"remainingBookedMonths":2.0,"numberOfEmployees":5},"employeeBookedMonths":5.0},
{"id":8,"project":{"id":9,"projectNumber":56789,"name":"Project 9","startDate":"2020-10-01","endDate":"2021-12-31","projectLengthInMonths":35.0,"currentBookedMonths":30.0,"remainingBookedMonths":5.0,"numberOfEmployees":3},"employeeBookedMonths":5.0},
{"id":13,"project":{"id":8,"projectNumber":54321,"name":"Project 8","startDate":"2020-05-01","endDate":"2022-06-31","projectLengthInMonths":40.0,"currentBookedMonths":32.0,"remainingBookedMonths":8.0,"numberOfEmployees":4},"employeeBookedMonths":6.6}]},
{"id":3,"name":"John Smith","contractedFrom":"2022-06-01","contractedTo":"2022-12-30","employeeProjects":[
{"id":12,"project":{"id":1,"projectNumber":12345,"name":"Project 1","startDate":"2020-01-01","endDate":"2022-12-31","projectLengthInMonths":30.0,"currentBookedMonths":28.0,"remainingBookedMonths":2.0,"numberOfEmployees":5},"employeeBookedMonths":2.5}]}];
const labels = listEmployees.reduce(function(result, item) {
result.push(item.name);
return result;
}, []);
const randomColorGenerator = function () {
return '#' + (Math.random().toString(16) + '0000000').slice(2, 8);
};
const projects = listEmployees.reduce(function(result, item) {
item.employeeProjects.forEach(function(prj){
const prjId = prj.project.id;
if (!result[prjId]) {
result[prjId] = {
label: prj.project.name,
data: [],
backgroundColor: randomColorGenerator()
};
}
});
return result;
}, {});
listEmployees.forEach(function(item) {
for (const prjId of Object.keys(projects)) {
const prj = projects[prjId];
const empPrj = item.employeeProjects.filter(el => el.project.id === parseFloat(prjId));
if (empPrj.length) {
prj.data.push(empPrj[0].employeeBookedMonths);
} else {
prj.data.push(0);
}
}
});
const ctx = document.getElementById("myChart");
const myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: Object.values(projects)
},
options: {
scales: {
x: {
stacked: true
},
y: {
stacked: true
}
}
}
});
.myChartDiv {
max-width: 600px;
max-height: 400px;
backgroundColor: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script>
<html>
<body>
<div class="myChartDiv">
<canvas id="myChart" width="600" height="400"></canvas>
</div>
</body>
</html>

Display API data in line charts dynamically

I was having trouble getting parseInt(res.data[0]['97'].value to render accurate data from my API call. [0] being the index, and ['97'] being the ID from my API Response. I've updated my code to accept props of {jobId} from my App.js sending the ID to LineChart.js. This allows me to access this ID when it is in a Cycle along with the Title, so that I can say "whatever Title is displaying, get the ID and in LineCharts, match that ID to the data needed for the Line chart."
Old LineChart.js
import React, { useState, useEffect } from "react";
import { Scatter } from "react-chartjs-2";
const TotalLineChart = () => {
const [chartData, setChartData] = useState({});
// const [designHours, setDesignHours] = useState([]);
// const [designAmount, setDesignAmount] = useState([]);
// const [subRoughHours, setSubRoughHours] = useState([]);
// const [subRoughAmount, setSubRoughAmount] = useState([]);
// const [roughHours, setRoughHours] = useState([]);
// const [roughAmount, setRoughAmount] = useState([]);
// const [finishHours, setFinishHours] = useState([]);
// const [finishAmount, setFinishAmount] = useState([]);
// const [closeHours, setCloseHours] = useState([]);
// const [closeAmount, setCloseAmount] = useState([]);
// const [actualHours, setActualHours] = useState([]);
// const [actualAmount, setActualAmount] = useState([]);
const chart = () => {
let designHours = [];
let designAmount = [];
let subRoughHours = [];
let subRoughAmount = [];
let roughHours = [];
let roughAmount = [];
let finishHours = [];
let finishAmount = [];
let closeHours = [];
let closeAmount = [];
let actualHours = [];
let actualAmount = [];
let headers = {
'QB-Realm-Hostname': 'XXXXXXXXXX.quickbase.com',
'User-Agent': 'FileService_Integration_V2.1',
'Authorization': 'QB-USER-TOKEN XXXX_XXX_XXXXXXXXXX',
'Content-Type': 'application/json'
};
let body = {"from":"bpz99ram7","select":[3,6,80,81,82,83,86,84,88,89,90,91,92,93,94,95,96,97,98,99,101,103,104,105,106,107,109,111,113,115,120,123,224,225,226,227,228,229,230,231,477,479,480,481],"where": "{40.CT. 'In Progress'}","sortBy":[{"fieldId":6,"order":"ASC"}],"groupBy":[{"fieldId":40,"grouping":"equal-values"}],"options":{"skip":0,"top":0,"compareWithAppLocalTime":false}}
fetch('https://api.quickbase.com/v1/records/query', {
method: 'POST',
headers: headers,
body: JSON.stringify(body)
}).then(response => response.json())
.then(res => {
console.log(res);
const designHours = parseInt(res.data[0]['89'].value, 10);
const designAmount = parseInt(res.data[0]['91'].value, 10);
const subRoughHours = parseInt(res.data[0]['93'].value, 10);
const subRoughAmount = parseInt(res.data[0]['95'].value, 10);
const roughHours = parseInt(res.data[0]['97'].value, 10);
const roughAmount = parseInt(res.data[0]['99'].value, 10);
const finishHours = parseInt(res.data[0]['105'].value, 10);
const finishAmount = parseInt(res.data[0]['107'].value, 10);
const closeHours = parseInt(res.data[0]['477'].value, 10);
const closeAmount = parseInt(res.data[0]['480'].value, 10);
const actualHours = parseInt(res.data[0]['479'].value, 10);
const actualAmount = parseInt(res.data[0]['224'].value, 10);
}
setChartData({
type: 'scatter',
data: {
datasets: [
{
data: [
{x: designHours, y: designAmount },
{x: subRoughHours, y: subRoughAmount },
{x: roughHours, y: roughAmount },
{x: finishHours, y: finishAmount },
{x: closeHours, y: closeAmount }
],
backgroundColor: ["rgba(75, 192, 192, 0.6)"],
borderWidth: 4
}
]
}
});
})
.catch(err => {
console.log(err);
});
console.log(designHours, designAmount, subRoughHours, subRoughAmount, finishHours, finishAmount, closeHours, closeAmount, actualHours, actualAmount);
};
useEffect(() => {
chart();
}, []);
return (
<div className="App">
<div>
<Scatter
data={chartData}
options={{
responsive: true,
title: { text: "", display: true },
scales: {
yAxes: [
{
ticks: {
autoSkip: true,
maxTicksLimit: 20,
beginAtZero: true
},
gridLines: {
display: true
}
}
],
xAxes: [
{
gridLines: {
display: true
}
}
]
}
}}
/>
</div>
</div>
);
};
export default TotalLineChart;
Fixed/Updated LineChart.js
import React, { useState, useEffect } from "react";
import { Scatter } from "react-chartjs-2";
// import jobId from '../TitleCycle';
// import Title from '../header/Title';
const TotalLineChart = (props) => {
const {jobId} = props;
console.log(jobId)
const [chartData, setChartData] = useState({});
const chart = () => {
let designHours = [];
let designAmount = [];
let subRoughHours = [];
let subRoughAmount = [];
let roughHours = [];
let roughAmount = [];
let finishHours = [];
let finishAmount = [];
let closeHours = [];
let closeAmount = [];
let actualHours = [];
let actualAmount = [];
let headers = {
"QB-Realm-Hostname": "XXXXXXXXX.quickbase.com",
"User-Agent": "FileService_Integration_V2.1",
"Authorization": "QB-USER-TOKEN XXXXXXXXXXXX",
"Content-Type": "application/json"
};
const body = {
from: "bpz99ram7",
select: [
3,
6,
80,
81,
82,
83,
86,
84,
88,
89,
90,
91,
92,
93,
94,
95,
96,
97,
98,
99,
101,
103,
104,
105,
106,
107,
109,
111,
113,
115,
120,
123,
224,
225,
226,
227,
228,
229,
230,
231,
477,
479,
480,
481
],
where: `{3.EX. ${jobId}}`,
sortBy: [{ fieldId: 6, order: "ASC" }],
groupBy: [{ fieldId: 40, grouping: "equal-values" }],
options: { skip: 0, compareWithAppLocalTime: false }
};
fetch("https://api.quickbase.com/v1/records/query", {
method: "POST",
headers: headers,
body: JSON.stringify(body)
})
.then((response) => response.json())
.then((res) => {
// console.log(res);
Object.keys(res.data).map(jobId => {
const designHours = parseInt(res.data[jobId]['88'].value, 10);
const designAmount = parseInt(res.data[jobId]['91'].value, 10);
const subRoughHours = parseInt(res.data[jobId]['92'].value, 10);
const subRoughAmount = parseInt(res.data[jobId]['95'].value, 10);
const roughHours = parseInt(res.data[jobId]['96'].value, 10);
const roughAmount = parseInt(res.data[jobId]['98'].value, 10);
const finishHours = parseInt(res.data[jobId]['104'].value, 10);
const finishAmount = parseInt(res.data[jobId]['107'].value, 10);
const closeHours = parseInt(res.data[jobId]['477'].value, 10);
const closeAmount = parseInt(res.data[jobId]['480'].value, 10);
const actualHours = parseInt(res.data[jobId]['479'].value, 10);
const actualAmount = parseInt(res.data[jobId]['224'].value, 10);
setChartData({
type: 'scatter',
datasets: [
{
label: 'TOTAL',
data: [
{ x: designHours, y: designAmount },
{ x: subRoughHours, y: subRoughAmount },
{ x: roughHours, y: roughAmount },
{ x: finishHours, y: finishAmount },
{ x: closeHours, y: closeAmount }
],
borderWidth: 2,
borderColor: '#4183c4',
backgroundColor: '#4183c4',
tension: 0.8,
spanGaps: true,
lineTension: 0.5,
showLine: true,
fill: false,
showTooltip: false,
pointBorderWidth: 1
},
{
label: 'ACTUALS',
data: [{ x: actualHours, y: actualAmount }],
fill: false,
borderColor: '#e34747',
backgroundColor: '#e34747',
borderWidth: 3,
showTooltip: false
}
],
options: {
showAllTooltips: true,
enabled: true,
maintainAspectRatio: false,
legend: {
display: true
}
}
})
setChartData.addData(chart, label, data); {
chart.data.labels.push(label);
chart.data.datasets.forEach((dataset) => {
dataset.data.push(data);
});
chart.update();
}
setChartData.removeData(chart); {
chart.data.labels.pop();
chart.data.datasets.forEach((dataset) => {
dataset.data.pop();
});
chart.update();
}
})
})
.catch((err) => {
console.log(err);
});
console.log(
designHours,
designAmount,
subRoughHours,
subRoughAmount,
roughHours,
roughAmount,
finishHours,
finishAmount,
closeHours,
closeAmount,
actualHours,
actualAmount
);
};
useEffect(() => {
chart();
}, []);
return (
<div className="App">
<div>
<Scatter
data={chartData}
options={{
responsive: true,
title: { text: "Total Project", display: true },
scales: {
yAxes: [
{
scaleLabel: {
display: true,
labelString: 'Amount'
},
ticks: {
autoSkip: true,
maxTicksLimit: 10,
beginAtZero: true
},
gridLines: {
display: true
}
}
],
xAxes: [
{
scaleLabel: {
display: true,
labelString: 'Hours'
},
gridLines: {
display: true
}
}
],
},
}}
/>
</div>
</div>
);
};
export default TotalLineChart;
NOTE how I've added ${jobId} to the API Body, as well as replacing the manually inputted Index in the parseInt()
App.js
import React, { useEffect, useState } from "react";
import './App.css'
import Title from './components/header/Title'
import TotalLineChart from './components/charts/TotalLineChart'
import RadiantLineChart from './components/charts/RadiantLineChart'
import PlumbingLineChart from './components/charts/PlumbingLineChart'
import SnowmeltLineChart from './components/charts/SnowmeltLineChart'
import HVACLineChart from './components/charts/HVACLineChart'
import GasPipeLineChart from './components/charts/GasPipeLineChart'
import FixturesLineChart from './components/charts/FixturesLineChart'
// import TitleCycle from './components/TitleCycle'
// import Logo from './components/Logo';
let headers = {
"QB-Realm-Hostname": "XXXXXXXX.quickbase.com",
"User-Agent": "FileService_Integration_V2.1",
"Authorization": "QB-USER-TOKEN XXXXXXXX",
"Content-Type": "application/json"
};
function App() {
const [allData, setAllData] = useState([]);
const [index, setIndex] = useState(0);
// Fetch all data, all jobs
useEffect(() => {
function fetchData() {
let body = {
from: "bpz99ram7",
select: [3, 6, 40],
where: "{40.CT. 'In Progress'}",
sortBy: [{ fieldId: 6, order: "ASC" }],
groupBy: [{ fieldId: 40, grouping: "equal-values" }],
options: { skip: 0, top: 0, compareWithAppLocalTime: false },
};
fetch("https://api.quickbase.com/v1/records/query", {
method: "POST",
headers: headers,
body: JSON.stringify(body),
})
.then((response) => response.json())
.then(({ data }) => setAllData(data));
}
fetchData();
}, []);
// Cycle through the jobIds and indexes
useEffect(() => {
const timerId = setInterval(
() => setIndex((i) => (i + 1) % allData.length),
5000 // 5 seconds.
);
return () => clearInterval(timerId);
}, [allData]);
console.log(allData)
console.log(index)
// Calculate info based on index
const jobId = allData[index]?.['3']?.value || 291; // Default 291
const title = allData[index]?.['6']?.value || 'Default Title';
console.log(jobId)
return (
<div>
{/* <div className="flexbox-container">
<div className="Logo">
{/* <Logo /> */}
{/* </div> */}
<div className="App">
<Title title = {title}/>
</div>
<div className="TopChart">
<TotalLineChart jobId = {jobId}/>
</div>
<div className="FirstRowContainer">
<RadiantLineChart jobId = {jobId}/>
<PlumbingLineChart jobId = {jobId}/>
<FixturesLineChart jobId = {jobId}/>
</div>
<div className="SecondRowContainer">
<SnowmeltLineChart jobId = {jobId}/>
<HVACLineChart jobId = {jobId}/>
<GasPipeLineChart jobId = {jobId}/>
</div>
</div>
);
}
export default App;
App.js takes the field ID and cycles it along with the Title in a duration of 5 seconds each, then sends that data to LineChart.js to be used at the same time with corresponding data.
UPDATE: Able to display dynamically by using props with IDs needed, and using those in each api call to get specific data based on the Title Displaying:
App.js:
import React, { useEffect, useState } from "react";
import './App.css'
import Title from './components/header/Title'
import TotalLineChart from './components/charts/TotalLineChart'
import RadiantLineChart from './components/charts/RadiantLineChart'
import PlumbingLineChart from './components/charts/PlumbingLineChart'
import SnowmeltLineChart from './components/charts/SnowmeltLineChart'
import HVACLineChart from './components/charts/HVACLineChart'
import GasPipeLineChart from './components/charts/GasPipeLineChart'
import FixturesLineChart from './components/charts/FixturesLineChart'
// import TitleCycle from './components/TitleCycle'
// import Logo from './components/Logo';
let headers = {
"QB-Realm-Hostname": "XXXXXXXXX.quickbase.com",
"User-Agent": "FileService_Integration_V2.1",
"Authorization": "QB-USER-TOKEN XXXXXXXXX",
"Content-Type": "application/json",
"Retry-After": 120000
};
function App() {
const [allData, setAllData] = useState([]);
const [index, setIndex] = useState(0);
// Fetch all data, all jobs
useEffect(() => {
function fetchData() {
let body = {
from: "bpz99ram7",
select: [3, 6, 40],
where: "{40.CT. 'In Progress'}",
sortBy: [{ fieldId: 6, order: "ASC" }],
groupBy: [{ fieldId: 40, grouping: "equal-values" }],
options: { skip: 0, top: 0, compareWithAppLocalTime: false },
};
fetch("https://api.quickbase.com/v1/records/query", {
method: "POST",
headers: headers,
body: JSON.stringify(body),
})
.then((response) => response.json())
.then(({ data }) => setAllData(data));
}
fetchData();
}, []);
// Cycle through the jobIds and indexes
useEffect(() => {
const timerId = setInterval(
() => setIndex((i) => (i + 1) % allData.length),
5000 // 5 seconds.
);
return () => clearInterval(timerId);
}, [allData]);
// console.log(allData)
// console.log(index)
// Calculate info based on index
const jobId = allData[index]?.['3']?.value || '291'; // Default 291
const title = allData[index]?.['6']?.value || 'Default Title';
// console.log(jobId)
return (
<div>
{/* <div className="flexbox-container">
<div className="Logo">
{/* <Logo /> */}
{/* </div> */}
<div className="App">
<Title title = {title} />
</div>
<div className="TopChart">
<TotalLineChart jobId = {jobId} />
</div>
<div className="FirstRowContainer">
{/* <RadiantLineChart jobId = {jobId} /> */}
<PlumbingLineChart jobId = {jobId} />
<FixturesLineChart jobId = {jobId} />
</div>
<div className="SecondRowContainer">
<SnowmeltLineChart jobId = {jobId} />
<HVACLineChart jobId = {jobId} />
<GasPipeLineChart jobId = {jobId} />
</div>
</div>
);
}
export default App;
LineChart.js
import React, { useState, useEffect } from "react";
import { Scatter } from "react-chartjs-2";
// import jobId from '../TitleCycle';
// import Title from '../header/Title';
function TotalLineChart(props) {
const { jobId } = props;
// console.log(`${jobId}`)
const [chartData, setChartData] = useState({});
const chart = () => {
let designHours = [];
let designAmount = [];
let subRoughHours = [];
let subRoughAmount = [];
let roughHours = [];
let roughAmount = [];
let finishHours = [];
let finishAmount = [];
let closeHours = [];
let closeAmount = [];
let actualHours = [];
let actualAmount = [];
let headers = {
"QB-Realm-Hostname": "XXXXXXXX.quickbase.com",
"User-Agent": "FileService_Integration_V2.1",
"Authorization": "QB-USER-TOKEN XXXXXXXX",
"Content-Type": "application/json",
"x-ratelimit-reset": 10000,
"Retry-After": 30000
};
// useEffect(() => {
// function fetchData() {
const body = {
from: "bpz99ram7",
select: [
3,
88,
91,
92,
95,
96,
98,
104,
107,
224,
477,
479,
480,
],
where: `{3.EX. ${ jobId }}`,
sortBy: [{ fieldId: 6, order: "ASC" }],
groupBy: [{ fieldId: 40, grouping: "equal-values" }],
options: { skip: 0, compareWithAppLocalTime: false }
};
fetch("https://api.quickbase.com/v1/records/query", {
method: "POST",
headers: headers,
body: JSON.stringify(body)
})
// }
// fetchData();
// }, [])
.then((response) => response.json())
.then((res) => {
// console.log(res);
Object.keys(res.data).map(jobId => {
designHours = parseInt(res.data[jobId]['88'].value, 10);
designAmount = parseInt(res.data[jobId]['91'].value, 10);
subRoughHours = parseInt(res.data[jobId]['92'].value, 10);
subRoughAmount = parseInt(res.data[jobId]['95'].value, 10);
roughHours = parseInt(res.data[jobId]['96'].value, 10);
roughAmount = parseInt(res.data[jobId]['98'].value, 10);
finishHours = parseInt(res.data[jobId]['104'].value, 10);
finishAmount = parseInt(res.data[jobId]['107'].value, 10);
closeHours = parseInt(res.data[jobId]['477'].value, 10);
closeAmount = parseInt(res.data[jobId]['480'].value, 10);
actualHours = parseInt(res.data[jobId]['479'].value, 10);
actualAmount = parseInt(res.data[jobId]['224'].value, 10);
setChartData({
type: 'scatter',
redraw: true,
datasets: [
{
label: 'TOTAL',
data: [
{ x: designHours, y: designAmount },
{ x: subRoughHours, y: subRoughAmount },
{ x: roughHours, y: roughAmount },
{ x: finishHours, y: finishAmount },
{ x: closeHours, y: closeAmount }
],
borderWidth: 2,
borderColor: '#4183c4',
backgroundColor: '#4183c4',
tension: 0.8,
spanGaps: true,
lineTension: 0.5,
showLine: true,
fill: false,
showTooltip: false,
pointBorderWidth: 1
},
{
label: 'ACTUALS',
data: [{ x: actualHours, y: actualAmount }],
fill: false,
borderColor: '#e34747',
backgroundColor: '#e34747',
borderWidth: 3,
showTooltip: false
}
],
options: {
showAllTooltips: true,
enabled: true,
maintainAspectRatio: false,
legend: {
display: true
}
}
})
})
})
.catch((err) => {
console.log(err);
});
};
useEffect(() => {
chart();
}, []);
return (
<div className="App">
<div>
<Scatter
// ref={(reference) => this.chartReference = reference }
data={chartData}
options={{
title: { text: "Total Project", display: false },
scales: {
yAxes: [
{
scaleLabel: {
display: true,
labelString: '$ AMOUNT'
},
ticks: {
autoSkip: true,
maxTicksLimit: 10,
beginAtZero: true
},
gridLines: {
display: true
}
}
],
xAxes: [
{
scaleLabel: {
display: true,
labelString: 'HOURS'
},
gridLines: {
display: true
}
}
],
},
}}
/>
</div>
</div>
);
};
export default TotalLineChart;
You are specifying all kind of weird radixes for your parseInt method, I assume all of your values are just base 10, even if not with a quick test the radix argument only goes up till 36, so if you remove that it should work.
Also you are pushing the same value to a lot of different arrays, seems like you need to specify the value in the dataObject you want to push and not just value, otherwise 1 array would be enough.

Adding color dynamically to Chart.js

I have a Chart.js project, best explained by this code below.
const response = [
{
"mmyy":"2019-12",
"promocode":"promo1",
"amount":"2776"
},
{
"mmyy":"2020-01",
"promocode":"promo1",
"amount":"1245"
},
{
"mmyy":"2020-01",
"promocode":"promo2",
"amount":"179"
}
];
var chartColors = window.chartColors;
var color = Chart.helpers.color;
var colors = [color(chartColors.red).alpha(0.5).rgbString(),
color(chartColors.orange).alpha(0.5).rgbString(),
color(chartColors.yellow).alpha(0.5).rgbString(),
color(chartColors.green).alpha(0.5).rgbString(),
color(chartColors.blue).alpha(0.5).rgbString()];
var bgColors = [];
const labels = Array.from(new Set(response.map(c => c.mmyy))).sort();
const promocodes = Array.from(new Set(response.map(c => c.promocode))).sort();
const datasets = promocodes.map(pc => ({ label: pc, data: [] }));
labels.forEach(l => {
for (let pc of promocodes) {
let city = response.find(c => c.mmyy == l && c.promocode == pc);
datasets.find(ds => ds.label == pc).data.push(city ? Number(city.amount) : 0);
}
});
var ctx = document.getElementById('promorChart').getContext('2d');
var chartColors = window.chartColors;
var color = Chart.helpers.color;
var promorChart = new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: datasets
},
options: {
scales: {
xAxes: [{
stacked: false
}],
yAxes: [{
stacked: false,
ticks: {
// Include a dollar sign in the ticks
callback: function(value, index, values) {
return '$' + value;
}
}
}]
},
tooltips: {
callbacks: {
label: function(tooltipItems, data) {
return "$" + tooltipItems.yLabel.toString();
}
}
},
responsive: true,
elements: {
}
}
});
<canvas id="promorChart"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<script src="https://www.chartjs.org/samples/latest/utils.js"></script>
It works great, but as you can see, it needs some color, so I am trying to add some color with this code:
const labels = Array.from(new Set(response.map(c => c.mmyy))).sort();
const promocodes = Array.from(new Set(response.map(c => c.promocode))).sort();
const datasets = promocodes.map(pc => ({ label: pc, data: [], backgroundColor: bgColors }));
labels.forEach(l => {
for (var i = 0; i < labels.count.length; i++) {
let bgColors = (colors[i % colors.length]);
};
for (let pc of promocodes) {
let city = response.find(c => c.mmyy == l && c.promocode == pc);
datasets.find(ds => ds.label == pc).data.push(city ? Number(city.amount) : 0);
}
});
But that's not working. I'm getting the error TypeError: undefined is not an object (evaluating 'labels.count.length') Could someone tell me how to add a color for each of the labels properly form the color array properly? Thanks.
In the following code snippet, I work with simple color definitions for illustrating how it can be done. Simply replace the colors array with your own colors and it should work as expected.
const response = [{
"mmyy": "2019-12",
"promocode": "promo1",
"amount": "2776"
},
{
"mmyy": "2020-01",
"promocode": "promo1",
"amount": "1245"
},
{
"mmyy": "2020-01",
"promocode": "promo2",
"amount": "179"
}
];
const colors = ['red', 'orange', 'yellow', 'green', 'blue'];
const labels = Array.from(new Set(response.map(c => c.mmyy))).sort();
const promocodes = Array.from(new Set(response.map(c => c.promocode))).sort();
let i = 0;
const datasets = promocodes.map(pc => ({
label: pc,
data: [],
backgroundColor: colors[i++]
}));
labels.forEach(l => {
for (let pc of promocodes) {
let city = response.find(c => c.mmyy == l && c.promocode == pc);
datasets.find(ds => ds.label == pc).data.push(city ? Number(city.amount) : 0);
}
});
var ctx = document.getElementById('promorChart').getContext('2d');
var chartColors = window.chartColors;
var color = Chart.helpers.color;
var promorChart = new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: datasets
},
options: {
scales: {
xAxes: [{
stacked: false
}],
yAxes: [{
stacked: false,
ticks: {
callback: (value, index, values) => '$' + value
}
}]
},
tooltips: {
callbacks: {
label: (tooltipItems, data) => "$" + tooltipItems.yLabel.toString()
}
},
responsive: true,
elements: {}
}
});
<canvas id="promorChart"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
I just modified the code. You have to set up the backgroundcolor for custom bar colors.
//added for colors
function colorsFunction() {
return ['#3e95cd','#8e5ea2'];
}
const labels = Array.from(new Set(response.map(c => c.mmyy))).sort();
const promocodes = Array.from(new Set(response.map(c => c.promocode))).sort();
const datasets = promocodes.map(pc => ({ label: pc, data: [],backgroundColor: colorsFunction() })); //Modified here
add this property inside our datasets => backgroundColor: ['#3a95cd','#4e5ea2']
const response = [{
"mmyy": "2019-12",
"promocode": "promo1",
"amount": "2776"
},
{
"mmyy": "2020-01",
"promocode": "promo1",
"amount": "1245"
},
{
"mmyy": "2020-01",
"promocode": "promo2",
"amount": "179"
}
];
const labels = Array.from(new Set(response.map(c => c.mmyy))).sort();
const promocodes = Array.from(new Set(response.map(c => c.promocode))).sort();
const datasets = promocodes.map(pc => ({
label: pc,
data: [],
backgroundColor: ['#3a95cd','#4e5ea2'] // ['#3a95cd','#4e5ea2']
}));
labels.forEach(l => {
for (let pc of promocodes) {
let city = response.find(c => c.mmyy == l && c.promocode == pc);
datasets.find(ds => ds.label == pc).data.push(city ? Number(city.amount) : 0);
}
});
var ctx = document.getElementById('promorChart').getContext('2d');
var chartColors = window.chartColors;
var color = Chart.helpers.color;
var promorChart = new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: datasets
},
options: {
plugins: {
colorschemes: {
scheme: 'brewer.DarkTwo3'
}
},
scales: {
xAxes: [{
stacked: false
}],
yAxes: [{
stacked: false,
ticks: {
callback: function(value, index, values) {
return '$' + value;
}
}
}]
},
tooltips: {
callbacks: {
label: function(tooltipItems, data) {
return "$" + tooltipItems.yLabel.toString();
}
}
},
responsive: true,
elements: {}
}
});
<canvas id="promorChart"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-colorschemes"></script>

Control Scaling of Canvas When dragged out of chart limit

When I dragged the datapoint out of chart's ticks limit like from max x and y axis value, the canvas increase the limits too fast. How can I control this scaling speed? So that it increase with specific number defined in the config of chart.
Here is the js fiddle link.
https://jsfiddle.net/rz7pw6j0/67/
JS
(function () {
let chartInstance;
let chartElement;
function createChart(chartElement) {
const chartConfig = {
type: 'scatter',
data: {
datasets: [
{
data: [
{
x: 0,
y:0
}
],
fill: true,
showLine: true,
lineTension: 0
}
]
},
options: {
legend: {
display: false,
},
layout: {
padding: {
left: 50,
right: 50,
top: 0,
bottom: 0
}
},
title: {
display: false,
text: 'Chart.js Interactive Points',
},
scales: {
xAxes: [
{
type: 'linear',
display: true,
padding: 20,
paddingLeft: 10,
paddingRight: 10,
paddingTop: 10,
paddingBottom: 10,
scaleLabel: {
display: true,
labelString: 'Time',
},
ticks: {
suggestedMin: -5,
suggestedMax: 5,
stepValue: 1,
}
}
],
yAxes: [
{
type: 'linear',
display: true,
scaleLabel: {
display: true,
labelString: 'Weight'
},
paddingLeft: 10,
paddingRight: 10,
paddingTop: 10,
paddingBottom: 10,
ticks: {
suggestedMin: 0,
suggestedMax: 3,
stepValue: 1
},
}
]
},
responsive: true,
maintainAspectRatio: true,
tooltips: {
intersect: true,
}
}
};
chartInstance = new Chart(chartElement.getContext('2d'), chartConfig);
let element = null;
let scaleY = null;
let scaleX = null;
let datasetIndex = null;
let index = null;
let valueY = null;
let valueX = null;
function onGetElement() {
const event = d3.event.sourceEvent;
element = chartInstance.getElementAtEvent(event)[0];
if (!element) {
chartClickHandler(event);
return;
}
if (event.shiftKey) {
const tempDatasetIndex = element['_datasetIndex'];
const tempIndex = element['_index'];
chartInstance.data.datasets[tempDatasetIndex].data = chartInstance
.data.datasets[tempDatasetIndex].data.filter((v, i) => i !== tempIndex);
chartInstance.update();
return;
}
scaleY = element['_yScale'].id;
scaleX = element['_xScale'].id;
}
function onDragStart() {
const event = d3.event.sourceEvent;
datasetIndex = element['_datasetIndex'];
index = element['_index'];
valueY = chartInstance.scales[scaleY].getValueForPixel(event.offsetY);
valueX = chartInstance.scales[scaleX].getValueForPixel(event.offsetX);
chartInstance.data.datasets[datasetIndex].data[index] = {
x: valueX,
y: valueY
};
chartInstance.update(0);
}
function onDragEnd() {
if (
chartInstance.data.datasets[datasetIndex] &&
chartInstance.data.datasets[datasetIndex].data) {
chartInstance.data.datasets[datasetIndex].data.sort((a, b) => a.x - b.x > 0 ? 1 : -1);
chartInstance.update(0);
}
element = null;
scaleY = null;
scaleX = null;
datasetIndex = null;
index = null;
valueY = null;
valueX = null;
}
d3.select(chartInstance.chart.canvas).call(
d3.drag().container(chartInstance.chart.canvas)
.on('start', onGetElement)
.on('drag', onDragStart)
.on('end', onDragEnd)
);
}
function chartClickHandler (event) {
let scaleRef;
let valueX = 0;
let valueY = 0;
Object.keys(chartInstance.scales).forEach((scaleKey) => {
scaleRef = chartInstance.scales[scaleKey];
if (scaleRef.isHorizontal() && scaleKey === 'x-axis-1') {
valueX = scaleRef.getValueForPixel(event.offsetX);
} else if (scaleKey === 'y-axis-1') {
valueY = scaleRef.getValueForPixel(event.offsetY);
}
});
const newPoint = {
x: valueX,
y: valueY
};
const dataSeries = chartInstance.data.datasets[0].data;
for (let i = 0; i < dataSeries.length; i++) {
if (dataSeries[i].x === newPoint.x) {
dataSeries.y = newPoint.y;
chartInstance.update();
return;
}
}
let inserted = false;
for (let j = dataSeries.length - 1; j >= 0; j--) {
if (dataSeries[j].x > newPoint.x) {
dataSeries[j + 1] = dataSeries[j];
} else {
dataSeries[j + 1] = newPoint;
inserted = true;
break;
}
}
if (!inserted) {
dataSeries.push(newPoint);
}
chartInstance.update();
}
chartElement = document.getElementById("chart");
createChart(chartElement);
})();
HTML
<body>
<div>Chart Drag and Click Test</div>
<div class="wrapper">
<canvas id="chart"></canvas>
</div>
</body>
CSS
.wrapper {
display: "block";
}
I want to control the scaling speed.
If a dragStart event occurs beyond the scale limits, the increment should be a fixed value to avoid the issue you mentioned. Also, ticks.min and ticks.max should be set for the same purpose. Below is a sample jsfiddle and code (you can control speed by step).
https://jsfiddle.net/oLrk3fb2/
function onDragStart() {
const event = d3.event.sourceEvent;
const scales = chartInstance.scales;
const scaleInstanceY = scales[scaleY];
const scaleInstanceX = scales[scaleX];
const scalesOpts = chartInstance.options.scales;
const ticksOptsX = scalesOpts.xAxes[0].ticks;
const ticksOptsY = scalesOpts.yAxes[0].ticks;
const step = 1;
datasetIndex = element['_datasetIndex'];
index = element['_index'];
valueY = scaleInstanceY.getValueForPixel(event.offsetY);
valueX = scaleInstanceX.getValueForPixel(event.offsetX);
if (valueY < scaleInstanceY.min) {
ticksOptsY.min = valueY = scaleInstanceY.min - step;
}
if (valueY > scaleInstanceY.max) {
ticksOptsY.max = valueY = scaleInstanceY.max + step;
}
if (valueX < scaleInstanceX.min) {
ticksOptsX.min = valueX = scaleInstanceX.min - step;
}
if (valueX > scaleInstanceX.max) {
ticksOptsX.max = valueX = scaleInstanceX.max + step;
}
chartInstance.data.datasets[datasetIndex].data[index] = {
x: valueX,
y: valueY
}
chartInstance.update(0);
}

Visualising my mapped object with Charts.js

I have a map object: As you can see it is nesting by year-month-day.
I would like to create a bar chart where you can see those numbers for "Keszeg", "Ponty"..etc based on the year-month-day.
My code is ready but i can't get it working. At this part i am getting undefinied error for the yearVal.entries.
This is the sulyhavonta.entries:
for (let [yearKey, yearVal] of sulyhavonta.entries()) {
for (let [monthKey, monthVal] of yearVal.entries())
let labels = [];
let datasets = [];
let fishData = {};
this.firebasedb.list("/fogasok/").subscribe(_data => {
// this.osszesfogasadatok = _data.filter(item => item.publikus == true);
// let fogasSzam=this.osszesfogasadatok.length;
let sulySum = _data.reduce((sum, item) => sum + parseInt(item.suly), 0);
let sulySumMap = _data.map((item, index) => {
var n = new Date(item.datum);
return {
ev: n.getFullYear(),
honap: n.getMonth() + 1,
nap: n.getDate(),
suly: item.suly,
halfaj: item.halfaj,
eteto: item.etetoanyag1,
csali: item.hasznaltcsali,
helyszin: item.helyszin
}
});
var sulySumByDate = d3.nest()
.key(function (d) {
return d.ev;
})
.key(function (d) {
return d.honap;
})
.key(function (d) {
return d.nap;
})
.key(function (d) {
return d.halfaj;
})
.rollup(function (values) {
return d3.sum(values, function (d) {
return parseInt(d.suly);
});
})
.map(sulySumMap)
var sulyhavonta=sulySumByDate;
console.log("sulyhavonta",sulyhavonta)
for (let [yearKey, yearVal] of sulyhavonta.entries()) {
for (let [monthKey, monthVal] of yearVal.entries()) {
for (let [dayKey, dayVal] of monthVal.entires()) {
labels.push(yearKey + '.' + monthKey + '.' + dayKey);
for (let [fish, fishVal] of dayVal.entires()) {
if (fishData[fish] === undefined) {
fishData[fish] = [];
}
fishData[fish].push(fishVal);
console.log("fishdata",fishData);
}
}
}
}
var colors = [
["#ce8d00", "#ffae00"],
["#007bce", "#84ceff"]
];
var i = 0;
for (let key in fishData) {
datasets.push({
label: key,
data: fishData[key],
backgroundColor: colors[i % 2][0],
hoverBackgroundColor: colors[i % 2][1],
hoverBorderWidth: 0
});
i++;
}
console.log("dataset",datasets)
});
var bar_ctx = document.getElementById('bar-chart');
var bar_chart = new Chart(bar_ctx, {
type: 'bar',
data: {
labels: labels,
datasets: datasets
},
options: {
animation: {
duration: 10,
},
scales: {
xAxes: [{
stacked: true,
gridLines: {
display: false
},
}],
yAxes: [{
stacked: true
}],
}, // scales
legend: {
display: true
}
} // options
});
Just a quick note, instead of the reading from firebase and d3 nesting, it is working with static data, but i would like to use the code above to directly read from my database.
var sulyhavonta = new Map([ [2018, new Map([ [1,new Map([[15, new
Map([['keszeg',3],['ponty',5]])], [29, new
Map([['keszeg',1],['ponty',1]])]])], [5,new Map([[24, new
Map([['keszeg',9],['ponty',7]])]])] ] )] ]);

Categories

Resources