cabana/src/components/CanGraph.js

124 lines
3.5 KiB
JavaScript
Raw Normal View History

import React, {Component} from 'react';
import Vega from 'react-vega';
import PropTypes from 'prop-types';
import Signal from '../models/can/signal';
import CanPlot from '../vega/CanPlot';
export default class CanGraph extends Component {
2017-06-13 18:40:05 -06:00
static MAX_POINTS = 10000;
static propTypes = {
data: PropTypes.array,
messageId: PropTypes.string,
messageName: PropTypes.string,
signalSpec: PropTypes.instanceOf(Signal),
2017-06-13 18:40:05 -06:00
segment: PropTypes.array,
unplot: PropTypes.func,
onRelativeTimeClick: PropTypes.func,
2017-06-16 16:45:19 -06:00
currentTime: PropTypes.number,
onSegmentChanged: PropTypes.func
};
constructor(props) {
super(props);
this.onNewView = this.onNewView.bind(this);
2017-06-13 18:40:05 -06:00
this.onSignalClickTime = this.onSignalClickTime.bind(this);
2017-06-16 16:45:19 -06:00
this.onSignalSegment = this.onSignalSegment.bind(this);
}
segmentIsNew(newSegment) {
return newSegment.length != this.props.segment.length
|| !(newSegment.every((val, idx) => this.props.segment[idx] == val));
}
dataChanged(prevProps, nextProps) {
return nextProps.data.length != prevProps.data.length
|| !(prevProps.signalSpec.equals(nextProps.signalSpec))
|| prevProps.data.some((prevEntry, idx) => prevEntry.y != nextProps.data[idx].y);
}
shouldComponentUpdate(nextProps, nextState) {
if(this.view) {
// only update if segment is new
2017-06-13 18:40:05 -06:00
let segmentChanged = false;
2017-06-16 22:41:15 -06:00
if(this.segmentIsNew(nextProps.segment)) {
if(nextProps.segment.length > 0) {
// Set segmented domain
this.view.signal('segment', nextProps.segment)
} else {
// Reset segment to full domain
2017-06-16 23:33:19 -06:00
this.view.signal('segment', 0);
2017-06-16 22:41:15 -06:00
}
segmentChanged = true;
}
2017-06-13 18:40:05 -06:00
if(nextProps.currentTime != this.props.currentTime) {
this.view.signal('videoTime', nextProps.currentTime);
segmentChanged = true;
}
if(segmentChanged) {
this.view.run();
}
}
return this.dataChanged(this.props, nextProps);
}
componentDidUpdate(prevProps, prevState) {
if(this.dataChanged(prevProps, this.props)) {
this.view.run();
}
}
onNewView(view) {
this.view = view;
if(this.props.segment.length > 0) {
view.signal('segment', this.props.segment);
}
}
2017-06-13 18:40:05 -06:00
onSignalClickTime(signal, clickTime) {
if(clickTime !== undefined) {
this.props.onRelativeTimeClick(this.props.messageId, clickTime);
2017-06-13 18:40:05 -06:00
}
}
2017-06-16 16:45:19 -06:00
onSignalSegment(signal, segment) {
2017-06-16 22:41:15 -06:00
if(!Array.isArray(segment)) {
return;
}
this.props.onSegmentChanged(this.props.messageId, segment);
2017-06-16 22:41:15 -06:00
if(this.view) {
const state = this.view.getState();
state.subcontext[0].signals.brush = 0;
this.view = this.view.setState(state);
}
2017-06-16 16:45:19 -06:00
}
render() {
return (
<div className='cabana-explorer-visuals-plot'>
<div className='cabana-explorer-visuals-plot-message'>
<span>{this.props.messageName}</span>
</div>
<div className='cabana-explorer-visuals-plot-signal'>
<strong>{this.props.signalSpec.name}</strong>
<a onClick={this.props.unplot}>(unplot)</a>
</div>
<CanPlot
className='cabana-explorer-visuals-plot-canvas'
logLevel={0}
data={{table: this.props.data}}
onNewView={this.onNewView}
onSignalClickTime={this.onSignalClickTime}
onSignalSegment={this.onSignalSegment}/>
</div>
);
}
}