Fix cabana graphs and upgrade react-vega (#22)
* Fix cabana graphs by upgrading react-vega * Fix test cases * Ensure tests on prs * Remove actions menu from graphsmain
parent
ef3ba96f18
commit
3eed6ea06c
|
@ -2,6 +2,9 @@
|
|||
trigger:
|
||||
- master
|
||||
|
||||
pr:
|
||||
- master
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
|
||||
|
|
|
@ -46,19 +46,21 @@
|
|||
"react-infinite": "^0.11.0",
|
||||
"react-list": "^0.8.6",
|
||||
"react-measure": "^2.0.2",
|
||||
"react-scripts": "1.0.17",
|
||||
"react-scripts": "^1.1.2",
|
||||
"react-test-renderer": "^16.2.0",
|
||||
"react-vega": "^3.0.0",
|
||||
"react-vega": "^7.0.0",
|
||||
"react-visibility-sensor": "^3.10.1",
|
||||
"right-pad": "^1.0.1",
|
||||
"simple-statistics": "^4.1.0",
|
||||
"socket.io-client": "^2.0.3",
|
||||
"stream-selector": "^0.1.1",
|
||||
"streamsaver": "^1.0.1",
|
||||
"vega": "3.0.10",
|
||||
"vega": "^5.3.4",
|
||||
"vega-lite": "^3.0.0",
|
||||
"vega-tooltip": "^0.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/plugin-transform-regenerator": "^7.4.5",
|
||||
"connect-history-api-fallback": "1.3.0",
|
||||
"cross-spawn": "4.0.2",
|
||||
"detect-port": "1.1.0",
|
||||
|
|
|
@ -2,10 +2,11 @@ import React, { Component } from "react";
|
|||
import Measure from "react-measure";
|
||||
import PropTypes from "prop-types";
|
||||
import cx from "classnames";
|
||||
import { Vega } from "react-vega";
|
||||
|
||||
import Signal from "../models/can/signal";
|
||||
import GraphData from "../models/graph-data";
|
||||
import CanPlot from "../vega/CanPlot";
|
||||
import CanPlotSpec from "../vega/CanPlot";
|
||||
import debounce from "../utils/debounce";
|
||||
|
||||
const DefaultPlotInnerStyle = {
|
||||
|
@ -106,19 +107,27 @@ export default class CanGraph extends Component {
|
|||
}
|
||||
|
||||
onPlotResize({ bounds }) {
|
||||
this.setState({ bounds });
|
||||
if (bounds) {
|
||||
this.setState({ bounds });
|
||||
} else {
|
||||
bounds = this.state.bounds;
|
||||
}
|
||||
|
||||
if (!this.view) {
|
||||
console.log("Cannot bounds");
|
||||
return;
|
||||
}
|
||||
this.view.signal("width", bounds.width - 70);
|
||||
this.view.signal("height", 0.4 * (bounds.width - 70)); // 5:2 aspect ratio
|
||||
this.view.run();
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
componentWillUpdate(nextProps, nextState) {
|
||||
if (this.view) {
|
||||
let segmentChanged = this.segmentIsNew(nextProps.segment);
|
||||
this.view.runAfter(() => {
|
||||
// only update if segment is new
|
||||
let segmentChanged = false;
|
||||
if (this.segmentIsNew(nextProps.segment)) {
|
||||
if (segmentChanged) {
|
||||
if (nextProps.segment.length > 0) {
|
||||
// Set segmented domain
|
||||
this.view.signal("segment", nextProps.segment);
|
||||
|
@ -141,14 +150,17 @@ export default class CanGraph extends Component {
|
|||
this.view.runAsync();
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
insertData = debounce(() => {
|
||||
if (!this.view) {
|
||||
console.log("Cannot insertData");
|
||||
return;
|
||||
}
|
||||
|
||||
let { series } = this.state.data;
|
||||
|
||||
// adding plot points by diff isn't faster since it basically has to be n^2
|
||||
|
@ -198,7 +210,7 @@ export default class CanGraph extends Component {
|
|||
this.view = view;
|
||||
|
||||
if (this.state.bounds) {
|
||||
this.onPlotResize({ bounds: this.state.bounds });
|
||||
this.onPlotResize();
|
||||
}
|
||||
if (this.props.segment.length > 0) {
|
||||
view.signal("segment", this.props.segment);
|
||||
|
@ -220,6 +232,11 @@ export default class CanGraph extends Component {
|
|||
|
||||
this.props.onSegmentChanged(this.props.messageId, segment);
|
||||
|
||||
if (!this.view) {
|
||||
console.log("Cannot insertData");
|
||||
return;
|
||||
}
|
||||
|
||||
this.view.runAfter(() => {
|
||||
const state = this.view.getState();
|
||||
state.subcontext[0].signals.brush = 0;
|
||||
|
@ -336,12 +353,19 @@ export default class CanGraph extends Component {
|
|||
ref={measureRef}
|
||||
className="cabana-explorer-visuals-plot-container"
|
||||
>
|
||||
<CanPlot
|
||||
logLevel={1}
|
||||
<Vega
|
||||
onNewView={this.onNewView}
|
||||
onSignalClickTime={this.onSignalClickTime}
|
||||
onSignalSegment={this.onSignalSegment}
|
||||
logLevel={1}
|
||||
signalListeners={{
|
||||
clickTime: this.onSignalClickTime,
|
||||
segment: this.onSignalSegment
|
||||
}}
|
||||
renderer={"canvas"}
|
||||
spec={CanPlotSpec}
|
||||
actions={false}
|
||||
data={{
|
||||
values: this.state.data.series
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -11,7 +11,6 @@ import Entries from "../models/can/entries";
|
|||
import debounce from "../utils/debounce";
|
||||
import PartSelector from "./PartSelector";
|
||||
import PlaySpeedSelector from "./PlaySpeedSelector";
|
||||
import GraphData from "../models/graph-data";
|
||||
|
||||
export default class Explorer extends Component {
|
||||
static propTypes = {
|
||||
|
@ -33,7 +32,6 @@ export default class Explorer extends Component {
|
|||
|
||||
this.state = {
|
||||
plottedSignals: [],
|
||||
graphData: [],
|
||||
segment: [],
|
||||
segmentIndices: [],
|
||||
shouldShowAddSignal: true,
|
||||
|
@ -56,7 +54,6 @@ export default class Explorer extends Component {
|
|||
this.onSignalPlotChange = this.onSignalPlotChange.bind(this);
|
||||
this._onKeyDown = this._onKeyDown.bind(this);
|
||||
this.mergePlots = this.mergePlots.bind(this);
|
||||
this.refreshGraphData = this.refreshGraphData.bind(this);
|
||||
this.toggleShouldShowAddSignal = this.toggleShouldShowAddSignal.bind(this);
|
||||
this.changePlaySpeed = this.changePlaySpeed.bind(this);
|
||||
}
|
||||
|
@ -107,7 +104,7 @@ export default class Explorer extends Component {
|
|||
componentWillReceiveProps(nextProps) {
|
||||
const nextMessage = nextProps.messages[nextProps.selectedMessage];
|
||||
const curMessage = this.props.messages[this.props.selectedMessage];
|
||||
let { plottedSignals, graphData } = this.state;
|
||||
let { plottedSignals } = this.state;
|
||||
|
||||
if (Object.keys(nextProps.messages).length === 0) {
|
||||
this.resetSegment();
|
||||
|
@ -183,43 +180,6 @@ export default class Explorer extends Component {
|
|||
);
|
||||
this.setState({ segment, segmentIndices });
|
||||
}
|
||||
|
||||
const partsDidChange =
|
||||
JSON.stringify(nextProps.currentParts) !==
|
||||
JSON.stringify(this.props.currentParts);
|
||||
|
||||
if (plottedSignals.length > 0) {
|
||||
if (graphData.length !== plottedSignals.length || partsDidChange) {
|
||||
this.refreshGraphData(nextProps.messages, plottedSignals);
|
||||
} else if (graphData.length === plottedSignals.length) {
|
||||
if (
|
||||
plottedSignals.some(plot =>
|
||||
plot.some(({ messageId, signalUid }) => {
|
||||
/* const signalName = Object.values(
|
||||
* this.props.messages[messageId].frame.signals
|
||||
* ).find(s => s.uid === signalUid);
|
||||
*/
|
||||
return (
|
||||
nextProps.messages[messageId].entries.length > 0 &&
|
||||
this.props.messages[messageId].entries.length > 0 &&
|
||||
nextProps.messages[messageId].entries[0].updated !==
|
||||
this.props.messages[messageId].entries[0].updated
|
||||
);
|
||||
})
|
||||
)
|
||||
) {
|
||||
this.refreshGraphData(nextProps.messages, plottedSignals);
|
||||
} else {
|
||||
graphData = GraphData.appendNewGraphData(
|
||||
plottedSignals,
|
||||
graphData,
|
||||
nextProps.messages,
|
||||
nextProps.firstCanTime
|
||||
);
|
||||
this.setState({ graphData });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
changePlaySpeed(value) {
|
||||
|
@ -248,56 +208,12 @@ export default class Explorer extends Component {
|
|||
} else return "";
|
||||
}
|
||||
|
||||
sortGraphData(graphData) {
|
||||
return graphData.sort((entry1, entry2) => {
|
||||
if (entry1.relTime < entry2.relTime) {
|
||||
return -1;
|
||||
} else if (entry1.relTime > entry2.relTime) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
calcGraphData(plottedSignals, messages) {
|
||||
const { firstCanTime } = this.props;
|
||||
if (typeof messages === "undefined") {
|
||||
messages = this.props.messages;
|
||||
}
|
||||
|
||||
const series = this.sortGraphData(
|
||||
plottedSignals
|
||||
.map(({ messageId, signalUid }) =>
|
||||
GraphData._calcGraphData(messages[messageId], signalUid, firstCanTime)
|
||||
)
|
||||
.reduce((combined, signalData) => combined.concat(signalData), [])
|
||||
);
|
||||
|
||||
return { series, updated: Date.now() };
|
||||
}
|
||||
|
||||
onSignalPlotPressed(messageId, signalUid) {
|
||||
let { plottedSignals, graphData } = this.state;
|
||||
let { plottedSignals } = this.state;
|
||||
|
||||
graphData = [this.calcGraphData([{ messageId, signalUid }]), ...graphData];
|
||||
plottedSignals = [[{ messageId, signalUid }], ...plottedSignals];
|
||||
|
||||
this.setState({ plottedSignals, graphData });
|
||||
}
|
||||
|
||||
refreshGraphData(messages, plottedSignals) {
|
||||
if (typeof messages === "undefined") {
|
||||
messages = this.props.messages;
|
||||
}
|
||||
if (typeof plottedSignals === "undefined") {
|
||||
plottedSignals = this.state.plottedSignals;
|
||||
}
|
||||
let graphData = plottedSignals.map((plotSignals, index) =>
|
||||
this.calcGraphData(plotSignals, messages)
|
||||
);
|
||||
|
||||
this.setState({ graphData });
|
||||
this.setState({ plottedSignals });
|
||||
}
|
||||
|
||||
onSignalUnplotPressed(messageId, signalUid) {
|
||||
|
@ -311,10 +227,7 @@ export default class Explorer extends Component {
|
|||
)
|
||||
.filter(plot => plot.length > 0);
|
||||
|
||||
this.setState(
|
||||
{ plottedSignals: newPlottedSignals },
|
||||
this.refreshGraphData(this.props.messages, newPlottedSignals)
|
||||
);
|
||||
this.setState({ plottedSignals: newPlottedSignals });
|
||||
}
|
||||
|
||||
updateSegment = debounce((messageId, segment) => {
|
||||
|
@ -526,9 +439,9 @@ export default class Explorer extends Component {
|
|||
}
|
||||
|
||||
mergePlots({ fromPlot, toPlot }) {
|
||||
let { plottedSignals, graphData } = this.state;
|
||||
let { plottedSignals } = this.state;
|
||||
|
||||
// remove fromPlot from plottedSignals, graphData
|
||||
// remove fromPlot from plottedSignals
|
||||
const fromPlotIdx = plottedSignals.findIndex(plot =>
|
||||
plot.some(
|
||||
signal =>
|
||||
|
@ -537,10 +450,6 @@ export default class Explorer extends Component {
|
|||
)
|
||||
);
|
||||
plottedSignals.splice(fromPlotIdx, 1);
|
||||
graphData.splice(fromPlotIdx, 1);
|
||||
|
||||
// calc new graph data
|
||||
const newGraphData = this.calcGraphData([fromPlot, toPlot]);
|
||||
|
||||
const toPlotIdx = plottedSignals.findIndex(plot =>
|
||||
plot.some(
|
||||
|
@ -549,10 +458,9 @@ export default class Explorer extends Component {
|
|||
signal.messageId === toPlot.messageId
|
||||
)
|
||||
);
|
||||
graphData[toPlotIdx] = newGraphData;
|
||||
plottedSignals[toPlotIdx] = [fromPlot, toPlot];
|
||||
|
||||
this.setState({ graphData, plottedSignals });
|
||||
this.setState({ plottedSignals });
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
import { createClassFromSpec } from "react-vega";
|
||||
|
||||
export default createClassFromSpec("CanPlot", {
|
||||
export default {
|
||||
$schema: "https://vega.github.io/schema/vega/v3.0.json",
|
||||
width: 400,
|
||||
height: 200,
|
||||
|
@ -335,4 +333,4 @@ export default createClassFromSpec("CanPlot", {
|
|||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue