I am having tough time understanding how I could create Graphs in React (this is first time I am working on it)
Can someone help me by sharing which library are you using and how would you use it to plot 3 data set which looks something like this in a single graph
This would be how my data set look.
(3) [{…}, {…}, {…}]
0:{id: "SAMPLE_#SPMJXVC_1_2", x: Array(963), y: Array(963)}
1: {id: "SAMPLE_#SPMJXVC_1_3", x: Array(964), y: Array(964)}
2: {id: "SAMPLE_#SPMJXVC_1_1", x: Array(954), y: Array(954)}
Chart.js is a very popular library for creating Javascript charts.
There is a wrapper that makes Chart.js easy to use in React: https://github.com/jerairrest/react-chartjs-2
If you don't want to use that, you can read this article for more ideas:
https://www.overloop.io/blog/2018/6/19/top-5-react-chart-libraries
If you decide to use this react-chartjs-2 package then in React you'd install the package and then follow the instructions in their github. For a scatter plot you have to setup the data object and then simply render <Scatter data={data} />
Here is their full example I took from their site:
import React from 'react';
import {Scatter} from 'react-chartjs-2';
const data = {
labels: ['Scatter'],
datasets: [
{
label: 'My First dataset',
fill: false,
backgroundColor: 'rgba(75,192,192,0.4)',
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: [
{ x: 65, y: 75 },
{ x: 59, y: 49 },
{ x: 80, y: 90 },
{ x: 81, y: 29 },
{ x: 56, y: 36 },
{ x: 55, y: 25 },
{ x: 40, y: 18 },
]
}
]
};
export default React.createClass({
displayName: 'ScatterExample',
render() {
return (
<div>
<h2>Scatter Example</h2>
<Scatter data={data} />
</div>
);
}
});
Related
I am using Chart.js library in my React application.
I want to implement Bollinger Bands looking like this:
Is it possible and if so how? I have searched through issues of the repository and have not found the answer I am looking for.
If it is not possible what other library could you recommend? I have looked into:
Highcharts
React-charts
react-chartjs-2
React-financial-charts
react-stockcharts
Recharts
Could you direct me to the sources I need to read.
Thanks in advance.
This is not possible in chart.js by default, you can achieve this in 2 ways, you can write a custom inline plugin to draw it on the canvas or you can use 2 extra datasets and filter out the legend
Extra datasets example:
var options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [7, 11, 5, 8, 3, 7],
borderWidth: 1,
backgroundColor: 'black',
borderColor: 'black'
},
{
label: 'boll 1',
data: [6.6, 9, 4, 7, 0, 2],
borderWidth: 1,
pointRadius: 0,
pointHoverRadius: 0,
tension: 0.4,
pointHitRadius: 0
},
{
label: 'boll 2',
data: [7.3, 11.5, 5.9, 9.6, 5, 11],
borderWidth: 1,
pointRadius: 0,
pointHoverRadius: 0,
fill: '-1',
tension: 0.4,
pointHitRadius: 0
}
]
},
options: {
plugins: {
legend: {
labels: {
filter: (label, data) => (!label.text.includes("boll"))
}
}
}
}
}
var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.2.0/chart.js"></script>
</body>
I am trying to generate a scatterplot using chartJS. The plot wont graph.
When i feed in data manually by declaring the data, it works fine,
var scatter = [
{ x: 65, y: 75 },
{ x: 59, y: 49 },
{ x: 80, y: 90 },
{ x: 81, y: 29 },
{ x: 56, y: 36 },
{ x: 55, y: 25 },
{ x: 40, y: 18 },
]
but when I get the data via an API call and push the data to the array, it won't work. Any suggestions? I suspect its to do with how data is pushed onto the array but not sure what's wrong.
Thank you
Minimum solution below
import React, { useEffect, useState } from 'react';
import axios from 'axios';
function App() {
const [scatterData, setScatterData] = useState({});
const chart = () => {
var scatter = [];
axios.get('http://dummy.restapiexample.com/api/v1/employees')
.then(res => {
let temp = res.data.data
temp.forEach( i=> {
let age = parseInt(i.employee_age)
let salary = parseInt(i.employee_salary)
scatter.push({"x": age,
"y": salary})
})
}).catch(err => {
console.log(err)
})
console.log(scatter)
setScatterData({
datasets: [
{
label: 'test',
fill: true,
backgroundColor: 'rgba(75,192,192,0.4)',
pointBorderColor: 'rgba(75,192,192,1)',
pointBackgroundColor: '#fff',
pointBorderWidth: 1,
pointHoverRadius: 10,
pointHoverBackgroundColor: 'rgba(75,192,192,1)',
pointHoverBorderColor: 'rgba(220,220,220,1)',
pointHoverBorderWidth: 2,
pointRadius: 3,
pointHitRadius: 10,
data: scatter,
backgroundColor: [
'rgba(75,192,192,0.6)'
],
borderWidth: 4
}
]
});
}
useEffect(() ={
chart()
},[])
return (
<div className ="container-fluid">
<div class="row">
<div className ="col-md-12">
<Scatter data={scatterData}/>
</div>
</div>
</div>
)
};
Try calling the update method on your chart object/instance after you pushed all the data from the api to your scatter array
I'm trying to display a line chart on a webpage using Chart.js that shows the number of downloads in the apple store and google play store for a specific client for the past 5 days. The data appears properly, but does not properly label the X axis with this:
var downloadsChartData = {
labels: ["4 Days", "3 Days", "2 Days", "Yesterday", "Today"],
datasets: [{
label: "Google Play",
fill: false,
lineTension: 0,
backgroundColor: "rgba(0, 230, 115, 1)",
borderColor: "rgba(0, 230, 115, 1)",
borderCapStyle: 'butt',
borderJoinStyle: 'miter',
borderWidth: 2,
pointBorderColor: "rgba(150, 75, 75, 1)",
pointBorderWidth: 3,
pointRadius: 6,
pointHoverRadius: 9,
pointStyle: 'triangle',
data: [{
x: 1,
y: 2
}, {
x: 2,
y: 0
}, {
x: 3,
y: 3
}, {
x: 4,
y: 1
}, {
x: 5,
y: 1
}]
}, {
label: "iOS",
fill: false,
lineTension: 0,
backgroundColor: "rgba(26, 117, 255, 1)",
borderColor: "rgba(26, 117, 225, 1)",
borderCapStyle: 'butt',
borderJoinStyle: 'miter',
borderWidth: 2,
pointBorderColor: "rgba(150, 75, 75, 1)",
pointBorderWidth: 3,
pointRadius: 6,
pointHoverRadius: 9,
data: [{
x: 1,
y: 4
}, {
x: 2,
y: 2
}, {
x: 3,
y: 0
}, {
x: 4,
y: 1
}, {
x: 5,
y: 4
}]
}]
};
var downloadsChartOptions = {
title: {
display: true,
text: 'Downloads on Google Play and App Store',
fontSize: 30
},
scales: {
xAxes: [{
scaleLabel: {
display: true,
abelString: 'Date',
fontSize: 20
},
type: 'linear',
position: 'bottom',
gridLines: {
display: false
}
}],
yAxes: [{
scaleLabel: {
display: true,
labelString: 'Downloads',
fontSize: 20
}
}]
}
};
var downloadsChart = document.getElementById('downloadsChart').getContext('2d');
new Chart(downloadsChart, {
type: 'line',
data: downloadsChartData,
options: downloadsChartOptions
});
I tried to switch the data field to an array of values so that Chart.js would recognize the labels I defined in downloadsChartData to:
...
pointStyle: 'triangle',
data: [2, 0, 3, 1, 1]
}]
...
pointHoverRadius: 9,
data: [4, 2, 0, 1, 4]
}]
However, when I make this change, the chart not only doesn't correctly label the X axes, but also stops displaying the data on the line chart entirely.
Can someone please spot what I'm doing incorrectly? The documentation isn't too helpful in this matter.
The documentation is not very clear on this point, but for graphing non-numerical data (such as your case where the X axis represents a Date) you cannot set the X axis to have a linear scale. In other words, if you set your axis with a linear scale, it will graph the numerical representation of the data (and therefore, not the label).
I removed type: 'linear' from your downloadsChartOptions and it solved the issue.:
var downloadsChartOptions = {
title: {
display: true,
text: 'Downloads on Google Play and App Store',
fontSize: 30
},
scales: {
xAxes: [{
scaleLabel: {
display: true,
labelString: 'Date',
fontSize: 20
},
//type: 'linear',
position: 'bottom',
gridLines: {
display: false
}
}],
yAxes: [{
scaleLabel: {
display: true,
labelString: 'Downloads',
fontSize: 20
}
}]
}
};
I started messing with Chart.js today, and I'm really impressed so far by how easy it is to understand, even for a javascript beginner like myself.
I'm wanting to add some spacing horizontally between the tooltip and the data point on the graph. By default, the caret point touches the data point. I can't figure it out. I know there's a position option, but I don't quite get how it's used. I also tried using the tooltips: { x } option but no luck either. Guessing I'm misunderstanding what that is for.
Below is what I have so far for one chart...
Thanks, appreciate it!
//Global Chart.js options
Chart.defaults.global.defaultFontFamily = 'Lato';
Chart.defaults.global.elements.responsive = true;
Chart.defaults.global.tooltips.xPadding = 10;
Chart.defaults.global.tooltips.yPadding = 10;
Chart.defaults.global.tooltips.titleMarginBottom = 10;
Chart.defaults.global.tooltips.position = 'average';
//Individual chart config
var ctx = "myChart";
var myChart = new Chart(ctx, {
type: 'line',
options: {
title: {
display: true,
text: 'Precision-Recall Curve',
},
layout: {
padding: 32
},
tooltips: {
x: 20
},
},
data: {
labels: ['0%', '10%', '20%', '30%', '40%', '50%', '60%', '70%', '80%', '90%', '100%'],
datasets: [{
label: 'Precision',
data: [2, 42, 55, 50, 42, 38, 32, 24, 20, 18, 18],
borderColor: '#1abc9c',
backgroundColor: 'RGBA(26, 188, 156, .4)',
pointBorderColor: "#4BC0C0",
pointBackgroundColor: "#fff",
pointHitRadius: 10
}, {
label: 'Recall',
data: [2, 12, 24, 30, 39, 58, 70, 82, 86, 89, 93],
borderColor: '#34495e',
backgroundColor: 'RGBA(52, 73, 94, .3)',
pointBorderColor: "#34495e",
pointBackgroundColor: "#fff",
pointHitRadius: 10
}]
}
});
<div class="container">
<div>
<canvas id="myChart"></canvas>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.bundle.min.js"></script>
I have something close, tooltips can accept a position which is an alias for a function stored in Chart.Tooltip.positioners. This function returns the x and y position for the tooltip.
You can add a custom one to adjust the x at an offset.
The only issue is that by adjust the x the layout (left/right direction) of the tooltip can change meaning that even after working out if the tool tip is below half way or above half way bu adjusting the x it then switches its layout meaning on tooltip in the middle will look odd as it is offset in the wrong direction.
This could be fixed by knowing the width of the tooltip and taking this into account but looking through the data provided to the function this is not given.
Anyway leaving this as an answer it gets you most of the way there and you/someone might be able to figure out how to get rid of that annoying last part
//Global Chart.js options
Chart.defaults.global.defaultFontFamily = 'Lato';
Chart.defaults.global.elements.responsive = true;
Chart.defaults.global.tooltips.xPadding = 10;
Chart.defaults.global.tooltips.yPadding = 10;
Chart.defaults.global.tooltips.titleMarginBottom = 10;
Chart.defaults.global.tooltips.position = 'average';
//register custome positioner
Chart.Tooltip.positioners.custom = function(elements, position) {
if (!elements.length) {
return false;
}
var offset = 0;
//adjust the offset left or right depending on the event position
if (elements[0]._chart.width / 2 > position.x) {
offset = 20;
} else {
offset = -20;
}
return {
x: position.x + offset,
y: position.y
}
}
//Individual chart config
var ctx = "myChart";
var myChart = new Chart(ctx, {
type: 'line',
options: {
title: {
display: true,
text: 'Precision-Recall Curve',
},
layout: {
padding: 32
},
tooltips: {
//use our new custom position
position: 'custom'
},
},
data: {
labels: ['0%', '10%', '20%', '30%', '40%', '50%', '60%', '70%', '80%', '90%', '100%'],
datasets: [{
label: 'Precision',
data: [2, 42, 55, 50, 42, 38, 32, 24, 20, 18, 18],
borderColor: '#1abc9c',
backgroundColor: 'RGBA(26, 188, 156, .4)',
pointBorderColor: "#4BC0C0",
pointBackgroundColor: "#fff",
pointHitRadius: 10
}, {
label: 'Recall',
data: [2, 12, 24, 30, 39, 58, 70, 82, 86, 89, 93],
borderColor: '#34495e',
backgroundColor: 'RGBA(52, 73, 94, .3)',
pointBorderColor: "#34495e",
pointBackgroundColor: "#fff",
pointHitRadius: 10
}]
}
});
<div class="container">
<div>
<canvas id="myChart"></canvas>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.bundle.min.js"></script>
I think it's simpler by change the number of caretPadding. We can increase the distance from tooltip to data point by caretPadding
option: {
tooltip: {
caretPadding: 20,
}
}
caretPadding-image
I'm using the latest version of high charts. I successfully created a 3d bubble chart following http://www.highcharts.com/demo/bubble-3d
I am wondering if I can add to the legend a reference to what the size of the bubble means. Just a simple bubble with some text next to it would be enough.
Thanks in advance for your help.
Just add an empty series and name it.Give it desired name ,See Updated fiddle here
{
name :"description",
marker: {
fillColor: {
radialGradient: { cx: 0.4, cy: 0.3, r: 0.7 },
stops: [
[0, 'rgba(255,255,255,0.5)'],
[1, Highcharts.Color(Highcharts.getOptions().colors[1]).setOpacity(0.5).get('rgba')]
]
}
}}
Representing bubble size in a legend is not currently a feature of Highcharts.
You can draw one manually:
Add a series for the legend
Draw a rendered box around the legend
JSFiddle
Add a series for the legend
series: [{
// This series gives a legend for reference
data: [{
color: Highcharts.getOptions().colors[0],
x: 86,
y: 25,
z: 10,
dataLabels: {
format: '10%',
y: 40
}
}, {
x: 90,
y: 25,
z: 15,
dataLabels: {
format: '15%',
y: 40
}
}, {
x: 94,
y: 25,
z: 35,
dataLabels: {
format: '35%',
y: 40
}
}]
}, {
color: Highcharts.getOptions().colors[0],
data: [{
x: 95,
y: 95,
z: 13.8,
name: 'BE',
country: 'Belgium'
}, {
Draw a rendered box around the legend
events: {
load: function() {
// Draw the flow chart
var ren = this.renderer,
colors = Highcharts.getOptions().colors;
// Script label
ren.label('Obesity Rate', 410, 220)
.attr({
stroke: '#777',
'stroke-width': 1,
padding: 5,
r: 5,
width: 168,
height: 73
})
.css({
color: '#333',
textAlign: 'center',
fontSize: '1.1em'
})
.add();
}
}