mirror of
https://github.com/filecoin-project/slate.git
synced 2024-12-27 19:15:26 +03:00
230 lines
5.5 KiB
JavaScript
230 lines
5.5 KiB
JavaScript
import * as React from "react";
|
|
|
|
import CreateChart from "~/components/stats/CreateChart";
|
|
|
|
export default class Chart extends React.Component {
|
|
state = {
|
|
minX: {},
|
|
maxX: {},
|
|
minY: {},
|
|
maxY: {},
|
|
deltaX: {},
|
|
deltaY: {},
|
|
bufferX: {},
|
|
ticks: [],
|
|
xLabel: {},
|
|
yLabel: {},
|
|
organizedData: [],
|
|
};
|
|
|
|
componentDidMount() {
|
|
this.getXLabel();
|
|
this.getYLabel();
|
|
this.getMinX();
|
|
this.getMaxX();
|
|
this.getMinY();
|
|
this.getMaxY();
|
|
this.sepCategories();
|
|
this.getTicks();
|
|
}
|
|
|
|
//Set Axis Labels
|
|
getXLabel() {
|
|
const { data } = this.props;
|
|
let allLabels = Object.keys(data[0]);
|
|
this.setState({
|
|
xLabel: allLabels[0],
|
|
});
|
|
}
|
|
|
|
getYLabel() {
|
|
const { data } = this.props;
|
|
let allLabels = Object.keys(data[0]);
|
|
this.setState({
|
|
yLabel: allLabels[2],
|
|
});
|
|
}
|
|
|
|
//Get Min & Max X
|
|
getMinX() {
|
|
const { data } = this.props;
|
|
let dates = data.sort(this.sortDates("date"));
|
|
this.setState({
|
|
minX: dates[0].date,
|
|
});
|
|
return dates[0].date;
|
|
}
|
|
|
|
getMaxX() {
|
|
const { data } = this.props;
|
|
let dates = data.sort(this.sortDates("date"));
|
|
this.setState({
|
|
maxX: dates[data.length - 1].date,
|
|
});
|
|
return dates[data.length - 1].date;
|
|
}
|
|
|
|
//Get Min & Max Y Values
|
|
getMinY() {
|
|
const { data } = this.props;
|
|
let y = {};
|
|
let values = data.map((x) => {
|
|
y = x.value;
|
|
return y;
|
|
});
|
|
|
|
this.setState({
|
|
//Spread operator is slow!! refactor to use for loop or .reduce
|
|
minY: Math.min(...values),
|
|
});
|
|
return Math.min(...values);
|
|
}
|
|
|
|
getMaxY() {
|
|
const { data } = this.props;
|
|
let y = {};
|
|
let values = data.map((x) => {
|
|
y = x.value;
|
|
return y;
|
|
});
|
|
this.setState({
|
|
maxY: Math.max(...values),
|
|
});
|
|
return Math.max(...values);
|
|
}
|
|
|
|
getTicks() {
|
|
const { data } = this.props;
|
|
const { maxTicks } = this.props;
|
|
const { xWall } = this.props;
|
|
const maxX = Date.parse(this.getMaxX());
|
|
const minX = Date.parse(this.getMinX());
|
|
let diffX = maxX - minX;
|
|
let dX = xWall / diffX;
|
|
let bufferX = (600 - xWall) / 2;
|
|
const allTicks = [];
|
|
const dates = data.map((z) => {
|
|
let t = {
|
|
date: "",
|
|
x: "",
|
|
};
|
|
t.date = z.date;
|
|
t.x = Math.floor((Date.parse(z.date) - minX) * dX + bufferX);
|
|
return t;
|
|
});
|
|
dates.sort(this.sortDates("x"));
|
|
const delta = Math.ceil(dates.length / maxTicks);
|
|
for (let i = 0; i < dates.length; i = i + delta) {
|
|
allTicks.push(dates[i]);
|
|
}
|
|
this.setState((prevState) => ({
|
|
ticks: [...prevState.ticks, allTicks],
|
|
}));
|
|
}
|
|
|
|
sortDates(key) {
|
|
return function innerSort(a, b) {
|
|
const varA = typeof a[key] === "string" ? a[key].toUpperCase() : a[key];
|
|
const varB = typeof b[key] === "string" ? b[key].toUpperCase() : b[key];
|
|
let comparison = 0;
|
|
if (varA > varB) {
|
|
comparison = 1;
|
|
} else if (varA < varB) {
|
|
comparison = -1;
|
|
}
|
|
return comparison;
|
|
};
|
|
}
|
|
//Organize Categories Into Seperate Arrays within a Larger Array
|
|
sepCategories() {
|
|
const { data } = this.props;
|
|
if (data) {
|
|
const oData = [];
|
|
const category1 = [];
|
|
const category2 = [];
|
|
const category3 = [];
|
|
|
|
data.forEach((data) => {
|
|
if (data.category == "1") {
|
|
category1.push(data);
|
|
}
|
|
if (data.category == "2") {
|
|
category2.push(data);
|
|
}
|
|
if (data.category == "3") {
|
|
category3.push(data);
|
|
}
|
|
});
|
|
|
|
oData.push(category1);
|
|
oData.push(category2);
|
|
oData.push(category3);
|
|
|
|
this.setState((prevState) => ({
|
|
organizedData: [...prevState.organizedData, oData],
|
|
}));
|
|
this.createCoordinates(oData);
|
|
}
|
|
}
|
|
|
|
//Map through arrays of arrays of an array of objects and add x and y key/value pairs to each object.
|
|
createCoordinates(z) {
|
|
const { yCeiling } = this.props;
|
|
const { xWall } = this.props;
|
|
const oData = z;
|
|
const maxX = Date.parse(this.getMaxX());
|
|
const minX = Date.parse(this.getMinX());
|
|
const maxY = this.getMaxY();
|
|
const minY = this.getMinY();
|
|
let diffY = maxY - minY;
|
|
let diffX = maxX - minX;
|
|
let dY = yCeiling / diffY;
|
|
let dX = xWall / diffX;
|
|
let bufferY = (600 - yCeiling) / 2;
|
|
let bufferX = (600 - xWall) / 2;
|
|
|
|
this.setState({ deltaX: dX });
|
|
this.setState({ deltaY: dY });
|
|
this.setState({ bufferX });
|
|
|
|
for (let group of oData) {
|
|
for (let i = 0; i < group.length; i++) {
|
|
if (group[i].category) {
|
|
let yPoints = group.map((y) => {
|
|
let yValue = Math.floor((y.value - minY) * dY);
|
|
y["y"] = yCeiling - yValue + bufferY;
|
|
});
|
|
|
|
let xPoints = group.map((x) => {
|
|
let xValue = Math.floor((Date.parse(x.date) - minX) * dX);
|
|
x["x"] = xValue + bufferX;
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
render() {
|
|
if (this.state.organizedData.length) {
|
|
return (
|
|
<React.Fragment>
|
|
<CreateChart
|
|
minX={this.state.minX}
|
|
maxX={this.state.maxX}
|
|
minY={this.state.minY}
|
|
maxY={this.state.maxY}
|
|
deltaX={this.state.deltaX}
|
|
deltaY={this.state.deltaY}
|
|
ticks={this.state.ticks}
|
|
xLabel={this.state.xLabel}
|
|
yLabel={this.state.yLabel}
|
|
organizedData={this.state.organizedData}
|
|
/>
|
|
</React.Fragment>
|
|
);
|
|
} else {
|
|
return <React.Fragment></React.Fragment>;
|
|
}
|
|
}
|
|
}
|