React App: Chart ================= Aim ---- Add chart to display data. Summary -------- .. image:: ../img/reactdraft.png :width: 300 :align: center Install packages ------------------------- .. code-block:: bash npm install d3 --save npm install react-timeseries-charts pondjs --save Code listing ------------- .. code-block:: javascript import React, { Component } from 'react' import './App.css' import {Button, ButtonToolbar, DropdownButton, MenuItem} from 'react-bootstrap/lib' import 'bootstrap/dist/css/bootstrap.css' import 'bootstrap/dist/css/bootstrap-theme.css' import { Charts, ChartContainer, ChartRow, YAxis, LineChart } from 'react-timeseries-charts' import { TimeSeries, TimeRange } from 'pondjs' class App extends Component { constructor(props){ super(props) this.measurementsFilter.bind(this) this.dropdownSelectionHandle.bind(this) this.state={ data: [], pageLoadDate: "", sensorNames: [], sensorLocations: [], sensorMeasurementType: [], temperature: "loading", days: 7, button7: "success", button28: "primary", button365: "primary", focusName: "", timeRange: this.createTimeRange(7), chartXAxisFormat: "day", } } componentDidMount() { this.setState({ pageLoadDate: new Date() }) } componentWillMount() { this.getDataFromApi() } getDataFromApi() { return fetch('/homesensors/api/v1.0/sensor_data', {credentials: 'same-origin'}) .then((response) => response.json()) .then((responseJson) => { this.setState({ data: responseJson.data }, () => this.measurementsFilter(this.state.data, this.state.days)) }) .catch((error) => { console.error(error) }) } measurementsFilter(arrObjects, days) { // copy var data = arrObjects.slice() // convert date for (var j=0; j { return el.dsCollected >= d }) // get sensor attributes (this provides user selections) var names = this.sensorAttrList(filteredArray, "name") var locs = this.sensorAttrList(filteredArray, "location") var mtype = this.sensorAttrList(filteredArray, "measurementType") // filter temp data (hardcode for now) var tempArray = filteredArray.filter(el=> { return el.measurementType === "temp" }) // focus data on user selections var fName = this.focusSensorName(tempArray, this.state.focusName, names) var fAttr = this.focusSensorValue(tempArray, fName) var fValue = fAttr[0] var fDate = fAttr[1] // create timeseries var timeSeries = this.convertFocusDataToTimeseries(tempArray, fName) // save state this.setState({ sensorNames: names, sensorLocations: locs, sensorMeasurementType: mtype, focusName: fName, focusValue: fValue, focusDate: fDate, temperature: tempArray, timeSeries: timeSeries, days: days }) } createTimeRange(days) { var dateNow = new Date().getTime() var datePrev = new Date(new Date().setDate(new Date().getDate()-days)).getTime() return new TimeRange([datePrev, dateNow]) } convertFocusDataToTimeseries(focusData, sensorName) { // create dictionary var data = { name: sensorName, columns: ["time", "val"], points: [] } // filter tempArray by fName var focusArray = focusData.filter(el=> { return el.name === sensorName }) // loop through data and add to points in the dictionary above for (var i=0; i { return el.name === sensorName }) var res = [] var dateNow = new Date() //console.log(dateNow.toString()) // treat undefined variable (occurs when filter returns no data) if (fValue.slice(-1)[0] == null) { res.push("No data") res.push("") } else { //console.log(fValue.slice(-1)[0]["dsCollected"].toString()) res.push(fValue.slice(-1)[0]["value"] + "°C") // 36e5 = 60*60*1000 var hours = Math.floor(Math.abs(dateNow - fValue.slice(-1)[0]["dsCollected"])/36e5) var mins = Math.floor((Math.abs(dateNow - fValue.slice(-1)[0]["dsCollected"])/(60*1000))%60) res.push(hours + " hours " + mins + " mins") } //console.log(res) return res } focusSensorName(fArray, sensorName, namesList) { // name of sensor with most recent record var startName = fArray.slice(-1)[0]["name"] // set sensor name to focus on var fName = (sensorName === "" & namesList.length >= 1) ? startName : sensorName // treat undefined variable (occurs when filter returns no data) if (fName == null) { fName = "Select" } return fName } sevenDayHandle(){ this.measurementsFilter(this.state.data, 7) this.setState({ button7: "success", //change color of button7 to green button28: "primary", button365: "primary", timeRange: this.createTimeRange(7), chartXAxisFormat: "day", }) } twentyEightDayHandle(){ this.measurementsFilter(this.state.data, 28) this.setState({ button7: "primary", button28: "success", //change color of button28 to green button365: "primary", timeRange: this.createTimeRange(28), chartXAxisFormat: "month" }) } oneYearHandle(){ this.measurementsFilter(this.state.data, 365) this.setState({ button7: "primary", button28: "primary", button365: "success", //change color of button365 to green timeRange: this.createTimeRange(365), chartXAxisFormat: "year", }) } dropdownSelectionHandle(sn, n){ var fAttr = this.focusSensorValue(this.state.temperature, sn[n]) var timeSeries = this.convertFocusDataToTimeseries(this.state.temperature, sn[n]) this.setState({ focusName: sn[n], focusValue: fAttr[0], focusDate: fAttr[1], timeSeries: timeSeries }) } render() { let button7col = this.state.button7 let button28col = this.state.button28 let button365col = this.state.button365 let sn = this.state.sensorNames let menuItems = [] for (var i=0; i < this.state.sensorNames.length; i++){ var key = i.toString() menuItems.push( {this.state.sensorNames[i]} ) } const buttonsInstance = (
{menuItems}
) if (this.state.timeSeries){ console.log(this.state.timeRange.toString()) console.log(this.state.timeSeries.toString()) console.log(this.state.timeSeries.size()) var chart = (
) } return (

Garden Monitor

{String(this.state.pageLoadDate)}

{buttonsInstance}

{this.state.focusValue}

{this.state.focusDate}

{chart}
) } } export default App;