How to make pie slices in chartjs clickable (react-native) - javascript

I am working with a library that makes chartjs usable on react-native:
react-native-chartjs.
The chart works well, but when I press on the pie slices I only get the tooltip.
What I would like to, is to create my own function that will load a pop-up window instead of the tooltip provided by chart.js
How would you guys do it? Is it even doable? (I am pretty new to react-native, so sorry if it's a stupid question).
Image of the:
Chart
Chart code:
export const NutritionChart = (props) => {
return (
<Chart
chartConfiguration={
{
type: 'polarArea',
data: {
labels: ['Fiber', 'Protein', 'Healthy Oil', 'Good Energy']‚
datasets: [
{
label: '# of Votes',
data: [ 50, 140, 90, 120 ],
backgroundColor: backgroundColor,
borderColor: borderColor,
borderWidth: datasets.border,
hoverBackgroundColor: hoverBackgroundColor,
},
],
},
options: {
layout: {
padding: {
top: options.layout.padding.top,
bottom: options.layout.padding.bottom,
}
},
scale: {
display: false,
ticks: {
min:0,
max:200,
}
},
responsive: true,
maintainAspectRatio: false,
},
}
}
defaultFontSize={10}
/>
);
};

Related

How to set percentage value by default on each bars in horizontal bar chart js

I have used horizontal bar chart from chart.js where i need percentage values to be shown next to each bar at right side? here is the bar sample image.
click here to view sample image of bar chart
Also these are the options i have tried :
xAxes: [
{
ticks: {
min: 0,
max: 100
},
grid: {
offset: false
}
},
],
yAxes: [
{
gridLines: {
display: false,
},
display: "right",
barPercentage: 0.8,
minBarLength: 2,
},
],
Is there any option which can turn the percentage values on at he right side of the horizontal bar chart?
Please click below image to see the expected output
click image expected output
You can make use of the datalabels plugin
Example:
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.3.0/dist/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels#2.0.0-rc"></script>
<canvas id="myChart" width="850" height="520"></canvas>
<script>
var ctx = document.getElementById('myChart');
Chart.register(ChartDataLabels);
Chart.defaults.set('plugins.datalabels', {
color: '#FE777B'
});
var myChart = new Chart(ctx, {
type: 'bar',
plugins: [ChartDataLabels],
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
data: [12, 19, 3, 5, 2, 3],
label: 'Advisor Closed MTD',
backgroundColor: 'rgb(192,111,94)',
barThickness: 25,
datalabels: {
color: '#FFCE56'
}
}],
},
options: {
indexAxis: 'y',
responsive: false,
plugins: {
datalabels: {
formatter: (val, context) => (`${val}%`),
anchor: 'end',
align: 'end',
labels: {
value: {
color: 'blue'
}
}
}
}
}
});
</script>

Trying to merge three different bar charts into one with chart.js

I'm trying to have 3 different categories into one bar chart, but I just can't get it to work. I'm using chart.js with React.
This is what I'm trying to achieve:
Here's what I tried:
function VerticalBarChart({data,width,height}) {
const data= {
labels: ['Department',"Gender","Age"],
datasets:[
{
label: "Corporate",
backgroundColor: "blue",
data: [3]
},
{
label: "Warehouse",
backgroundColor: "blue",
data: [10]
},
{
label: "Finance",
backgroundColor: "blue",
data: [6]
},
{
label: ["Male","Female","Other"],
backgroundColor: "red",
data: [0,7,5]
},
{
label: ["18-29","30-49","50+"],
backgroundColor: "black",
data: [0,10,4]
}
],
options:{
responsive:true,
legend: {
display: false,
},
labels:{
fontColor: 'black',
fontFamily: "'Montserrat', sans-serif",
},
scales: {
yAxes: [{
ticks:{
beginAtZero:true
}
}],
xAxes: [{
gridLines: {
display: false
}
}]
},
maintainAspectRatio: false,
}
};
return (
<div>
<Bar data={data} width={width} height={height} options={data.options} />
</div>
)
}
Which gives me this result:
If I do it like this, it creates additional spacing for the different categories. I'm trying to figure out how to arrange the data variable so that chart.js knows its separate categories and it's not tied to each other. Basically I'm trying to combine three different bar charts together in one.

Chart.js Mouse Over Show Old Chart Data

I was having some problem when trying to redraw chart on canvas using chart.js in Angular. Here is my HTML component:
<div class="form-group">
<select [(ngModel)]="timeMode" id="timeModeInput" class="browser-default custom-select" (change)="onTimeModeChange($event)">
<option value="all" selected>Yearly</option>
<option value="monthly">Monthly</option>
</select>
</div>
<canvas id="expenseTimelineCanvas"></canvas>
Upon dropdown select, I repopulate the chart:
if (chart != null) { chart.destroy(); chart.clear(); }
chart = new Chart(chartName, {
type: "line",
data: {
labels: labels,
datasets: [
{
data: chartData,
borderColor: lineColor,
fill: false,
borderWidth: 1,
borderDash: [10, 10],
pointBackgroundColor: "white",
pointBorderColor: lineColor,
pointRadius: 5
}
]
}
}
});
However, when I mouse over at certain part of the canvas, the old chart will be displayed. Any ideas on how to totally destroy the canvas before replotting on the same DOM element?
Thanks!
this happens because chartjs uses canvas and for redrawing you just have to destroy old drawing from the canvas.
when you make a new chart then you have to destroy the old chart.
but in angular you can also just reload the component to destroy the chart
your method
//this method
initChart(){
//this will generate chart you need
//before generating just destroy the old chart
}
second method
//in html file
<thisIsHTMLTagOfChartComponent *ngIf="showChart">
</thisIsHTMLTagOfChartComponent>
//in typescript
public showChart = false;
//this function will be called everytime you fetch the data from server
getChartData(){
this.showChart = false; //this will remove the component from the page
fetchData(uri)
.then(result => {
//do your stuff here
this.showChart = true // this will load the component in the page again
}
)
i prefer to not destroy your chart just change the value of it for e.g: in your change function just load a new chart definition in your same chart with new config, we have 2 different configs:
config = {
type: 'bar',
data: {
labels: dringlichkeiten.map(x => x.id),
datasets: [
{
label: 'My Bar Chart',
data: dringlichkeiten.map(x => x.value),
backgroundColor: ['red', 'green', 'yellow', 'blue', 'orange']
}
]
},
}
config2 = {
type: 'line',
data: {
datasets: [{
label: 'Höhenlinie',
backgroundColor: "rgba(255, 99, 132,0.4)",
borderColor: "rgb(255, 99, 132)",
fill: true,
data: [
{ x: 1, y: 2 },
{ x: 2500, y: 2.5 },
{ x: 3000, y: 5 },
{ x: 3400, y: 4.75 },
{ x: 3600, y: 4.75 },
{ x: 5200, y: 6 },
{ x: 6000, y: 9 },
{ x: 7100, y: 6 },
],
}]
},
options: {
responsive: true,
title: {
display: true,
text: 'Höhenlinie'
},
scales: {
xAxes: [{
type: 'linear',
position: 'bottom',
ticks: {
userCallback: function (tick) {
if (tick >= 1000) {
return (tick / 1000).toString() + 'km';
}
return tick.toString() + 'm';
}
},
scaleLabel: {
labelString: 'Länge',
display: true,
}
}],
yAxes: [{
type: 'linear',
ticks: {
userCallback: function (tick) {
return tick.toString() + 'm';
}
},
scaleLabel: {
labelString: 'Höhe',
display: true
}
}]
}
}
}
chart: Chart ;
in your change function just load a new config:
change(){
this.chart = new Chart('canvas', this.config2)
}
DEMO.

Draw horizontal line on chart in chart.js on v2

I have drawn a line chart using chart.js. For the labels and datasets i am getting values from the database. I am new to chart.js and its very powerful library, yet i am unable to completely understand it. I want to draw multiples horizontal lines. Like where if mean of dataset, standard deviation and min and max. I have tried the question here in stackoverflow but these are giving errors or may be i am not able to understand the working. This is my chart.js code
function display_graph(id, label, data) {
var ctx = document.getElementById(id);
var data = {
labels: data.labels,
datasets: [
{
label: label,
fill: false,
lineTension: 0.1,
backgroundColor: "rgba(75,192,192,0.4)",
borderColor: "rgba(75,192,192,1)",
borderCapStyle: 'butt',
borderDash: [],
borderDashOffset: 0.0,
borderWidth: 1,
borderJoinStyle: 'miter',
pointBorderColor: "rgba(75,192,192,1)",
pointBackgroundColor: "#fff",
pointBorderWidth: 1,
pointHoverRadius: 5,
pointHoverBackgroundColor: "rgba(75,192,192,1)",
pointHoverBorderColor: "rgba(220,220,220,1)",
pointHoverBorderWidth: 2,
pointRadius: 1,
pointHitRadius: 10,
data: data.assay_value,
spanGaps: false
}
]
};
//options
var options = {
responsive: true,
title: {
display: true,
position: "top",
text: label,
fontSize: 18,
fontColor: "#111"
},
legend: {
display: true,
position: "bottom",
labels: {
fontColor: "#333",
fontSize: 16
}
}
};
var Blanks_Chart=null;
Blanks_Chart = new Chart(ctx, {
type: 'line',
data: data,
options: options
});}
You could use the chart.js annotation plugin to easily draw lines on your chart without having to mess with rendering pixels in your canvas manually (the old approach that is giving you errors). Note, the plugin is created/supported by the same team as chart.js and is mentioned in the chart.js docs.
Here is an example codepen demonstrating creating a line on a chart.
Once you add the plugin, you simply just set annotation properties in your chart config. Here is an example.
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ["January", "February"],
datasets: [{
label: 'Dataset 1',
borderColor: window.chartColors.blue,
borderWidth: 2,
fill: false,
data: [2, 10]
}]
},
options: {
responsive: true,
title: {
display: true,
text: 'Chart.js Draw Line On Chart'
},
tooltips: {
mode: 'index',
intersect: true
},
annotation: {
annotations: [{
type: 'line',
mode: 'horizontal',
scaleID: 'y-axis-0',
value: 5,
borderColor: 'rgb(75, 192, 192)',
borderWidth: 4,
label: {
enabled: false,
content: 'Test label'
}
}]
}
}
});
if you want to draw threshold line,easiest way is that using mixed line chart.
Note: Make an array filled with threshold value and the length should be same as your dataset.
var datasets = [1, 2, 3];
var ctx = document.getElementById('chart').getContext('2d');
var thresholdValue = 2;
var thresholdHighArray = new Array(datasets.length).fill(thresholdValue);
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: [],
datasets: [
{datasets}, thresholdHighArray]
},
options: {
responsive: true,
legend: {
position: 'bottom',
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Readings'
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Reading ( °C )'
}
}]
},
annotation: {
annotations: [
{
type: "line",
mode: "vertical",
scaleID: "x-axis-0",
borderColor: "red",
label: {
content: "",
enabled: true,
position: "top"
}
}
]
}
});
};
If you are using the NPM package chartjs-plugin-annotation.js, the important thing - which you may forget, is to register the plugin.
So first of all you installed the npm packages (here for React):
npm i react-chartjs-2 (depends on your framework)
npm i chartjs-plugin-annotation (always required)
See Vue.js or Angular for their framework depending packages.
Option 1: Global plugin registration
import { Line } from 'react-chartjs-2';
import Chart from 'chart.js';
import * as ChartAnnotation from 'chartjs-plugin-annotation';
Chart.plugins.register([ChartAnnotation]); // Global
// ...
render() {
return (
<Line data={chartData} options={chartOpts} />
)
}
Option 2: Per chart plugin registration
import { Line } from 'react-chartjs-2';
import * as ChartAnnotation from 'chartjs-plugin-annotation';
// ...
render() {
return (
{/* per chart */}
<Line data={chartData} options={chartOpts} plugins={[ChartAnnotation]} />
)
}
chartData is equivalent to the data: { section and chartOpts to options: { from jordanwillis answer. See this github post for further information.
There are many other plugins available for chart.js.
Here's an example of getting it working in a Rails view if you're using it with the Chartkick gem:
<%=
line_chart profit_per_day_chart_path(staff), xtitle: 'Day', ytitle: 'Profit',
library: {
annotation: {
annotations: [
{
type: 'line',
mode: 'horizontal',
scaleID: 'y-axis-0',
value: 20,
label: {
content: 'My Horizontal Line',
enabled: true
}
}
]
}
}
%>
Ensure that you've registered the chartjs-plugin-annotation.js plugin with Chart.js first:
import ChartAnnotationsPlugin from 'chartjs-plugin-annotation';
Chart.plugins.register(ChartAnnotationsPlugin);

Chart.js v2 - combined stacked bar chart and 2 unstacked lines

Can Chart.js v2.x generate a combined stacked bar chart with 2 unstacked lines utilizing one y-axis? If so, how?
Below fiddle has 2 y-axis. The descending line, would render better if the right y-axis had a maximum value of 6000 as does the left axis.
jsfiddle example.
Below is the code for reference.
// set default no fill beneath the line
Chart.defaults.global.elements.line.fill = false;
// stacked bar with 2 unstacked lines - nope
var barChartData = {
labels: ['2016', '2017', '2018', '2019'],
datasets: [{
type: 'bar',
label: 'a',
yAxisID: "y-axis-0",
backgroundColor: "rgba(217,83,79,0.75)",
data: [1000, 2000, 4000, 5000]
}, {
type: 'bar',
label: 'b',
yAxisID: "y-axis-0",
backgroundColor: "rgba(92,184,92,0.75)",
data: [500, 600, 700, 800]
}, {
type: 'line',
label: 'c',
yAxisID: "y-axis-0",
backgroundColor: "rgba(51,51,51,0.5)",
data: [1500, 2600, 4700, 5800]
}, {
type: 'line',
label: 'd',
yAxisID: "y-axis-1",
backgroundColor: "rgba(151,187,205,0.5)",
data: [5000, 3000, 1000, 0]
}]
};
var ctx = document.getElementById("chart").getContext("2d");
// allocate and initialize a chart
var ch = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
title: {
display: true,
text: "Chart.js Bar Chart - Stacked"
},
tooltips: {
mode: 'label'
},
responsive: true,
scales: {
xAxes: [{
stacked: true
}],
yAxes: [{
stacked: true,
position: "left",
id: "y-axis-0",
}, {
stacked: false,
position: "right",
id: "y-axis-1",
}]
}
}
});
Turns out, I just needed a modification or two so that the 2 y-axis use the same scale. See this jsfiddle. Now the chart renders better. The key, in my case, is adding a ticks node and these two properties to both yAxes objects:
ticks: {
beginAtZero: true,
suggestedMax: 5800
}
Naturally, the suggestedMax value would not be hard coded. Further, since the 2 scales are now the same, I hid the right scale with this property setting display: false.
As the fiddle shows, we now have 2 unstacked lines on a stacked bar chart nicely rendered.
Use this as the data for the graph:
var barData = {
labels: ['test1','test2'],
datasets: [
{
label: 'stack1',
backgroundColor: 'yellow',
borderColor: 'white',
borderWidth: 1,
stack: '1',
data: [5,4,3,2,1]
},
{
label: 'stack2',
backgroundColor: 'blue',
borderColor: 'white',
borderWidth: 1,
stack: '2',
data: [1,2,3,4,5]
}
]
};
This is the component to render the data:
<Bar data={barData} options={{scales: { xAxes: [{stacked:true}} }], yAxes:[{stacked:true}}] } }}}} />

Categories

Resources