I'd like to sum objects from array, I've been searching and testing different things founds around there, using Lodash or not, without any success.
Here is the data array, there is 5 elements but it could be less or more. The properties will always be the same, but there could be a lot more.
const data = [
{
from: "2019-10-15",
stats: [
{
options: {
width: 15,
height: 20,
borders: 35,
removable: 5
}
}
]
},
{
from: "2019-10-16",
stats: [
{
options: {
width: 22,
height: 18,
borders: 10,
removable: 0
}
}
]
},
{
from: "2019-10-17",
stats: [
{
options: {
width: 0,
height: 15,
borders: 15,
removable: 0
}
}
]
},
{
from: "2019-10-18",
stats: [
{
options: {
width: 20,
height: 20,
borders: 10,
removable: 5,
}
}
]
},
{
from: "2019-10-19",
stats: [
{
options: {
width: 0,
height: 10,
borders: 0,
removable: 30
}
}
]
}
];
The expected result is the sum of each array element stats[0].options properties:
const sum = {
width: 57,
height: 83,
borders: 70,
removable: 40
}
I know it's definitely not complicated.
Use _.map() to get the options, then combine the objects using _.mergeWith(), and use _.add() as the customizer.
const data = [{"from":"2019-10-15","stats":[{"options":{"width":15,"height":20,"borders":35,"removable":5}}]},{"from":"2019-10-16","stats":[{"options":{"width":22,"height":18,"borders":10,"removable":0}}]},{"from":"2019-10-17","stats":[{"options":{"width":0,"height":15,"borders":15,"removable":0}}]},{"from":"2019-10-18","stats":[{"options":{"width":20,"height":20,"borders":10,"removable":5}}]},{"from":"2019-10-19","stats":[{"options":{"width":0,"height":10,"borders":0,"removable":30}}]}];
const result = _.mergeWith({}, ..._.map(data, 'stats[0].options'), _.add);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
If you use lodash/fp you can create a function using _.flow(), and replace _.mergeWith with _.mergeAllWith():
const { flow, map, mergeAllWith, add } = _;
const fn = flow(
map('stats[0].options'),
mergeAllWith(add)
);
const data = [{"from":"2019-10-15","stats":[{"options":{"width":15,"height":20,"borders":35,"removable":5}}]},{"from":"2019-10-16","stats":[{"options":{"width":22,"height":18,"borders":10,"removable":0}}]},{"from":"2019-10-17","stats":[{"options":{"width":0,"height":15,"borders":15,"removable":0}}]},{"from":"2019-10-18","stats":[{"options":{"width":20,"height":20,"borders":10,"removable":5}}]},{"from":"2019-10-19","stats":[{"options":{"width":0,"height":10,"borders":0,"removable":30}}]}];
const result = fn(data);
console.log(result);
<script src='https://cdn.jsdelivr.net/g/lodash#4(lodash.min.js+lodash.fp.min.js)'></script>
It can be done through vanill JavaScript. Just use reduce and foreach methods:
const data = [
{
from: "2019-10-15",
stats: [
{
options: {
width: 15,
height: 20,
borders: 35,
removable: 5
}
}
]
},
{
from: "2019-10-16",
stats: [
{
options: {
width: 22,
height: 18,
borders: 10,
removable: 0
}
}
]
},
{
from: "2019-10-17",
stats: [
{
options: {
width: 0,
height: 15,
borders: 15,
removable: 0
}
}
]
},
{
from: "2019-10-18",
stats: [
{
options: {
width: 20,
height: 20,
borders: 10,
removable: 5,
}
}
]
},
{
from: "2019-10-19",
stats: [
{
options: {
width: 0,
height: 10,
borders: 0,
removable: 30
}
}
]
}
];
const result = data.reduce((a, {stats}) => {
stats.forEach(({options}) => {
for (const key in options) {
a[key] = a[key] || 0;
a[key] += options[key];
}
});
return a;
}, {})
console.log(result);
The vanilla JS code looks like this:
const result = data.reduce((a, {stats}) => {
stats.forEach(({options}) => {
for (const key in options) {
a[key] = a[key] || 0;
a[key] += options[key];
}
});
return a;
}, {})
Another approach to do this with a reduce and nested forEach, but a bit more straightforward:
const data = [
{
from: "2019-10-15",
stats: [
{
options: {
width: 15,
height: 20,
borders: 35,
removable: 5
}
}
]
},
{
from: "2019-10-16",
stats: [
{
options: {
width: 22,
height: 18,
borders: 10,
removable: 0
}
}
]
},
{
from: "2019-10-17",
stats: [
{
options: {
width: 0,
height: 15,
borders: 15,
removable: 0
}
}
]
},
{
from: "2019-10-18",
stats: [
{
options: {
width: 20,
height: 20,
borders: 10,
removable: 5,
}
}
]
},
{
from: "2019-10-19",
stats: [
{
options: {
width: 0,
height: 10,
borders: 0,
removable: 30
}
}
]
}
];
let result = _.reduce(data, (acc, value) =>{
// our nested options object
const options = value.stats[0].options;
_.forEach(options, (optionValue, optionKey) =>{
// if we know about this key already, then add optionValue to it
// if not, this will be our first value for that key
acc[optionKey] = !!acc[optionKey] ? acc[optionKey] + optionValue : optionValue;
})
return acc;
}, {})
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
Related
I am currently trying to use the plugin chartjs-plugin-annotation in my react project.
Unfortunately, it is not working...
He is my implementation :
import React, { Component } from "react";
//import "./css/tideComponent.css";
import jsonData from "./ressources/tideOostende2023.json";
import "chart.js/auto";
import { Chart } from "react-chartjs-2";
import * as ChartAnnotation from "chartjs-plugin-annotation";
class Tide extends Component {
state = {
dayDate: new Date().toJSON().slice(5, 10),
highTide: "",
highTide2: "",
lowTide: "",
lowTide2: "",
};
async componentDidMount() {
const index = jsonData.findIndex(
(item) => item.date === this.state.dayDate
);
//TODO store tide in an array(using split method) & filter low to high to have a correct graph
this.setState({
highTide: jsonData[index].highTide,
highTide2: jsonData[index].highTide2,
lowTide: jsonData[index].lowTide,
lowTide2: jsonData[index].lowTide2,
});
}
timeToNumeric(tideTime) {
const tideTimeSplitted = tideTime.split(":");
return tideTimeSplitted[0] * 1 + tideTimeSplitted[1] / 60;
}
handleTideData() {
if (
this.timeToNumeric(this.state.highTide) <
this.timeToNumeric(this.state.lowTide)
)
return [
{ x: -2, y: 0.5 },
{ x: this.timeToNumeric(this.state.highTide), y: 1.5 },
{ x: this.timeToNumeric(this.state.lowTide), y: 0.5 },
{ x: this.timeToNumeric(this.state.highTide2), y: 1.5 },
{ x: this.timeToNumeric(this.state.lowTide2), y: 0.5 },
{ x: 26, y: 1.5 },
];
return [
{ x: -2, y: 1.5 },
{ x: this.timeToNumeric(this.state.lowTide), y: 0.5 },
{ x: this.timeToNumeric(this.state.highTide), y: 1.5 },
{ x: this.timeToNumeric(this.state.lowTide2), y: 0.5 },
{ x: this.timeToNumeric(this.state.highTide2), y: 1.5 },
{ x: 26, y: 0.5 },
];
}
render() {
const data = {
datasets: [
{
data: this.handleTideData(),
fill: false,
backgroundColor: "rgb(35, 71, 89, 0.88)",
borderColor: " rgb(35, 71, 79, 0.88)",
tension: 0.4,
},
],
};
const options = {
annotation: {
annotations: [
{
type: "line",
mode: "horizontal",
scaleID: "x",
value: 1,
borderColor: "white",
borderWidth: 2,
},
],
},
scales: {
x: { min: 0, max: 24, ticks: { stepSize: 1 } },
y: { min: 0, max: 2.2, display: false },
},
showLine: true,
pointStyle: false,
plugins: {
legend: { display: false },
},
};
return (
<div className="tideContainer">
<Chart
type="scatter"
data={data}
options={options}
plugins={ChartAnnotation}
/>
</div>
);
}
}
export default Tide;`
I tried different things but still not working. I also reviewed multiple question on SO but cannot find my solution. Chart Js is correctly working with my implementation, it is only the plugin that does not work.
Thank you in advance for your great help !!!
I think plugins property in react-chartjs-2 should be an array, I guess.
<Chart
type="scatter"
data={data}
options={options}
plugins={[ChartAnnotation]}
/>
The options config for annotation plugin is not in the right node.
It must be added in options.plugins node.
const options = {
plugins: { // <-- to add, was missing
annotation: {
annotations: [
{
type: "line",
mode: "horizontal",
scaleID: "x",
value: 1,
borderColor: "white",
borderWidth: 2,
},
],
},
}
I am trying to accomplish the following graph in react-charts-js2.
ChartsJS2 chart in Figma
I have been able to accomplish the version with the linear gradient using this code:
<Line
data={createLineGraphData(
gpuMemoryUtilizationTimeSeries,
toMomentTimeFormat,
val => (val == null ? 0 : val * 100),
'Power Draw (W)',
)}
options={gpuExplorerGpuMemoryUtilizationOptions}
/>
const createLineGraphData = function(
data,
fnLabel,
fnValue,
label = '',
) {
// data.result.values
const labels =
data &&
data.map(i => {
if (i && i[0] && fnLabel(i[0])) {
return fnLabel(i[0])
} else {
return '-'
}
})
const graphdata =
data &&
data.map(i => {
if (i && i[0] && fnValue(i[1])) {
return fnValue(i[1])
} else {
return 0
}
})
return canvas => {
let ctx = canvas.getContext('2d')
let gradientStroke = ctx.createLinearGradient(0, 230, 0, 50)
gradientStroke.addColorStop(1, 'rgba(29,140,248,0.2)')
gradientStroke.addColorStop(0.4, 'rgba(29,140,248,0.0)')
gradientStroke.addColorStop(0, 'rgba(29,140,248,0)') //blue colors
return {
labels: labels,
datasets: [
{
label: label,
fill: true,
backgroundColor: gradientStroke,
borderColor: '#1f8ef1',
borderWidth: 2,
borderDash: [],
borderDashOffset: 0.0,
pointBackgroundColor: '#1f8ef1',
pointBorderColor: 'rgba(255,255,255,0)',
pointHoverBackgroundColor: '#1f8ef1',
pointBorderWidth: 20,
pointHoverRadius: 4,
pointHoverBorderWidth: 15,
pointRadius: 4,
data: graphdata,
},
],
}
}
}
However when adding these options: (Specifically when I add the box annotations) the linear gradient disappears. How can I achieve both? ..
export const getGpuExplorerPowerDrawOptions = (data, timestamps) => {
const xAxisTicks = [0]
const suggestedMaxNum = maxNum(data) === 0 ? 500 : maxNum(data)
let i = 0
while (i <= suggestedMaxNum) {
i += stepSize(data)
xAxisTicks.push(i)
}
return {
maintainAspectRatio: false,
legend: {
display: false,
},
tooltips: {
backgroundColor: '#f5f5f5',
titleFontColor: '#333',
bodyFontColor: '#666',
bodySpacing: 4,
xPadding: 12,
mode: 'nearest',
intersect: 0,
position: 'nearest',
},
responsive: true,
scales: {
yAxes: [
{
position: 'right',
barPercentage: 1.6,
gridLines: {
display: false,
drawBorder: false,
},
ticks: {
callback: function(value, index, ticks) {
return value + ' W'
},
min: 0,
beginAtZero: true,
suggestedMin: 0,
suggestedMax: maxNum(data) === 0 ? 500 : maxNum(data),
stepSize: stepSize(data),
padding: 20,
fontColor: '#9a9a9a',
},
},
],
xAxes: [
{
type: 'time',
time: {
unit: 'minute',
unitStepSize: 30,
displayFormats: {
minute: 'h:mm A',
millisecond: 'h:mm A',
},
},
barPercentage: 1.6,
gridLines: {
display: false,
drawBorder: false,
color: 'rgba(255,255,255, 0.1)',
zeroLineColor: 'transparent',
},
ticks: {
padding: 20,
fontColor: '#9a9a9a',
},
},
],
},
annotation: {
annotations: [
...timestamps.map((timestamp, idx, arr) => {
return {
adjustScaleRange: false,
type: 'box',
// optional drawTime to control layering, overrides global drawTime setting
drawTime: 'beforeDatasetsDraw',
// ID of the X scale to bind onto
xScaleID: 'x-axis-0',
// ID of the Y scale to bind onto
yScaleID: 'y-axis-0',
xMin: arr[idx],
xMax: idx + 4 > arr.length - 1 ? arr[arr.length - 1] : arr[idx + 4],
// Top edge of the box in units along the y axis
yMax: xAxisTicks[xAxisTicks.length - 1],
// Bottom edge of the box
yMin: 0, //maxNum(data),
backgroundColor:
idx % 2 === 0 ? thirdBackground : 'rgb(46, 51, 58)',
}
}),
...xAxisTicks.map(tick => {
return {
type: 'line',
mode: 'horizontal',
scaleID: 'y-axis-0',
value: tick,
borderColor: 'rgba(215, 215, 215, 0.1)',
borderWidth: 1,
label: {
enabled: false,
},
}
}),
],
},
}
}
Here is a picture of what the graph looks like before I add the box annotations:
Before adding box annotations options
After adding box annotations options (Notice how the linear gradient disappears)
I am building an app for gym-goers to record and track their progress. For each exercise they input, it should render a chart showing their previous track record. This is working fine.
Users can then add another entry to this track record, but it does not update the chart unless you refresh the page. I can't work out why or how to fix it.
There are a number of different components involved - a parent Exercise.js one, then an ExerciseFooter.js one, which contains the buttons to adjust the target or add a new entry to the exercise, and then AddHistory.js and SetTarget.js components which contain modals and the logic to update the exercise via Redux and MongoDB.
A minimal version of the Exercise.js page is here (I've collapsed the stuff that's mainly styling into single lines as much as possible):
import React, { useState, useEffect } from "react";
import { ExerciseFooter } from "./ExerciseFooter";
import { Line } from "react-chartjs-2";
import { useLocation } from "react-router-dom";
import { useSelector } from "react-redux";
export const Exercise = (props) => {
const location = useLocation();
const users = useSelector((state) => state.auth);
const localUser = JSON.parse(localStorage.getItem("profile"));
const [user, setUser] = useState("");
const [exerciseProp, setExerciseProp] = useState({
history: [""],
target: 0,
});
useEffect(() => {
localUser &&
localUser?.result &&
users.length > 0 &&
setUser(
users.filter(
(filteredUser) => filteredUser._id == props.match.params.userId
)[0]
);
if (!localUser) setUser("");
setExerciseProp(
user?.exercises?.filter(
(exercise) => exercise._id == props.match.params.exerciseId
)[0]
);
}, [users, location]);
//styling for chart
const [barData, setBarData] = useState({
labels: [""],
datasets: [
{ label: "Target", fill: false, radius: 0, data: [""], borderColor: ["rgba(35, 53, 89)"], borderWidth: [3], },
{ label: "You did", data: [""], tension: 0.3, borderColor: ["white"], backgroundColor: ["white"], borderWidth: 3, },
],
});
//updating chart data
var weightArr = [];
var dateArr = [];
var targetArr = [];
if (exerciseProp) {
exerciseProp.history.map((hist) =>
weightArr.push(parseInt(hist.weight) || 0)
);
exerciseProp.history.map((hist) => dateArr.push(hist.date));
for (let i = 0; i < exerciseProp.history.length; i++) {
targetArr.push(exerciseProp.target);
}
}
useEffect(() => {
if (exerciseProp) {
setBarData({
labels: dateArr,
datasets: [
{
label: "Target",
fill: false,
radius: 0,
data: targetArr,
borderColor: ["rgba(35, 53, 89)"], borderWidth: [3],
},
{
label: "Weight",
data: weightArr,
tension: 0.3, borderColor: ["white"], backgroundColor: ["white"], borderWidth: 3,
},
],
});
}
}, [users]);
//render chart ones exerciseProp is populated
if (exerciseProp) {
return (
<div style={{ marginTop: "200px" }}>
<Line
data={barData}
options={{ plugins: { title: { display: false, }, legend: { display: false, }, },
scales: { x: { grid: { color: "white", font: { family: "Dongle", size: 20, }, }, ticks: { color: "white", font: { family: "Dongle", size: 20, }, }, }, y: { grid: { color: "white", }, ticks: { color: "white", font: { family: "Dongle", size: 20, }, }, }, }, }}
/>
{exerciseProp && <ExerciseFooter user={user} exercise={exerciseProp} />}
</div>
);
} else {
return <>Loading...</>;
}
};
I've tried doing a few different things but nothing has worked. I tried adding an 'update' state variable which was updated by a function passed down to the the various dispatches, and then added it to the dependencies of the useEffects, but that didn't seem to make any difference.
Any help much appreciated! As I say, if I just force a refresh then it works fine but know that's bad practice so trying to work out why it isn't re-rendering correctly.
Thanks!
You just have to enable redraw prop
like this
<Line
redraw={true}
data={barData}
options={{ plugins: { title: { display: false, }, legend: { display: false, }, },
scales: { x: { grid: { color: "white", font: { family: "Dongle", size: 20, }, }, ticks: { color: "white", font: { family: "Dongle", size: 20, }, }, }, y: { grid: { color: "white", }, ticks: { color: "white", font: { family: "Dongle", size: 20, }, }, }, }, }}/>
this all you have to do
redraw={true}
I wanna show tooltips over the line not only on data points.
I also tried the chartjs-plugin-crosshair but it doesn't work in V3 of chartjs.
You can write a custom implementation for V3 for it:
// Options for the indicators
const indicatorOptions = {
radius: 4,
borderWidth: 1,
borderColor: 'red',
backgroundColor: 'transparent'
};
// Override getLabelAndValue to return the interpolated value
const getLabelAndValue = Chart.controllers.line.prototype.getLabelAndValue;
Chart.controllers.line.prototype.getLabelAndValue = function(index) {
if (index === -1) {
const meta = this.getMeta();
const pt = meta._pt;
const vScale = meta.vScale;
return {
label: 'interpolated',
value: vScale.getValueForPixel(pt.y)
};
}
return getLabelAndValue.call(this, index);
}
// The interaction mode
Chart.Interaction.modes.interpolate = function(chart, e, option) {
const x = e.x;
const items = [];
const metas = chart.getSortedVisibleDatasetMetas();
for (let i = 0; i < metas.length; i++) {
const meta = metas[i];
const pt = meta.dataset.interpolate({
x
}, "x");
if (pt) {
const element = new Chart.elements.PointElement({ ...pt,
options: { ...indicatorOptions
}
});
meta._pt = element;
items.push({
element,
index: -1,
datasetIndex: meta.index
});
} else {
meta._pt = null;
}
}
return items;
};
// Plugin to draw the indicators
Chart.register({
id: 'indicators',
afterDraw(chart) {
const metas = chart.getSortedVisibleDatasetMetas();
for (let i = 0; i < metas.length; i++) {
const meta = metas[i];
if (meta._pt) {
meta._pt.draw(chart.ctx);
}
}
},
afterEvent(chart, args) {
if (args.event.type === 'mouseout') {
const metas = chart.getSortedVisibleDatasetMetas();
for (let i = 0; i < metas.length; i++) {
metas[i]._pt = null;
}
args.changed = true;
}
}
})
var ctx = document.getElementById("myChart").getContext("2d");
var chart = new Chart(ctx, {
type: "line",
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
fill: true,
label: "My First dataset",
backgroundColor: "rgba(132, 0, 0, 1)",
borderColor: "rgb(255, 99, 132)",
data: [0, 10, 5, 2, 20, 30, 45]
},
{
data: [30, 40, 50],
label: 'My Second Dataset',
fill: true,
backgroundColor: "lightgreen",
borderColor: "green"
}
]
},
options: {
interaction: {
mode: "interpolate",
intersect: false,
axis: "x"
},
plugins: {
tooltip: {
displayColors: false,
}
}
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.js"></script>
<h1>Interpolating line values</h1>
<div class="myChartDiv">
<canvas id="myChart" width="600" height="400"></canvas>
</div>
The following combination of chartjs-plugin-crosshair and chart.js seems to be working fine for me.
"chart.js": "^3.4.0",
"chartjs-plugin-crosshair": "^1.2.0"
I am initiating the Chart object like below:
Chart.register(CrosshairPlugin);
Which can be used properly in an useEffect block:
useEffect(() =>
Chart.register(CrosshairPlugin);
return () => {
Chart.unregister(CrosshairPlugin);
};
}, []);
And then you can pass the options of the chart like below:
{
...,
options: {
plugins: {
crosshair: {
line: {
color: "#d1d1d1",
width: 1,
},
sync: {
enabled: true,
group: 1,
suppressTooltips: false,
},
zoom: {
enabled: false,
},
}
}
}
}
Note that the configurations above, will keep the crosshair pointer synced over all your charts rendered on the same component. You may need to change the behavior here.
you can use chartjs-plugin-crosshair
function generateDataset(shift, label, color) {
var data = [];
var x = 0;
while (x < 30) {
data.push({
x: x,
y: Math.sin(shift + x / 3)
});
x += Math.random();
}
var dataset = {
backgroundColor: color,
borderColor: color,
showLine: true,
fill: false,
pointRadius: 2,
label: label,
data: data,
lineTension: 0,
interpolate: true
};
return dataset;
}
var chart1 = new Chart(document.getElementById("chart").getContext("2d"), {
type: "scatter",
options: {
plugins: {
crosshair: {
sync: {
enabled: false
},
},
tooltip: {
animation: false,
mode: "interpolate",
intersect: false,
callbacks: {
title: function(a, d) {
return a[0].element.x.toFixed(2);
},
label: function(d) {
return (
d.chart.data.datasets[d.datasetIndex].label + ": " + d.element.y.toFixed(2)
);
}
}
}
},
scales: {
x: {
min: 2,
max: 28
}
}
},
data: {
datasets: [
generateDataset(0, "A", "red")
]
}
});
<script src="https://cdn.jsdelivr.net/npm/moment#2.27.0/moment.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.4.0/dist/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment#0.1.1"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-crosshair#1.2.0/dist/chartjs-plugin-crosshair.min.js"></script>
<canvas id="chart" height="100"></canvas>
https://jsfiddle.net/Lb0k2sqx/1/
I am trying to find a way in the apex chart. By which if user zoom on the year graph then the user should be able to get month data when they zoom on month data this should show the day data.
But I am not able to figure out if its possible in apex chart or not.
This is how my graph look like right now.
import React from "react";
import ReactApexChart from "react-apexcharts";
interface StackedGraphProps {}
type SeriesType = {
name: string;
data: number[];
};
interface StackedGraphState {
series: SeriesType[];
options: any;
}
class StackedBarGraph extends React.Component<
StackedGraphProps,
StackedGraphState
> {
constructor(props: any) {
super(props);
this.state = {
series: [
{
name: "Marine Sprite",
data: [44, 55, 41, 37, 22, 43, 21],
},
{
name: "Striking Calf",
data: [53, 32, 33, 52, 13, 43, 32],
},
{
name: "Tank Picture",
data: [12, 17, 11, 9, 15, 11, 20],
},
],
options: {
chart: {
events: {
zoomed: function (chartContext: any, { xaxis, yaxis }) {
console.log("xAxis", xaxis, yaxis);
},
selection: function (chartContext: any, { xaxis, yaxis }) {
console.log("Selecton", xaxis, yaxis);
},
dataPointSelection: (
event: any,
chartContext: any,
config: any
) => {
console.log("datapoint", chartContext, config);
},
},
zoom: {
enabled: true,
type: "x",
autoScaleYaxis: false,
// zoomedArea: {
// fill: {
// color: "#90CAF9",
// opacity: 0.4,
// },
// stroke: {
// color: "#0D47A1",
// opacity: 0.4,
// width: 1,
// },
// },
},
type: "bar",
height: 350,
stacked: true,
},
toolbar: {
show: true,
},
plotOptions: {
bar: {
horizontal: false,
},
},
stroke: {
width: 1,
colors: ["#fff"],
},
grid: {
row: {
colors: ["#fff", "#f2f2f2f2"],
},
},
title: {
text: "",
},
xaxis: {
tickPlacement: "on",
categories: [2008, 2009, 2010, 2011, 2012, 2013, 2014],
labels: {
formatter: function (val: any) {
return val + "K";
},
},
},
yaxis: {
title: {
text: undefined,
},
},
tooltip: {
y: {
formatter: function (val: any) {
return val + "K";
},
},
},
fill: {
opacity: 1,
},
legend: {
position: "top",
horizontalAlign: "left",
offsetX: 40,
},
},
};
}
render() {
return (
<div id="chart">
<ReactApexChart
zoomEnabled={true}
options={this.state.options}
series={this.state.series}
type="bar"
height={350}
/>
</div>
);
}
}
export default StackedBarGraph;