2021年7月21日 星期三

[dygraphs, react] How to show a live updated time-serial data using Dygraphs in React function component

How to show a live updated time-serial data using Dygraphs in React function component

井民全, Jing, mqjing@gmail.com


Github : Source



1. Install packages

# install

npx create-react-app app --template typescript

cd app

yarn add @types/dygraphs dygraphs


# edit

cd src

code .



2. Code

File: src/component/showWae.css

  .center {

    margin: auto; /* To horizontally center a block element, use margin:auto*/

    background: rgb(202, 236, 195);

    width: 66%;

  }


File: src/components/showWave.tsx

import React, { useEffect } from 'react';

import Dygraph from 'dygraphs';

import './showWave.css';


function ShowWave(props: { labName: number }): JSX.Element {

    console.log('ShowWave:' + JSON.stringify(props));

    let data: any = [];


    useEffect(() => {

        console.log('use Effect');


        var t = new Date();

        var g = new Dygraph('graph', data, {

            drawPoints: true,

            showRoller: true,

            valueRange: [0.0, 1.2],

            labels: ['Time', 'Random']

        });


        setInterval(() => {

            var x = new Date(); // current time

            var y = Math.random();

            console.log('id = ' + props.labName + ' x = ' + x + ' y = ' + y);

            if (data.length > 100)

                data.shift();

            data.push([x, y]);

            g.updateOptions({

                'file': data

            });

        }, 100);

    }, []);



    return (

        <div>

            <div>{props.labName}</div>

            <div id="graph"  className="center"> </div>

        </div>

    );


}

export default ShowWave;


File:./src/App.tsx

import React, { useState } from 'react';

import './App.css';

import Button from '@material-ui/core/Button';

import MyFunComp from './components/my-fun-comp'

import ShowWave from './components/showWave'



function App() {

  const [state, setState] = useState({ id: 0 });

  const [state2, setState2] = useState({ labName: 1 });


  const OnStartTest = async () => {

    console.log('OnStartTest');

    

    // setState will chain react the renders all childs

    setState({ ...state, id: state.id = (state.id + 1)%3 });

    setState2({ ...state2, labName: state.id });

  }


  return (

    <div className="App">

      <div> Show Wave <ShowWave labName={state2.labName}></ShowWave></div>

      <div> Function Component <MyFunComp id={state.id}></MyFunComp></div>

      <div><Button onClick={OnStartTest} variant="contained" color="primary"> Start Test</Button></div>

    </div>

  );

}


export default App;



Result



Make Clean

File: ./package.json

"clean": "(rm -fr node_modules; rm -fr build; find . -name \"*.js\" -type f|xargs rm -f; find . -name \"*.map\" -type f|xargs rm -f)"





If you interesting in Class way, here is an example.

File: app.tsx

import React, {Component} from 'react';

import './App.css';

import Dygraph from 'dygraphs';

import 'dygraphs/dist/dygraph.min.css'


class App extends Component {

  data:any = [];


  constructor(props:any) {

      super(props);

  }

  

  render() {

      return <div id="graph"></div>;

  }


  componentDidMount() {

    var t = new Date();

    var g = new Dygraph('graph', this.data, {

      drawPoints: true,

      showRoller: true,

      valueRange: [0.0, 1.2],

      labels: ['Time', 'Random']

    });


    setInterval(() => {

      var x = new Date(); // current time

      var y = Math.random();

      if(this.data.length > 100)

        this.data.shift();

      this.data.push([x, y]);

      g.updateOptions({

        'file': this.data

      });

    }, 10);

  }

}


export default App;