UNPKG

react-meteo-chart

Version:

pre alpha of meteo chart

518 lines (484 loc) 15.6 kB
import React, { Component, PureComponent } from "react"; import BasicChart, { rgbToHex } from "../BasicChart"; import LeBasicChart from "../LeBasicChart"; import Candlestick from "../Candlestick"; import sizeMe from "react-sizeme"; import { FlexAmsLegend as AmsLegend, TempLegend, WindSpeedLegend, PressureLegend, BarTendencyLegend, PrecipLegend, COLORS, } from "./AmsLegend"; import { AmsCrossFormat, EmptyCrossFormat } from "./AmsCrossFormat"; import GridDates, { fontSize } from "../GridDates"; import { XYPlot, FlexibleWidthXYPlot, FlexibleXYPlot, CustomSVGSeries, YAxis, XAxis, VerticalBarSeries, VerticalGridLines, HorizontalGridLines, LineSeries, LineSeriesCanvas, LineMarkSeries, MarkSeries, DecorativeAxis, VerticalRectSeries, Crosshair, } from "react-vis"; import moment from "moment"; 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 AmsChart extends PureComponent { constructor(props) { super(props); this.state = { cross: [], showcross: false, showSpeedCross: false, showTempCross: false, showBarometricCross: false, showPrecipCross: false, showPressCross: false, wind: true, temp: true, tendency: true, precipit: true, normalPress: true, press: true, width: 0, }; } componentWillUnmount() { // window.removeEventListener("resizedir", e => // this.setState({ width: document.getElementById("dirwind").clientWidth }) // ); } setTooltip = (value, crossName) => { let { superArr } = this.props; let xx = superArr.map((d) => Math.max.apply( Math, d .filter((s) => s.y !== null) .map((x) => x.x) .filter((x) => { return x <= value.x; }) ) ); let cress = superArr.map((d, indx) => d.filter((asd, id) => asd.x == xx[indx]) ); // if (cress[3] && cress[3].length > 1) // cress[3].sort((a, b) => b.y - a.y)[0].y; this.setState({ cross: superArr.map((d, indx) => ({ x: value.x, y: cress[indx][0] ? indx == 4 ? cress[indx][0].z : cress[indx][0].y : null, })), [crossName]: true, }); }; render() { const { width } = this.props.size; let { superArr, dateFrom, dateTo, plotHeight = 270, plotWidth = width, } = this.props; 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") ); let gridDates = GridDates(dateFrom, dateTo); const setVal = (data, name) => { this.setState({ [name]: !data }); }; if (this.props.arrows) { var arrowsArr = superArr[4].filter( (e, i) => i % Math.trunc((150 * superArr[4].length) / width) === 0 ); } const { cross, showcross, showSpeedCross, showTempCross, showBarometricCross, showPrecipCross, showPressCross, wind, temp, tendency, precipit, normalPress, press, } = this.state; const isAdmin = this.props.isAdmin; const animated = this.props.animated; return ( <> <BasicChart opacity={this.props.opacity} superArr={superArr} dateFrom={dateFrom} dateTo={dateTo} plotHeight={plotHeight > 130 ? plotHeight : 130} plotWidth={plotWidth} > <FlexibleXYPlot // width={plotWidth} height={plotHeight > 130 ? plotHeight : 130} className="mainPlot" // yPadding={35} margin={{ left: 65 }} xDomain={[domainFrom, domainTo]} onMouseLeave={() => { this.setState({ showPressCross: false }); }} > <YAxis left={0} tickTotal={5} tickFormat={(v) => (v !== null ? `${v} гПа` : "")} /> {/* <VerticalGridLines /> */} <HorizontalGridLines /> {/* Normalized pressure array */} {superArr[6] && normalPress && ( <LineMarkSeries getNull={(d) => d.y !== null} data={superArr[6]} stroke={`${COLORS.normalizedPressureColor}`} size="1" curve={"curveMonotoneX"} onNearestX={(value, { index }) => { this.setTooltip(value, "showPressCross"); }} /> )} {/* Pressure array */} {superArr[5] && press && ( <LineMarkSeries getNull={(d) => d.y !== null} data={superArr[5]} stroke={`${COLORS.pressureColor}`} size="1" curve={"curveMonotoneX"} /> )} {superArr[2] && superArr[2].length > 0 && press && ( <Candlestick className="mainPlot" getNull={(d) => d.y !== null} colorType="literal" opacityType="literal" stroke="#000000" // fill="#ff0000" data={superArr[2]} /> )} {!animated && ( <Crosshair values={cross}> {showPressCross && !animated ? ( <AmsCrossFormat superArr={superArr} cross={cross} /> ) : ( <EmptyCrossFormat /> )} </Crosshair> )} </FlexibleXYPlot> {isAdmin && <PressureLegend setVal={setVal} isAdmin={isAdmin} />} </BasicChart> <BasicChart opacity={this.props.opacity} superArr={superArr} dateFrom={dateFrom} dateTo={dateTo} // extremum={extremumArr[0]} plotHeight={plotHeight > 180 ? plotHeight : 180} plotWidth={plotWidth} > <FlexibleXYPlot // width={plotWidth} height={plotHeight > 180 ? plotHeight : 180} className="mainPlot" xDomain={[domainFrom, domainTo]} margin={{ left: 65 }} yPadding={15} // getY={e => console.log(e)} onMouseLeave={() => { this.setState({ showSpeedCross: false }); }} > <YAxis left={0} tickFormat={(v) => (v !== null && v >= 0 ? `${v} м/с` : "")} /> {/* <VerticalGridLines /> */} <HorizontalGridLines /> {/* Wind speed array */} {superArr[0] && wind && ( <CustomSVGSeries className="directionPlot" data={arrowsArr ? arrowsArr : superArr[4]} getNull={(d) => d.y !== null} /> )} {superArr[0] && wind && ( <LineMarkSeries ref={(lms) => { this.lms = lms; }} getNull={(d) => d.y !== null} data={superArr[0]} curve={"linear"} //find solution stroke={`${COLORS.widSpeedColor}`} size="1" onNearestX={(value, { index }) => { this.setTooltip(value, "showSpeedCross"); }} /> )} {!animated && ( <Crosshair values={cross}> {showSpeedCross && !animated ? ( <AmsCrossFormat superArr={superArr} cross={cross} /> ) : ( <EmptyCrossFormat /> )} </Crosshair> )} </FlexibleXYPlot> {isAdmin && <WindSpeedLegend setVal={setVal} isAdmin={true} />} </BasicChart> <BasicChart opacity={this.props.opacity} superArr={superArr} dateFrom={dateFrom} dateTo={dateTo} plotHeight={plotHeight > 130 ? plotHeight : 130} plotWidth={plotWidth} > <FlexibleXYPlot // width={plotWidth} // height={plotHeight > 120 ? plotHeight : 120} className="mainPlot" margin={{ left: 65 }} yPadding={20} xDomain={[domainFrom, domainTo]} onMouseLeave={() => { this.setState({ showTempCross: false }); }} > <YAxis left={0} tickTotal={5} tickFormat={(v) => (v !== null ? `${v} C°` : "")} /> {/* <VerticalGridLines /> */} <HorizontalGridLines /> {/* Temperature array */} {superArr[1] && temp && ( <LineMarkSeries getNull={(d) => d.y !== null} data={superArr[1]} style={{ strokeWidth: "3" }} stroke={`${COLORS.temperatureColor}`} size="1" // onSeriesMouseOver={onNearestX} onNearestX={(value, { index }) => { this.setTooltip(value, "showTempCross"); }} /> )} {!animated && ( <Crosshair values={cross}> {showTempCross ? ( <AmsCrossFormat superArr={superArr} cross={cross} /> ) : ( <EmptyCrossFormat /> )} </Crosshair> )} </FlexibleXYPlot> {isAdmin && <TempLegend setVal={setVal} isAdmin={true} />} {isAdmin && <PrecipLegend setVal={setVal} isAdmin={true} />} </BasicChart> {superArr[3] !== undefined && superArr[3].length > 0 && precipit ? ( <div style={{ // border: "1px solid #7d9cb8", backgroundColor: rgbToHex(255, 255, 255, this.props.opacity), }} > <FlexibleXYPlot // width={plotWidth} margin={{ left: 65 }} height={plotHeight > 130 ? plotHeight : 130} className="precipitationPlot" xDomain={[domainFrom, domainTo]} xType="time" yDomain={ superArr[3].length > 0 ? Math.max.apply( Math, superArr[3].map((d) => d.y) ) == 0 ? [0, 5] : [ 0, Math.max.apply( Math, superArr[3].map((d) => d.y) ), ] : [0, 5] } // scale="1" // dontCheckIfEmpty={true} onMouseLeave={() => { this.setState({ showPrecipCross: false }); }} > <YAxis left={0} // tickTotal={5} 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} /> <VerticalGridLines /> <HorizontalGridLines /> {/* Precipitation array */} <MiddleVerticalRectSeries className="precipitBars" getNull={(d) => d.y !== null} data={superArr[3]} fill={`${COLORS.precipitationColor}`} stroke={`#000000`} // scale="2" style={ { // strokeWidth: 10 } } onNearestX={(value, { index }) => { this.setTooltip(value, "showPrecipCross"); }} /> {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" }, }} /> ); })} {!animated && ( <Crosshair values={cross}> {showPrecipCross ? ( <AmsCrossFormat superArr={superArr} cross={cross} /> ) : ( <EmptyCrossFormat /> )} </Crosshair> )} </FlexibleXYPlot> </div> ) : ( <BasicChart opacity={this.props.opacity} superArr={superArr} dateFrom={dateFrom} dateTo={dateTo} plotHeight={plotHeight > 130 ? plotHeight : 130} plotWidth={plotWidth} /> )} {!isAdmin && <AmsLegend setVal={setVal} />} </> ); } } export default sizeMe()(AmsChart);