somehow cobble together a working time series
This commit is contained in:
parent
d7baadec6c
commit
5b63ee4f37
|
@ -1593,6 +1593,11 @@
|
|||
"@prefresh/utils": "^0.2.1"
|
||||
}
|
||||
},
|
||||
"@reach/observe-rect": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@reach/observe-rect/-/observe-rect-1.2.0.tgz",
|
||||
"integrity": "sha512-Ba7HmkFgfQxZqqaeIWWkNK0rEhpxVQHIoVyW1YDSkGsGIXzcaW4deC8B0pZrNSSyLTdIk7y+5olKt5+g0GmFIQ=="
|
||||
},
|
||||
"@rollup/plugin-node-resolve": {
|
||||
"version": "7.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz",
|
||||
|
@ -4722,6 +4727,68 @@
|
|||
"integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=",
|
||||
"dev": true
|
||||
},
|
||||
"d3-array": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz",
|
||||
"integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw=="
|
||||
},
|
||||
"d3-color": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.1.tgz",
|
||||
"integrity": "sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q=="
|
||||
},
|
||||
"d3-delaunay": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-5.3.0.tgz",
|
||||
"integrity": "sha512-amALSrOllWVLaHTnDLHwMIiz0d1bBu9gZXd1FiLfXf8sHcX9jrcj81TVZOqD4UX7MgBZZ07c8GxzEgBpJqc74w==",
|
||||
"requires": {
|
||||
"delaunator": "4"
|
||||
}
|
||||
},
|
||||
"d3-format": {
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.4.tgz",
|
||||
"integrity": "sha512-TWks25e7t8/cqctxCmxpUuzZN11QxIA7YrMbram94zMQ0PXjE4LVIMe/f6a4+xxL8HQ3OsAFULOINQi1pE62Aw=="
|
||||
},
|
||||
"d3-interpolate": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.4.0.tgz",
|
||||
"integrity": "sha512-V9znK0zc3jOPV4VD2zZn0sDhZU3WAE2bmlxdIwwQPPzPjvyLkd8B3JUVdS1IDUFDkWZ72c9qnv1GK2ZagTZ8EA==",
|
||||
"requires": {
|
||||
"d3-color": "1"
|
||||
}
|
||||
},
|
||||
"d3-path": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz",
|
||||
"integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg=="
|
||||
},
|
||||
"d3-shape": {
|
||||
"version": "1.3.7",
|
||||
"resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz",
|
||||
"integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==",
|
||||
"requires": {
|
||||
"d3-path": "1"
|
||||
}
|
||||
},
|
||||
"d3-time": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.1.0.tgz",
|
||||
"integrity": "sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA=="
|
||||
},
|
||||
"d3-time-format": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.2.3.tgz",
|
||||
"integrity": "sha512-RAHNnD8+XvC4Zc4d2A56Uw0yJoM7bsvOlJR33bclxq399Rak/b9bhvu/InjxdWhPtkgU53JJcleJTGkNRnN6IA==",
|
||||
"requires": {
|
||||
"d3-time": "1"
|
||||
}
|
||||
},
|
||||
"d3-voronoi": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/d3-voronoi/-/d3-voronoi-1.1.4.tgz",
|
||||
"integrity": "sha512-dArJ32hchFsrQ8uMiTBLq256MpnZjeuBtdHpaDlYuQyjU0CVzCJl/BVW+SkszaAeH95D/8gxqAhgx0ouAWAfRg=="
|
||||
},
|
||||
"dashdash": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
|
||||
|
@ -4944,6 +5011,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"delaunator": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/delaunator/-/delaunator-4.0.1.tgz",
|
||||
"integrity": "sha512-WNPWi1IRKZfCt/qIDMfERkDp93+iZEmOxN2yy4Jg+Xhv8SLk2UTqqbe1sfiipn0and9QrE914/ihdx82Y/Giag=="
|
||||
},
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
|
@ -10832,6 +10904,11 @@
|
|||
"minimist": "^1.2.5"
|
||||
}
|
||||
},
|
||||
"moment": {
|
||||
"version": "2.27.0",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.27.0.tgz",
|
||||
"integrity": "sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ=="
|
||||
},
|
||||
"moo": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/moo/-/moo-0.5.1.tgz",
|
||||
|
@ -13103,6 +13180,32 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"react-charts": {
|
||||
"version": "2.0.0-beta.7",
|
||||
"resolved": "https://registry.npmjs.org/react-charts/-/react-charts-2.0.0-beta.7.tgz",
|
||||
"integrity": "sha512-iUspg9rnx7kD0H/wsK67HNUioOgKgJ8WRXr/Tk3EGP2qcFb9Vo7pjDk4oz1jH12TC+mqL+HFxNYraMkhWd6CUw==",
|
||||
"requires": {
|
||||
"@reach/observe-rect": "^1.1.0",
|
||||
"d3-delaunay": "^5.2.1",
|
||||
"d3-scale": "^3.2.1",
|
||||
"d3-shape": "^1.3.7",
|
||||
"d3-voronoi": "^1.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"d3-scale": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.2.1.tgz",
|
||||
"integrity": "sha512-huz5byJO/6MPpz6Q8d4lg7GgSpTjIZW/l+1MQkzKfu2u8P6hjaXaStOpmyrD6ymKoW87d2QVFCKvSjLwjzx/rA==",
|
||||
"requires": {
|
||||
"d3-array": "1.2.0 - 2",
|
||||
"d3-format": "1",
|
||||
"d3-interpolate": "^1.2.0",
|
||||
"d3-time": "1",
|
||||
"d3-time-format": "2"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
|
|
|
@ -23,11 +23,13 @@
|
|||
"build/*"
|
||||
],
|
||||
"dependencies": {
|
||||
"moment": "^2.27.0",
|
||||
"preact": "^10.3.1",
|
||||
"preact-jsx-chai": "^3.0.0",
|
||||
"preact-markup": "^2.0.0",
|
||||
"preact-render-to-string": "^5.1.4",
|
||||
"preact-router": "^3.2.1"
|
||||
"preact-router": "^3.2.1",
|
||||
"react-charts": "^2.0.0-beta.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@teamsupercell/typings-for-css-modules-loader": "^2.2.0",
|
||||
|
|
|
@ -27,6 +27,9 @@ export default {
|
|||
"index"
|
||||
);
|
||||
|
||||
config.resolve.alias["react"] = "preact/compat";
|
||||
config.resolve.alias["react-dom"] = "preact/compat";
|
||||
|
||||
config.devServer.proxy = [{
|
||||
// proxy requests matching a pattern:
|
||||
path: '/api/**',
|
||||
|
|
|
@ -1,41 +1,85 @@
|
|||
import { Component, h } from "preact";
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
import { Chart } from 'react-charts'
|
||||
import * as style from "./style.css";
|
||||
|
||||
|
||||
import moment from "moment";
|
||||
|
||||
export interface DatasetProps {
|
||||
name: string,
|
||||
}
|
||||
|
||||
export interface Datapoint {
|
||||
export interface ApiDatapoint {
|
||||
id: number,
|
||||
devicename: string,
|
||||
value: number,
|
||||
timestamp: string,
|
||||
}
|
||||
|
||||
export interface DatasetState {
|
||||
export interface Datapoint {
|
||||
y: number,
|
||||
x: Date,
|
||||
}
|
||||
|
||||
interface Series{
|
||||
label: string,
|
||||
data: Datapoint[],
|
||||
}
|
||||
|
||||
export interface DatasetState {
|
||||
label: string,
|
||||
data: Series[] | undefined,
|
||||
width: number,
|
||||
height: number,
|
||||
}
|
||||
const axes = [
|
||||
{primary: true, type: 'time', position: 'bottom' },
|
||||
{type: 'linear', position: 'left'}
|
||||
];
|
||||
|
||||
class Dataset extends Component<DatasetProps, DatasetState> {
|
||||
|
||||
constructor(){
|
||||
super();
|
||||
this.state = { data: [] };
|
||||
this.state = { data: undefined, label: "w", width: 0, height: 0 };
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
this.updateWindowDimensions();
|
||||
window.addEventListener('resize', this.updateWindowDimensions);
|
||||
|
||||
var devicesResponse = await fetch(`/api/device/${this.props.name}`);
|
||||
this.setState({ data: await devicesResponse.json() as Datapoint[] })
|
||||
var apiData = await devicesResponse.json() as ApiDatapoint[];
|
||||
|
||||
var data = apiData.map((d) => {return {x: moment(d.timestamp).toDate(), y: d.value} as Datapoint});
|
||||
|
||||
this.setState({ data: [{data: data, label: "datapoint"}]});
|
||||
}
|
||||
|
||||
// Lifecycle: Called just before our component will be destroyed
|
||||
componentWillUnmount() {
|
||||
// stop when not renderable
|
||||
window.removeEventListener('resize', this.updateWindowDimensions);
|
||||
}
|
||||
|
||||
updateWindowDimensions() {
|
||||
this.setState({ width: window.innerWidth - 30, height: window.innerHeight - 150 }); // crudely account for heading / padding. yikes
|
||||
}
|
||||
|
||||
render() {
|
||||
var deviceLinks = this.state.data.map((d) => <div>{d.devicename},{d.value},{d.timestamp}</div>)
|
||||
return <div class={style.profile}>{this.props.name}<span>{deviceLinks}</span></div>;
|
||||
if (this.state.data){
|
||||
//var deviceLinks = this.state.data.map((d) => <div>{d.y},{d.x}</div>)
|
||||
return <div class={style.profile}>
|
||||
{this.props.name}
|
||||
<div style={{width: this.state.width, height: this.state.height}}>
|
||||
<Chart data={this.state.data} axes={axes} tooltip/>
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
return <div class={style.profile}>
|
||||
Loading data for {this.props.name}
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
declare module 'react-charts'
|
Loading…
Reference in New Issue