How to push Firestore data to ChartJS? - javascript

I'm having a problem with plotting data to ChartJS from Firestore data. For some reason it only shows a single value on the bottom of the graph and random number on y-axis instead of date. I hope someone can help me.
My firestore : firestore
My chart : chart
Here's what I have so far.
db.collection('Items').get().then((snapshot) => {
snapshot.docs.forEach(doc => {
var item= doc.data();
var price= item.price;
var date = item.date;
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: [date],
datasets: [{
label: 'Items',
data: [price],
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
},
// Container for pan options
pan: {
// Boolean to enable panning
enabled: true,
// Panning directions.
mode: 'x',
speed: 1
},
// Container for zoom options
zoom: {
// enable zooming
enabled: true,
// Zooming directions.
mode: 'x',
}
}
});
})
})

For each doc in the snapshot you are doing var myChart = new Chart(), creating a new chart each time.
You should build your data and labels arrays in the forEach and then (outside the forEach) create a new chart and pass it the arrays.
Something like the following (not tested):
var labelsArray = [];
var dataArray = [];
db.collection('Items').get().then((snapshot) => {
snapshot.docs.forEach(doc => {
var item = doc.data();
var price = item.price;
dataArray.push(price);
var date = item.date;
labelsArray.push(date);
});
});
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: labelsArray,
datasets: [{
label: 'Items',
data: dataArray ,
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
},
// Container for pan options
pan: {
// Boolean to enable panning
enabled: true,
// Panning directions.
mode: 'x',
speed: 1
},
// Container for zoom options
zoom: {
// enable zooming
enabled: true,
// Zooming directions.
mode: 'x',
}
}
});

Related

chart.js add clickable link to horizontal bar stacks

Hi there I am stuck in chat.js horizontal bar graph. Here is the JS script that is populating a horizontal bar chart perfectly. Now what I want is to add link on these horizontal bar stacks. Whenever I click a particular bar stack the user should be directed to that link.
var ctx = document.getElementById('qr_tagging_data');
ctx.height = 160;
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Total Tagged','Center Zone','North Zone','South Zone'],
datasets: [{
data: ['21500','5000','10000','6500'],
backgroundColor: [
'#53B63C', '#E8A412', '#128BE8', '#648fbb'
],
hoverOffset: 3
}]
},
plugins: [ChartDataLabels],
options: {
indexAxis: 'y',
responsive: true,
plugins: {
legend: {
display: false
},
datalabels: {
font: {
weight: 'bold',
size: '15'
}
}
}
},
});
function clickHandlerZones(evt) {
const points = myChart.getElementsAtEventForMode(evt, 'nearest', { intersect: true }, true);
if (points.length) {
alert(points.length);
const firstPoint = points[0];
const label = myChart.data.labels[firstPoint.index];
const value = myChart.data.datasets[firstPoint.datasetIndex].data[firstPoint.index];
window.open('google.com','_blank');
}
}
ctx.onclick = clickHandlerZones;
I have populated another chart.js graph but it is vertical bar graph and the bars are perfectly redirected whenever a user clicks on the vertical bar graph. I am pasting the code of vertical bar graph too for reference and suggestions.
var ctx = document.getElementById('hospital_data');
ctx.height = 300;
var myChart = new Chart(ctx, {
type: 'bar',
data: {
datasets: [{
data: <?php echo $hospitals_data?>,
backgroundColor: [<?php echo $legend_colors?>],
hoverOffset: 3
}]
},
plugins: [ChartDataLabels],
options: {
parsing:{
xAxisKey: 'hospital_name',
yAxisKey: 'tagging_count'
},
responsive: true,
plugins: {
legend: {
display: false
},
datalabels: {
formatter: function (value) {
return value['tagging_count'];
},
anchor: 'end',
align: 'top',
font: {
weight: 'bold',
size: '11'
}
}
}
}
});
function clickHandler(evt) {
const points = myChart.getElementsAtEventForMode(evt, 'nearest', { intersect: true }, true);
if (points.length) {
const firstPoint = points[0];
const label = myChart.data.labels[firstPoint.index];
const value = myChart.data.datasets[firstPoint.datasetIndex].data[firstPoint.index];
window.open('google.com','_blank');
}
}
ctx.onclick = clickHandler;
can someone guide how do I fix this horizontal bar stacks clickable functionality. The links are applied on the numbers i.e. (5000,10000,15000,20000,25000 on x-axis) rather they should be applied to each horizontal stack.

Chart.JS: How to make sharp lines to smooth curved lines

Hi I'm new at charts and this is my chartjs chart, it's working currently, but it's showing in sharp lines and I want to make it smooth curve lines on this chart. Any ideas?
function statistics(data) {
if ($('#stats-currency').length > 0) {
if (typeof(stats_currency) !== 'undefined') {
stats_currency.destroy();
}
if (typeof(data) == 'undefined') {
var currency = $('select[name="currency"]').val();
$.get(admin_url + 'home/stats_currency/' + currency, function(response) {
stats_currency = new Chart($('#stats-currency'), {
type: 'line',
data: response,
options: {
responsive:true,
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
}
}]
},
},
});
}, 'json');
} else {
stats_currency = new Chart($('#stats-currency'), {
type: 'line',
data: data,
options: {
responsive: true,
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
}
}]
},
},
});
}
This can be done through the option lineTension that needs to be defined on your dataset. Choose a value below 1.
datasets: [{
...
lineTension: 0.8
}]
By default, you should however already see curved smooth lines since accoring to Chart.js documentation, the default value is 0.4.
lineTension: Bezier curve tension of the line. Set to 0 to draw straight lines.
Please note that if the steppedLine value is set to anything other than false, lineTension will be ignored.
you can do it by adding tension value to your charts options
<canvas id="myChart"></canvas>
JS
const config = {
type: 'line', // your chart type
data: data, // pass here your data
options: {
elements: {
line: {
tension : 0.4 // smooth lines
},
},
},
};
// pass it like
const myChart = new Chart(
document.getElementById('myChart'),
config
);

What kind of graph could I use to achieve this with ChartJS (or similar)?

I'm trying to make a deciBel-frequency chart like this in javascript:
[X axis is frequency domain (red, blue and yellow are 4G bands), Y axis is power in dB]
However, the classic bar chart that I find in every library cannot fix the bottom of the bars below 0. I'm trying to find another kind of chart that I could use to achieve this. Orange color is the noise floor power.
Thank you in advance.
No way to create "range" only by one value.
For example, the data for the red bar in your example is not only 20 -or- -180 but -180 to 20 = nested array (Multidimensional Array)
data = [[-180,20]];
snippet:
labels1 = ["a","b","c","d"];
data = [[20,-180],[40,-160],[20,-120]];
var data = {
labels: labels1,
datasets: [
{
label: "hello",
data: data,
backgroundColor: ["yellow", "blue", "orange"],
borderWidth: 5
}
]
}
var options = {
responsive: true,
scales: {
xAxes: [{
stacked: false,
}],
yAxes: [{
stacked: false,
ticks: {
gridLines: {
drawOnChartArea: true
},
max: 100,
min: -180,
}
}]
},
title: {
display: true,
text: name
},
tooltips: {
mode: 'index',
intersect: false,
},
};
/*for(let i = 0; i<10; i++)
{
let labels2 = [];
let datos2 = [];
labels2.push(i);
datos2.push(-120);
}*/
var ctx = document.getElementById("myChart");
var chartInstance = new Chart(ctx, {
type: 'bar',
data: data,
options:options
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<h2>
Hello World!
</h2>
<canvas id='myChart'/>

Chart.js how define max tick of polarArea?

I look for way to use polarArea but with limit scale (line of tick) defined at 100. Actualy the scale display scale based in max value, but I want max fixed.
var data = {
datasets: [{
data: [10,20,30,40],
}],
labels: ["Red","Green","Yellow","Grey","Blue"]
};
var polarArea = new Chart(ctx, {
data: data,
type: 'polarArea',
options: {
scale: {
ticks: {
beginAtZero: true
}
}
}
});
This marked with arrow green as I want the graph.
Can you help me?
var data = {
datasets: [{
data: [10,20,30,40],
}],
labels: ["Red","Green","Yellow","Grey"]
};
var polarArea = new Chart(ctx, {
data: data,
type: 'polarArea',
options: {
scale: {
ticks: {
min: 0,
max: 100
}
}
}
});
A JSFiddle would be super helpful for your exact situation, but based on the information provided, this should do it for you. http://jsfiddle.net/andrewborem/vup9o5fx/

Hide Y-axis labels when data is not displayed in Chart.js

I have a Chart.js bar graph displaying two sets of data: Total SQL Queries and Slow SQL Queries. I have Y-axis labels for each respective set of data. The graph can be seen below:
When I toggle one of the sets of data to not display, the corresponding Y-axis labels still display. When interpreting the graph, this is a bit confusing. As seen below:
My question: How can I hide the Y-axis labels of any set of data that is currently not being displayed?
This is how I currently have my chart set up:
<canvas id="SQLPerformanceChart" minHeight="400"></canvas>
<script type="text/javascript">
...
var data = {
labels: labelArray,
datasets: [{
label: "Total SQL Queries",
fill: false,
borderWidth: 1,
borderColor: "green",
backgroundColor: "rgba(0, 255, 0, 0.3)",
yAxisID: "y-axis-0",
data: totalQueriesArray
}, {
label: "Slow SQL Queries",
fill: false,
borderWidth: 1,
borderColor: "orange",
backgroundColor: "rgba(255, 255, 0, 0.3)",
yAxisID: "y-axis-1",
data: slowQueriesArray,
}]
};
var options = {
animation: false,
scales: {
yAxes: [{
position: "left",
ticks: {
beginAtZero: true
},
scaleLabel: {
display: true,
labelString: 'Total SQL Queries'
},
id: "y-axis-0"
}, {
position: "right",
ticks: {
beginAtZero: true
},
scaleLabel: {
display: true,
labelString: 'Slow SQL Queries'
},
id: "y-axis-1"
}]
},
tooltips: {
enabled: true,
mode: 'single',
callbacks: {
title: function(tooltipItem, data) {
return data.label;
},
beforeLabel: function(tooltipItem, data) {
if (tooltipItem.index == 24) {
return data.labels[tooltipItem.index] + " - Now";
} else {
return data.labels[tooltipItem.index] + " - " + data.labels[(tooltipItem.index) + 1];
}
}
}
}
}
var ctx = document.getElementById("SQLPerformanceChart");
var SQLPerformanceChart = new Chart(ctx, {
type: 'bar',
data: data,
options: options
});
</script>
You can add a callback function to legends onClick:
var options = {
animation: false,
scales: {
yAxes: [{
position: "left",
ticks: {
beginAtZero: true
},
scaleLabel: {
display: true,
labelString: 'Total SQL Queries'
},
id: "y-axis-0"
}, {
position: "right",
ticks: {
beginAtZero: true
},
scaleLabel: {
display: true,
labelString: 'Slow SQL Queries'
},
id: "y-axis-1"
}]
},
legend: {
onClick: function(event, legendItem) {
//get the index of the clicked legend
var index = legendItem.datasetIndex;
//toggle chosen dataset's visibility
SQLPerformanceChart.data.datasets[index].hidden =
!SQLPerformanceChart.data.datasets[index].hidden;
//toggle the related labels' visibility
SQLPerformanceChart.options.scales.yAxes[index].display =
!SQLPerformanceChart.options.scales.yAxes[index].display;
SQLPerformanceChart.update();
}
}
}
This solution applies if you are using angular-chartjs, and if you want to apply this behaviour to all displayed charts.
If you want to skip to the code, check this fiddlejs.
You can also check this other fiddlejs to check the default Angular-Chartjs behaviour.
Step by step:
I use the first chart example in angular-chart.js, so this will be the final result after clicking:
<div ng-app="app" ng-controller="MainController as mainCtrl">
<canvas id="line" class="chart chart-line" chart-data="data"
chart-labels="labels" chart-series="series" chart-options="options"
chart-dataset-override="datasetOverride" chart-click="onClick">
</canvas>
</div>
Replace the handler of the global Chart:
Chart.defaults.global.legend.onClick = function (e, legendItem) {
var idx = legendItem.datasetIndex;
// IMPORTANT charts will be created in the second and third step
var chart = charts[e.srcElement.id];
chart.options.scales.yAxes[idx].display = !chart.options.scales.yAxes[idx].display;
var meta = chart.getDatasetMeta(idx);
// See controller.isDatasetVisible comment
meta.hidden = meta.hidden === null ? !chart.data.datasets[idx].hidden : null;
chart.update();
};
Create a global variable charts so we can get access each of the charts with the canvas id:
var charts = {};
Fill up the charts variables using the chart-create event:
angular.module("app", ["chart.js"]).controller("MainController", function ($scope) {
$scope.$on('chart-create', function (event, chart) {
charts[chart.chart.canvas.id] = chart;
});
$scope.labels = ["January", "February", "March", "April", "May", "June", "July"];
$scope.series = ['Series A', 'Series B'];
$scope.data = [...
I wish there would be a better way of getting a chart from the canvas id, but as far as I know this is the suggested way by the developers.
This solution applies if you are using ng2-charts with chart.js and Angular 7^ and if you want to apply this behavior to all displayed charts.
import Chart from chart.js
Chart.defaults.global.legend.onClick = function (e: MouseEvent, chartLegendLabelItem: ChartLegendLabelItem) {
const idx: number = chartLegendLabelItem.datasetIndex;
const chart = this.chart;
chart.options.scales.yAxes[idx].display = !chart.options.scales.yAxes[idx].display;
const meta = chart.getDatasetMeta(idx);
meta.hidden = meta.hidden === null ? !chart.data.datasets[idx].hidden : null;
chart.update();
};
or for local configuration
legend: <ChartLegendOptions>{
onClick: function (e: MouseEvent, chartLegendLabelItem:ChartLegendLabelItem) {
const idx: number = chartLegendLabelItem.datasetIndex;
const chart = this.chart;
chart.options.scales.yAxes[idx].display =
!chart.options.scales.yAxes[idx].display;
const meta = chart.getDatasetMeta(idx);
meta.hidden = meta.hidden === null ?
!chart.data.datasets[idx].hidden : null;
chart.update();
}
}
I came along this problem using v3.8.0, none of the obove worked for me.
This code works for me.
Note I'm storing all my chart instances in a Map because I have multiple charts on the same page.
var instances = new Map();
When createing the incances I put them there.
and now the hiding of the y axis label and data on legend click:
onClick: function (event, legendItem) {
var instance = instances.get(event.chart.id);
var meta = instance.getDatasetMeta(legendItem.datasetIndex);
var newValue = !meta.yScale.options.display;
meta.hidden = meta.yScale.options.display;
meta.yScale.options.display = newValue;
instance.update();
}

Categories