UNPKG

react-meteo-chart

Version:

pre alpha of meteo chart

303 lines (284 loc) 9.04 kB
import React from "react"; import PluvioChart from "../Pluvio/PluvioChart"; import { Query, ApolloProvider } from "react-apollo"; import moment from "moment"; import ApolloClient from "apollo-boost"; import ReactLoading from "react-loading"; import gql from "graphql-tag"; import "./style.css"; import Select from "react-select"; const PLUVIO_DATAPLOT_QUERY = gql` query( $token: String! $stationId: String! $since: DateTime $to: DateTime $typeName: String! ) { pluvioPlotData( token: $token stationId: $stationId typeName: $typeName since: $since to: $to ) } `; const ME = gql` query($token: String!) { me(token: $token) { lastLogin } } `; const selecterStyle = { control: (base, state) => ({ ...base, backgroundColor: "ccccff", opacity: 1, height: "12px", width: "100px", border: state.isFocused ? 0 : 0, boxShadow: state.isFocused ? 0 : 0, "&:hover": { border: state.isFocused ? 0 : 0, }, }), dropdownIndicator: (e) => ({ ...e, color: "#646464", transform: "rotate(180deg)", }), menu: (e) => ({ ...e, color: "#00000", width: "100px", backgroundColor: "#ffFffF", }), }; const zooms = [ [1, "d", "День"], [3, "d", "3 Дня"], [7, "d", "Неделя"], [14, "d", "2 Недели"], ]; const selectValues = [ { label: "День", value: 0 }, { label: "3 Дня", value: 1 }, { label: "Неделя", value: 2 }, { label: "2 Недели", value: 3 }, ]; const types = ["hsum", "3hsum", "6hsum", "24hsum"]; class PluvioChartGen extends React.Component { constructor(props) { super(props); this.state = { chunks: [], isLoadingChunks: [], zoom: 0, since: this.props.dateFrom ? moment(this.props.dateFrom).utc().format("YYYY-MM-DDTHH:mm:ss") : null, to: moment(this.props.dateTo).utc().format("YYYY-MM-DDTHH:mm:ss"), deep: true, stationId: this.props.stationId, loadMessage: this.props.loadMessage !== undefined ? this.props.loadMessage : true, }; this.deep = true; this.apollo = new ApolloClient({ uri: this.props.client, }); } componentDidUpdate() { if ( this.state.to !== moment(this.props.dateTo).utc().format("YYYY-MM-DDTHH:mm:ss") && this.props.dateTo ) { this.setState({ to: moment(this.props.dateTo).utc().format("YYYY-MM-DDTHH:mm:ss"), }); this.deep = true; } if ( this.state.since !== moment(this.props.dateFrom).utc().format("YYYY-MM-DDTHH:mm:ss") && this.props.dateFrom ) { this.setState({ since: moment(this.props.dateFrom).utc().format("YYYY-MM-DDTHH:mm:ss"), }); this.deep = true; } if (this.props.stationId !== this.state.stationId) { this.setState({ stationId: this.props.stationId, }); this.deep = true; } } render() { const variables = { token: this.props.token, stationId: this.state.stationId, since: this.state.since ? this.state.since : moment(this.props.dateTo) .utc() .add(-zooms[this.state.zoom][0], zooms[this.state.zoom][1]) .format("YYYY-MM-DDTHH:mm:ss"), to: moment(this.props.dateTo).utc().format("YYYY-MM-DDTHH:mm:ss"), typeName: "24hsum", maxPoints: this.props.maxPoints, }; if (this.props.doneLoading) { this.props.doneLoading( this.state.isLoadingChunks.filter((d) => d == false).length == 0 && this.state.isLoadingChunks.length > 0 ); } return ( <ApolloProvider client={this.apollo}> <div className="pluvioGraph"> {this.deep && ( <Query query={ME} variables={{ token: variables.token }} partialRefetch={true} > {({ loading, error, data: plotdata, refetch, client }) => { if (loading) return <div />; if (error) return setTimeout(() => refetch(), 5000); this.deep = false; types.forEach((t, indx) => { let req = client.query({ query: PLUVIO_DATAPLOT_QUERY, variables: { token: variables.token, stationId: variables.stationId, typeName: t, since: variables.since, to: variables.to, maxPoints: this.props.maxPoints, }, }); setTimeout(() => this.setState((state) => { let chunk = false; const isLoadingChunks = (state.isLoadingChunks[ indx ] = chunk); return isLoadingChunks; }) ); req.then((data) => { if (this.props.doneLoading) this.props.doneLoading( this.state.isLoadingChunks.filter((d) => d == false) .length > 0 ); setTimeout(() => this.setState((state) => { let chunk = []; chunk = data.data.pluvioPlotData.map((s) => ({ x0: s[0] * 1000, x: s[1] * 1000, y: s[2] !== null ? s[2] : "", })); const chunks = (state.chunks[indx] = chunk); return chunks; }) ); setTimeout(() => this.setState((state) => { let chunk = true; const isLoadingChunks = (state.isLoadingChunks[ indx ] = chunk); return isLoadingChunks; }) ); }); }); return null; }} </Query> )} {this.state.isLoadingChunks.filter((d) => d == false).length > 0 && this.state.loadMessage && ( <div style={{ display: "flex", justifyContent: "center", alignContent: "center", alignItems: "center", flexDirection: "column", fontSize: "17px", height: "100%", }} > <ReactLoading type="balls" color="#333333" height={25} width={50} />{" "} <p> Загрузка графиков </p> </div> )} <div> <PluvioChart opacity={this.props.opacity} superArr={this.state.chunks} plotHeight={this.props.height} dateFrom={variables.since} dateTo={variables.to} isAdmin={this.props.isAdmin} /> <div style={{ marginTop: "-40px", width: "100px", }} > {!this.props.isAdmin && ( <Select theme={(theme) => ({ ...theme, borderRadius: 1, spacing: { baseUnit: 2, controlHeight: 30, menuGutter: 2, }, colors: { ...theme.colors, primary: "#cee0eb", neutral0: "#000000", }, })} isSearchable={false} // opacity={10} onChange={(option) => this.state.zoom !== option.value ? (this.setState({ zoom: option.value }), (this.deep = true)) : "" } placeholder={""} value={selectValues[this.state.zoom]} menuPlacement="top" menuPosition="fixed" styles={selecterStyle} options={selectValues} /> )} </div> </div> </div>{" "} </ApolloProvider> ); } } export default PluvioChartGen;