react-meteo-chart
Version:
pre alpha of meteo chart
349 lines (320 loc) • 10.5 kB
JSX
import React, { Component } from "react";
import BasicChart, { rgbToHex } from "../BasicChart";
import moment from "moment";
import {
LineSeries,
LineMarkSeries,
MarkSeries,
FlexibleXYPlot,
Crosshair,
HorizontalGridLines,
XAxis,
YAxis,
VerticalGridLines,
DecorativeAxis,
FlexibleWidthXYPlot,
VerticalRectSeries,
Borders,
} from "react-vis";
import { LegendLW, LegendTWr, FullLevelsLegend, COLORS } from "./LevelsLegend";
import sizeMe from "react-sizeme";
import GridDates from "../GridDates";
import { LevelsCrossFormat, EmptyCrossFormat } from "./LevelsCrossFormat";
const gaps = [
[1, "h"],
[3, "h"],
[6, "h"],
[24, "h"],
];
class MiddleVerticalRectSeries extends VerticalRectSeries {
_handleNearestX = function (event) {
var _props3 = this.props,
onNearestX = _props3.onNearestX,
data = _props3.data;
var minDistance = -Number.POSITIVE_INFINITY;
var value = null;
var valueIndex = null;
var coordinate = this._getXYCoordinateInContainer(event);
var xScaleFn = this._getAttributeFunctor("x");
data.forEach(function (item, i) {
var currentCoordinate = xScaleFn(item);
var newDistance = coordinate.x - currentCoordinate;
if (newDistance <= 0 && newDistance > minDistance) {
minDistance = newDistance;
value = item;
valueIndex = i;
}
});
if (!value) {
return;
}
onNearestX(value, {
innerX: xScaleFn(value),
index: valueIndex,
event: event.nativeEvent,
});
};
}
class LevelsChart extends Component {
state = {
cross: null,
dailySum: true,
showLWCross: false,
showTWCross: false,
show6hCross: false,
show24hCross: false,
LW: true,
TW: true,
hsum6: true,
hsum24: true,
data: null,
};
getCrossTime = (value, span, index) => {
if (value.x - value.x0 < span) {
if (index == 0) return moment.unix(value.x / 1000);
else return moment.unix(value.x0 / 1000).add(span, "ms");
}
return moment.unix(value.x / 1000);
};
render() {
const { width } = this.props.size;
let {
superArr,
dateFrom,
dateTo,
plotHeight = 270,
plotWidth = width,
} = this.props;
const {
cross,
dailySum,
showLWCross,
showTWCross,
LW,
TW,
data,
} = this.state;
let domainFrom = moment(
moment.utc(dateFrom).local().format("YYYY-MM-DDTHH:mm")
);
let domainTo = moment(
moment.utc(dateTo).local().format("YYYY-MM-DD:HH:mm")
);
const day = 86400000;
const dateThreshold = day * 5;
let gridDates = GridDates(dateFrom, dateTo);
const isAdmin = this.props.isAdmin;
const daySpan = moment(dateTo) - moment(dateFrom);
const showDirectionThreshold = day * 30;
const setVal = (data, name) => {
this.setState({ [name]: !data });
};
// const plotHeight = 270;
// const plotWidth = 1400;
return (
<>
<BasicChart
opacity={this.props.opacity}
superArr={superArr}
dateFrom={dateFrom}
dateTo={dateTo}
plotHeight={plotHeight > 120 ? plotHeight : 120}
plotWidth={plotWidth}
>
<FlexibleXYPlot
height={plotHeight > 120 ? plotHeight : 120}
// width={plotWidth}
className="mainPlot"
margin={{ left: 65 }}
onMouseLeave={() => {
this.setState({ showLWCross: false });
}}
// xType="time"
xDomain={[domainFrom, domainTo]}
yPadding={40}
>
<YAxis left={0} tickFormat={(v) => `${v} мм`} />
<HorizontalGridLines />
{/* <VerticalGridLines /> */}
{superArr[0] && LW && (
<LineMarkSeries
getNull={(d) => d.y !== null}
data={superArr[0]}
fill={`${COLORS.LWColor}`}
stroke={`${COLORS.LWColor}`}
curve={"linear"}
size="1"
onNearestX={(value, { index }) => {
let xx = superArr.map((d) =>
Math.max.apply(
Math,
d
.map((x) => x.x)
.filter((x) => {
return x <= value.x;
})
)
);
let cress = superArr.map((d, indx) =>
d.filter((asd, id) => asd.x == xx[indx])
);
this.setState({
cross: superArr.map((d, indx) => ({
x: value.x,
y: cress[indx][0] ? cress[indx][0].y : null,
})),
data: superArr.map((d, indx) => ({
x: this.getCrossTime(value, day / 24, index),
info: cress[indx][0] ? cress[indx][0] : null,
})),
showLWCross: true,
});
}}
/>
)}
<Crosshair values={cross}>
{showLWCross ? (
<LevelsCrossFormat
superArr={superArr}
cross={cross}
data={data}
/>
) : (
<EmptyCrossFormat />
)}
</Crosshair>
</FlexibleXYPlot>
{isAdmin && <LegendLW setVal={setVal} isAdmin />}
{isAdmin && <LegendTWr setVal={setVal} isAdmin />}
</BasicChart>
{superArr[1] !== undefined && superArr[1].length > 0 && TW ? (
<div
style={{
// border: "1px solid #7d9cb8",
backgroundColor: rgbToHex(255, 255, 255, this.props.opacity),
}}
>
<FlexibleXYPlot
height={plotHeight > 120 ? plotHeight : 120}
// width={plotWidth}
className="dailySumPlot"
margin={{ left: 65 }}
onMouseLeave={() => {
this.setState({ showTWCross: false });
}}
xDomain={[domainFrom, domainTo]}
xType="time"
>
<YAxis left={0} tickFormat={(v) => (v ? `${v} C°` : "")} />
<XAxis
tickFormat={(d) =>
moment(d).format("HH:mm") == "00:00"
? ``
: `${moment(d).format("HH:mm")}`
}
tickTotal={width * 0.01}
/>
<XAxis
tickFormat={(d) =>
moment(d).format("HH:mm") == "00:00"
? `${moment(d).format("D.MM")}`
: ``
}
style={{
line: { stroke: "#ADDDE1" },
ticks: { stroke: "#ADDDE1" },
text: {
stroke: "none",
fill: "#000000",
fontWeight: 750,
fontSize: 12,
},
}}
tickTotal={width * 0.01}
/>
<HorizontalGridLines />
<VerticalGridLines />
{/* <YAxis /> */}
{gridDates.map((date) => {
return (
<DecorativeAxis
key={`${date}-axis`}
className="decaxis"
axisDomain={[]}
axisStart={{
x: moment(date.format("YYYY-MM-DD")),
y: 0,
}}
axisEnd={{
x: moment(date.format("YYYY-MM-DD")),
y: 1,
}}
tickTotal={0}
style={{
ticks: { display: "none" },
text: { display: "none" },
}}
/>
);
})}
<LineSeries
getNull={(d) => d.y !== null}
data={superArr[1]}
fill={`${COLORS.TWColor}`}
stroke={`${COLORS.TWColor}`}
onNearestX={(value, { index }) => {
let xx = superArr.map((d) =>
Math.max.apply(
Math,
d
.map((x) => x.x)
.filter((x) => {
return x <= value.x;
})
)
);
let cress = superArr.map((d, indx) =>
d.filter((asd, id) => asd.x == xx[indx])
);
this.setState({
cross: superArr.map((d, indx) => ({
x: value.x,
y: cress[indx][0] ? cress[indx][0].y : null,
})),
data: superArr.map((d, indx) => ({
x: this.getCrossTime(value, day, index),
info: cress[indx][0] ? cress[indx][0] : null,
})),
showTWCross: true,
});
}}
/>
<Crosshair values={cross}>
{showTWCross ? (
<LevelsCrossFormat
superArr={superArr}
cross={cross}
data={data}
/>
) : (
<EmptyCrossFormat />
)}
</Crosshair>
</FlexibleXYPlot>
</div>
) : (
<BasicChart
opacity={this.props.opacity}
superArr={superArr}
dateFrom={dateFrom}
dateTo={dateTo}
plotHeight={plotHeight > 120 ? plotHeight : 120}
plotWidth={plotWidth}
/>
)}
{!isAdmin && <FullLevelsLegend setVal={setVal} isAdmin />}
</>
);
}
}
export default sizeMe()(LevelsChart);