react-meteo-chart
Version:
pre alpha of meteo chart
488 lines (465 loc) • 14.9 kB
JSX
import React, { Component } from "react";
import BasicChart, { rgbToHex } from "../BasicChart";
import moment from "moment";
import {
LineSeries,
FlexibleXYPlot,
Crosshair,
HorizontalGridLines,
XAxis,
YAxis,
VerticalGridLines,
DecorativeAxis,
FlexibleWidthXYPlot,
VerticalRectSeries,
Borders,
} from "react-vis";
import {
PluvioLegend1h,
PluvioLegend3h,
PluvioLegend6h,
PluvioLegend24h,
FullPluvioLegend,
COLORS,
} from "./PluvioLegend";
import sizeMe from "react-sizeme";
import GridDates from "../GridDates";
import { PluvioCrossFormat, EmptyCrossFormat } from "./PluvioCrossFormat";
const gaps = [
[1, "h"],
[3, "h"],
[6, "h"],
[24, "h"],
];
const legaps = [24, 8, 4, 1];
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 PluvioChart extends Component {
state = {
cross: null,
dailySum: true,
showhCross: false,
show3hCross: false,
show6hCross: false,
show24hCross: false,
hsum: true,
hsum3: true,
hsum6: true,
hsum24: true,
data: null,
};
getCrossTime = (value, span, index) => {
if (!value) return null;
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);
};
setTooltip = (value, crossName, index) => {
const day = 86400000;
let { superArr } = this.props;
let xx = superArr.map((d) =>
Math.max.apply(
Math,
d
.map((x) => x.x0)
.filter((x) => {
return x < value.x;
})
)
);
let cress = superArr.map((d, indx) =>
d.filter((asd, id) => asd.x0 == xx[indx])
);
this.setState({
cross: superArr.map((d, indx) => ({
x: (value.x + value.x0) / 2,
y: cress[indx][0] ? cress[indx][0].y : null,
})),
data: superArr.map((d, indx) => ({
x: this.getCrossTime(cress[indx][0], day / legaps[indx], index),
info: cress[indx][0] ? cress[indx][0] : null,
})),
[crossName]: true,
});
};
render() {
const { width } = this.props.size;
let {
superArr,
dateFrom,
dateTo,
plotHeight = 270,
plotWidth = width,
} = this.props;
const {
cross,
dailySum,
showhCross,
show3hCross,
show6hCross,
show24hCross,
hsum,
hsum3,
hsum6,
hsum24,
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}
>
{superArr[0] && hsum && (
<FlexibleXYPlot
height={plotHeight > 120 ? plotHeight : 120}
margin={{ left: 65 }}
// width={plotWidth}
className="dailySumPlot"
onMouseLeave={() => {
this.setState({ showhCross: false });
}}
xType="time"
xDomain={[domainFrom, domainTo]}
yDomain={
Math.max.apply(
Math,
superArr[0].map((d) => d.y)
) == 0
? [0, 5]
: [
0,
Math.max.apply(
Math,
superArr[0].map((d) => d.y)
),
]
}
>
<YAxis left={0} tickFormat={(v) => (v >= 0 ? `${v} мм` : "")} />
<HorizontalGridLines />
{/* <VerticalGridLines /> */}
<MiddleVerticalRectSeries
// getNull={d => d.y !== null}
data={superArr[0]}
fill={`${COLORS.Sum1hColor}`}
stroke={`${COLORS.Sum1hStrokeColor}`}
onNearestX={(value, { index }) => {
this.setTooltip(value, "showhCross", index);
}}
/>
<Crosshair values={cross}>
{showhCross ? (
<PluvioCrossFormat
superArr={superArr}
cross={cross}
data={data}
indx={0}
/>
) : (
<EmptyCrossFormat />
)}
</Crosshair>
</FlexibleXYPlot>
)}
{isAdmin && <PluvioLegend1h setVal={setVal} isAdmin />}
</BasicChart>
<BasicChart
opacity={this.props.opacity}
superArr={superArr}
dateFrom={dateFrom}
dateTo={dateTo}
plotHeight={plotHeight > 120 ? plotHeight : 120}
plotWidth={plotWidth}
>
{superArr[1] && hsum3 && (
<FlexibleXYPlot
height={plotHeight > 120 ? plotHeight : 120}
// width={plotWidth}
className="dailySumPlot"
margin={{ left: 65 }}
onMouseLeave={() => {
this.setState({ show3hCross: false });
}}
xType="time"
xDomain={[domainFrom, domainTo]}
yDomain={
Math.max.apply(
Math,
superArr[1].map((d) => d.y)
) == 0
? [0, 5]
: [
0,
Math.max.apply(
Math,
superArr[1].map((d) => d.y)
),
]
}
>
<YAxis left={0} tickFormat={(v) => (v >= 0 ? `${v} мм` : "")} />
<HorizontalGridLines />
{/* <VerticalGridLines /> */}
<MiddleVerticalRectSeries
getNull={(d) => d.y !== null}
data={superArr[1]}
fill={`${COLORS.Sum3hColor}`}
stroke={`${COLORS.Sum3hStrokeColor}`}
onNearestX={(value, { index }) => {
this.setTooltip(value, "show3hCross", index);
}}
/>
<Crosshair values={cross}>
{show3hCross ? (
<PluvioCrossFormat
superArr={superArr}
cross={cross}
data={data}
indx={1}
/>
) : (
<EmptyCrossFormat />
)}
</Crosshair>
</FlexibleXYPlot>
)}
{isAdmin && <PluvioLegend3h setVal={setVal} isAdmin />}
</BasicChart>
<BasicChart
opacity={this.props.opacity}
superArr={superArr}
dateFrom={dateFrom}
dateTo={dateTo}
plotHeight={plotHeight > 120 ? plotHeight : 120}
plotWidth={plotWidth}
>
{superArr[2] && hsum6 && (
<FlexibleXYPlot
height={plotHeight > 120 ? plotHeight : 120}
// width={plotWidth}
margin={{ left: 65 }}
className="dailySumPlot"
onMouseLeave={() => {
this.setState({ show6hCross: false });
}}
xType="time"
xDomain={[domainFrom, domainTo]}
yDomain={
Math.max.apply(
Math,
superArr[2].map((d) => d.y)
) == 0
? [0, 5]
: [
0,
Math.max.apply(
Math,
superArr[2].map((d) => d.y)
),
]
}
>
<YAxis left={0} tickFormat={(v) => (v >= 0 ? `${v} мм` : "")} />
<HorizontalGridLines />
{/* <VerticalGridLines /> */}
<MiddleVerticalRectSeries
getNull={(d) => d.y !== null}
data={superArr[2]}
fill={`${COLORS.Sum6hColor}`}
stroke={`${COLORS.Sum6hStrokeColor}`}
onNearestX={(value, { index }) => {
this.setTooltip(value, "show6hCross", index);
}}
/>
<Crosshair values={cross}>
{show6hCross ? (
<PluvioCrossFormat
superArr={superArr}
cross={cross}
data={data}
indx={2}
/>
) : (
<EmptyCrossFormat />
)}
</Crosshair>
</FlexibleXYPlot>
)}
{isAdmin && <PluvioLegend6h setVal={setVal} isAdmin />}
{isAdmin && <PluvioLegend24h setVal={setVal} isAdmin />}
</BasicChart>
{hsum24 && superArr[3] ? (
<div
style={{
// border: "1px solid #7d9cb8",
backgroundColor: rgbToHex(255, 255, 255, this.props.opacity),
}}
>
<FlexibleXYPlot
height={plotHeight > 120 ? plotHeight : 120}
// width={plotWidth}
margin={{ left: 65 }}
className="dailySumPlot"
onMouseLeave={() => {
this.setState({ show24hCross: false });
}}
xDomain={[domainFrom, domainTo]}
xType="time"
yDomain={
Math.max.apply(
Math,
superArr[3].map((d) => d.y)
) == 0
? [0, 5]
: [
0,
Math.max.apply(
Math,
superArr[3].map((d) => d.y)
),
]
}
>
<HorizontalGridLines />
<VerticalGridLines />
<YAxis left={0} tickFormat={(v) => (v >= 0 ? `${v} мм` : "")} />
<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}
/>
{/* <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" },
}}
/>
);
})}
<MiddleVerticalRectSeries
getNull={(d) => d.y !== null}
data={superArr[3]}
fill={`${COLORS.Sum24hColor}`}
stroke={`${COLORS.Sum24hStrokeColor}`}
// onNearestX={value => console.log(value)}
onNearestX={(value, { index }) => {
this.setTooltip(value, "show24hCross", index);
}}
/>
<Crosshair values={cross}>
{show24hCross ? (
<PluvioCrossFormat
superArr={superArr}
cross={cross}
data={data}
indx={3}
/>
) : (
<EmptyCrossFormat />
)}
</Crosshair>
</FlexibleXYPlot>
</div>
) : (
<BasicChart
opacity={this.props.opacity}
superArr={superArr}
dateFrom={dateFrom}
dateTo={dateTo}
plotHeight={plotHeight > 120 ? plotHeight : 120}
plotWidth={plotWidth}
/>
)}
{!isAdmin && <FullPluvioLegend setVal={setVal} isAdmin />}
</>
);
}
}
export default sizeMe()(PluvioChart);