react-meteo-chart
Version:
pre alpha of meteo chart
304 lines (284 loc) • 9.05 kB
JSX
import React from "react";
import LevelsChart from "../Levels/LevelsChart";
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 LEVELS_DATAPLOT_QUERY = gql`
query(
$token: String!
$stationId: String!
$since: DateTime
$to: DateTime
$typeName: String!
$maxPoints: Int
) {
levelsPlotData(
token: $token
stationId: $stationId
typeName: $typeName
since: $since
to: $to
maxPoints: $maxPoints
)
}
`;
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 = ["LW", "TW"];
class LevelsChartGen 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"),
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"),
typeList: [],
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="levelsGraph">
{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: LEVELS_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.levelsPlotData.map((s) => ({
x: s[0] * 1000,
y: s[1] !== null ? s[1] : "",
}));
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>
<LevelsChart
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 LevelsChartGen;