Refactor can plot spec, fix charts not receiving new data
parent
eb37fcc7e1
commit
79035c5990
|
@ -566,7 +566,7 @@ export default class CanExplorer extends Component {
|
|||
// handles merging the data in correct order
|
||||
options = options || {};
|
||||
|
||||
const { messages } = this.state;
|
||||
const messages = { ...this.state.messages };
|
||||
|
||||
Object.keys(newMessages).forEach((key) => {
|
||||
// add message
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
/* eslint-env jest */
|
||||
import { demoLogUrls, demoProps, demoRoute } from '../demo';
|
||||
import { getLogPart } from '../api/rlog';
|
||||
|
||||
describe('demo fixtures', () => {
|
||||
it('demo log urls are valid', async () => {
|
||||
const data = await getLogPart(demoLogUrls[0]);
|
||||
expect(data.statusCode).toBe(200);
|
||||
});
|
||||
});
|
|
@ -165,7 +165,7 @@ export default class Signal {
|
|||
}
|
||||
|
||||
getColors(messageId) {
|
||||
const parts = messageId.split(':').map((p) => Number.parseInt(p, 16) % 255);
|
||||
const parts = messageId.split(':').map((p) => ((3 + Number.parseInt(p, 16)) * 3) % 253);
|
||||
const colors = this._colors || this.generateColors();
|
||||
|
||||
return colors.map((c) => parts.reduce((m, v) => m ^ v, c));
|
||||
|
|
|
@ -32,6 +32,7 @@ function _calcGraphData(msg, signalUid, firstCanTime) {
|
|||
}
|
||||
|
||||
const colors = signal.getColors(msg.id);
|
||||
signalUid = msg.id + signalUid;
|
||||
// sorting these doesn't fix the phantom lines
|
||||
let lastEntry = samples[0].relTime;
|
||||
return samples
|
||||
|
|
|
@ -1,340 +1,472 @@
|
|||
export default {
|
||||
$schema: 'https://vega.github.io/schema/vega/v5.6.json',
|
||||
width: 400,
|
||||
height: 200,
|
||||
padding: {
|
||||
top: 5,
|
||||
left: 30,
|
||||
right: 5,
|
||||
bottom: 10
|
||||
"$schema": "https://vega.github.io/schema/vega/v5.json",
|
||||
"width": 400,
|
||||
"height": 200,
|
||||
"padding": {
|
||||
"top": 5,
|
||||
"left": 30,
|
||||
"right": 5,
|
||||
"bottom": 10
|
||||
},
|
||||
signals: [
|
||||
"data": [
|
||||
{
|
||||
name: 'tipTime',
|
||||
on: [
|
||||
"name": "table"
|
||||
},
|
||||
{
|
||||
"name": "segment"
|
||||
},
|
||||
{
|
||||
"name": "tooltip",
|
||||
"source": "table",
|
||||
"transform": [
|
||||
{
|
||||
events: 'mousemove',
|
||||
update: "invert('xrelscale', x())"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'clickTime',
|
||||
on: [
|
||||
{
|
||||
events: 'click',
|
||||
update: "invert('xrelscale', x())"
|
||||
}
|
||||
]
|
||||
},
|
||||
{ name: 'videoTime' },
|
||||
{
|
||||
name: 'segment',
|
||||
value: { data: 'table', field: 'relTime' }
|
||||
}
|
||||
],
|
||||
data: [
|
||||
{
|
||||
name: 'table'
|
||||
},
|
||||
{
|
||||
name: 'segment'
|
||||
},
|
||||
{
|
||||
name: 'tooltip',
|
||||
source: 'table',
|
||||
transform: [
|
||||
{
|
||||
type: 'filter',
|
||||
expr: 'abs(datum.relTime - tipTime) <= 0.01'
|
||||
"type": "filter",
|
||||
"expr": "abs(datum.relTime - tipTime) <= 0.05"
|
||||
},
|
||||
{
|
||||
type: 'aggregate',
|
||||
fields: ['relTime', 'y', 'unit'],
|
||||
ops: ['min', 'argmin', 'argmin'],
|
||||
as: ['min', 'argmin', 'argmin']
|
||||
"type": "aggregate",
|
||||
"groupby": ["color"],
|
||||
"fields": [
|
||||
"relTime",
|
||||
"y",
|
||||
"unit"
|
||||
],
|
||||
"ops": [
|
||||
"min",
|
||||
"argmin",
|
||||
"argmin"
|
||||
],
|
||||
"as": [
|
||||
"min",
|
||||
"argmin",
|
||||
"argmin"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'ySegmentScale',
|
||||
source: 'table',
|
||||
transform: [
|
||||
"name": "ySegmentScale",
|
||||
"source": "table",
|
||||
"transform": [
|
||||
{
|
||||
type: 'filter',
|
||||
expr:
|
||||
'length(segment) != 2 || (datum.relTime >= segment[0] && datum.relTime <= segment[1])'
|
||||
"type": "filter",
|
||||
"expr": "length(segment) != 2 || (datum.relTime >= segment[0] && datum.relTime <= segment[1])"
|
||||
},
|
||||
{ type: 'extent', field: 'y', signal: 'ySegment' }
|
||||
{
|
||||
"type": "extent",
|
||||
"field": "y",
|
||||
"signal": "ySegment"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
scales: [
|
||||
|
||||
"scales": [
|
||||
{
|
||||
name: 'xscale',
|
||||
type: 'linear',
|
||||
range: 'width',
|
||||
domain: { data: 'table', field: 'x' },
|
||||
zero: false
|
||||
"name": "xscale",
|
||||
"type": "linear",
|
||||
"range": "width",
|
||||
"domain": {
|
||||
"data": "table",
|
||||
"field": "x"
|
||||
},
|
||||
"zero": false
|
||||
},
|
||||
{
|
||||
name: 'xrelscale',
|
||||
type: 'linear',
|
||||
range: 'width',
|
||||
domain: { data: 'table', field: 'relTime' },
|
||||
zero: false,
|
||||
clamp: true,
|
||||
domainRaw: { signal: 'segment' }
|
||||
"name": "xrelscale",
|
||||
"type": "linear",
|
||||
"range": "width",
|
||||
"domain": {
|
||||
"data": "table",
|
||||
"field": "relTime"
|
||||
},
|
||||
"zero": false,
|
||||
"clamp": true,
|
||||
"nice": true,
|
||||
"domainRaw": {
|
||||
"signal": "segment"
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'yscale',
|
||||
type: 'linear',
|
||||
range: 'height',
|
||||
clamp: true,
|
||||
zero: false,
|
||||
domain: { signal: 'ySegment' }
|
||||
"name": "yscale",
|
||||
"type": "linear",
|
||||
"range": "height",
|
||||
"clamp": true,
|
||||
"zero": false,
|
||||
"nice": true,
|
||||
"domain": {
|
||||
"signal": "ySegment"
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'color',
|
||||
type: 'ordinal',
|
||||
domain: { data: 'table', field: 'color' },
|
||||
range: { data: 'table', field: 'color' }
|
||||
"name": "color",
|
||||
"type": "ordinal",
|
||||
"domain": {
|
||||
"data": "table",
|
||||
"field": "color"
|
||||
},
|
||||
"range": {
|
||||
"data": "table",
|
||||
"field": "color"
|
||||
}
|
||||
}
|
||||
],
|
||||
axes: [
|
||||
{ orient: 'bottom', scale: 'xrelscale', labelOverlap: true },
|
||||
{ orient: 'left', scale: 'yscale' }
|
||||
],
|
||||
marks: [
|
||||
|
||||
|
||||
"axes": [
|
||||
{
|
||||
type: 'group',
|
||||
name: 'plot',
|
||||
interactive: true,
|
||||
encode: {
|
||||
enter: {
|
||||
width: { signal: 'width' },
|
||||
height: { signal: 'height' },
|
||||
fill: { value: 'transparent' }
|
||||
"orient": "bottom",
|
||||
"scale": "xrelscale",
|
||||
"labelOverlap": true
|
||||
},
|
||||
{
|
||||
"orient": "left",
|
||||
"scale": "yscale"
|
||||
}
|
||||
],
|
||||
|
||||
"signals": [
|
||||
{
|
||||
"name": "tipTime",
|
||||
"on": [
|
||||
{
|
||||
"events": "mousemove",
|
||||
"update": "invert('xrelscale', x())"
|
||||
},
|
||||
{
|
||||
"events": "mouseout",
|
||||
"update": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "clickTime",
|
||||
"on": [
|
||||
{
|
||||
"events": "click",
|
||||
"update": "invert('xrelscale', x())"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "videoTime"
|
||||
},
|
||||
{
|
||||
"name": "segment",
|
||||
"value": {
|
||||
"data": "table",
|
||||
"field": "relTime"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"marks": [
|
||||
{
|
||||
"type": "group",
|
||||
"name": "plot",
|
||||
"interactive": true,
|
||||
"encode": {
|
||||
"enter": {
|
||||
"width": {
|
||||
"signal": "width"
|
||||
},
|
||||
"height": {
|
||||
"signal": "height"
|
||||
},
|
||||
"fill": {
|
||||
"value": "transparent"
|
||||
}
|
||||
}
|
||||
},
|
||||
signals: [
|
||||
"signals": [
|
||||
{
|
||||
name: 'brush',
|
||||
value: 0,
|
||||
on: [
|
||||
"name": "brush",
|
||||
"value": 0,
|
||||
"on": [
|
||||
{
|
||||
events: '@boundingRect:mousedown',
|
||||
update: '[x(), x()]'
|
||||
"events": "@boundingRect:mousedown",
|
||||
"update": "[x(), x()]"
|
||||
},
|
||||
{
|
||||
events:
|
||||
'[@boundingRect:mousedown, window:mouseup] > window:mousemove!',
|
||||
update: '[brush[0], clamp(x(), 0, width)]'
|
||||
"events": "[@boundingRect:mousedown, window:mouseup] > window:mousemove!",
|
||||
"update": "[brush[0], clamp(x(), 0, width)]"
|
||||
},
|
||||
{
|
||||
events: { signal: 'delta' },
|
||||
update:
|
||||
'clampRange([anchor[0] + delta, anchor[1] + delta], 0, width)'
|
||||
"events": {
|
||||
"signal": "delta"
|
||||
},
|
||||
"update": "clampRange([anchor[0] + delta, anchor[1] + delta], 0, width)"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'anchor',
|
||||
value: null,
|
||||
on: [{ events: '@brush:mousedown', update: 'slice(brush)' }]
|
||||
},
|
||||
{
|
||||
name: 'xdown',
|
||||
value: 0,
|
||||
on: [{ events: '@brush:mousedown', update: 'x()' }]
|
||||
},
|
||||
{
|
||||
name: 'xup',
|
||||
value: 0,
|
||||
on: [{ events: '@brush:mouseup', update: 'x()' }]
|
||||
},
|
||||
{
|
||||
name: 'delta',
|
||||
value: 0,
|
||||
on: [
|
||||
"name": "anchor",
|
||||
"value": null,
|
||||
"on": [
|
||||
{
|
||||
events: '[@brush:mousedown, window:mouseup] > window:mousemove!',
|
||||
update: 'x() - xdown'
|
||||
"events": "@brush:mousedown",
|
||||
"update": "slice(brush)"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
name: 'segment',
|
||||
push: 'outer',
|
||||
on: [
|
||||
"name": "xdown",
|
||||
"value": 0,
|
||||
"on": [
|
||||
{
|
||||
events: 'window:mouseup',
|
||||
update:
|
||||
"span(brush) && span(brush) > 15 ? invert('xrelscale', brush) : segment"
|
||||
"events": "@brush:mousedown",
|
||||
"update": "x()"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "xup",
|
||||
"value": 0,
|
||||
"on": [
|
||||
{
|
||||
"events": "@brush:mouseup",
|
||||
"update": "x()"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "delta",
|
||||
"value": 0,
|
||||
"on": [
|
||||
{
|
||||
"events": "[@brush:mousedown, window:mouseup] > window:mousemove!",
|
||||
"update": "x() - xdown"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "segment",
|
||||
"push": "outer",
|
||||
"on": [
|
||||
{
|
||||
"events": "window:mouseup",
|
||||
"update": "span(brush) && span(brush) > 15 ? invert('xrelscale', brush) : segment"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
marks: [
|
||||
"marks": [
|
||||
{
|
||||
type: 'group',
|
||||
from: {
|
||||
facet: {
|
||||
name: 'series',
|
||||
data: 'table',
|
||||
groupby: 'signalUid'
|
||||
"type": "group",
|
||||
"from": {
|
||||
"facet": {
|
||||
"name": "series",
|
||||
"data": "table",
|
||||
"groupby": "signalUid"
|
||||
}
|
||||
},
|
||||
marks: {
|
||||
type: 'line',
|
||||
name: 'lineMark',
|
||||
from: { data: 'series' },
|
||||
interactive: true,
|
||||
encode: {
|
||||
update: {
|
||||
interpolate: { value: 'step' },
|
||||
x: { scale: 'xrelscale', field: 'relTime' },
|
||||
y: { scale: 'yscale', field: 'y' }
|
||||
},
|
||||
hover: {
|
||||
fillOpacity: { value: 0.5 }
|
||||
},
|
||||
enter: {
|
||||
clip: { value: true },
|
||||
stroke: { scale: 'color', field: 'color' },
|
||||
strokeWidth: { value: 2 }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'rect',
|
||||
interactive: true,
|
||||
name: 'brush',
|
||||
encode: {
|
||||
enter: {
|
||||
y: { value: 0 },
|
||||
height: { signal: 'height' },
|
||||
fill: { value: '#333' },
|
||||
fillOpacity: { value: 0.2 }
|
||||
"marks": [{
|
||||
"type": "line",
|
||||
"name": "lineMark",
|
||||
"from": {
|
||||
"data": "series"
|
||||
},
|
||||
update: {
|
||||
x: { signal: 'brush[0]' },
|
||||
x2: { signal: 'brush[1]' }
|
||||
"interactive": true,
|
||||
"encode": {
|
||||
"update": {
|
||||
"interpolate": {
|
||||
"value": "natural",
|
||||
"tension": 1
|
||||
},
|
||||
"x": {
|
||||
"scale": "xrelscale",
|
||||
"field": "relTime"
|
||||
},
|
||||
"y": {
|
||||
"scale": "yscale",
|
||||
"field": "y"
|
||||
},
|
||||
"detail": {
|
||||
"field": "signalUid"
|
||||
}
|
||||
},
|
||||
"hover": {
|
||||
"fillOpacity": {
|
||||
"value": 0.5
|
||||
}
|
||||
},
|
||||
"enter": {
|
||||
"clip": {
|
||||
"value": true
|
||||
},
|
||||
"stroke": {
|
||||
"scale": "color",
|
||||
"field": "color"
|
||||
},
|
||||
"strokeWidth": {
|
||||
"value": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}]
|
||||
},
|
||||
// {
|
||||
// "type": "rect",
|
||||
// "interactive": false,
|
||||
// "encode": {
|
||||
// "enter": {
|
||||
// "y": {"value": 0},
|
||||
// "height": {"value": 200},
|
||||
// "width": {"value": 2},
|
||||
// "fill": {"value": "firebrick"}
|
||||
// },
|
||||
// "update": {
|
||||
// "x": {"signal": "brush[0]"}
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// "type": "rect",
|
||||
// "interactive": false,
|
||||
// "encode": {
|
||||
// "enter": {
|
||||
// "y": {"value": 0},
|
||||
// "height": {"value": 200},
|
||||
// "width": {"value": 2},
|
||||
// "fill": {"value": "firebrick"}
|
||||
// },
|
||||
// "update": {
|
||||
// "x": {"signal": "brush[1]"}
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
{
|
||||
type: 'rule',
|
||||
encode: {
|
||||
update: {
|
||||
y: { value: 0 },
|
||||
y2: { field: { group: 'height' } },
|
||||
stroke: { value: '#000' },
|
||||
strokeWidth: { value: 2 },
|
||||
x: {
|
||||
scale: 'xrelscale',
|
||||
signal: 'videoTime',
|
||||
offset: 0.5
|
||||
"type": "rect",
|
||||
"interactive": true,
|
||||
"name": "brush",
|
||||
"encode": {
|
||||
"enter": {
|
||||
"y": {
|
||||
"value": 0
|
||||
},
|
||||
"height": {
|
||||
"signal": "height"
|
||||
},
|
||||
"fill": {
|
||||
"value": "#333"
|
||||
},
|
||||
"fillOpacity": {
|
||||
"value": 0.2
|
||||
}
|
||||
},
|
||||
"update": {
|
||||
"x": {
|
||||
"signal": "brush[0]"
|
||||
},
|
||||
"x2": {
|
||||
"signal": "brush[1]"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'symbol',
|
||||
from: { data: 'tooltip' },
|
||||
encode: {
|
||||
update: {
|
||||
x: { scale: 'xrelscale', field: 'argmin.relTime' },
|
||||
y: { scale: 'yscale', field: 'argmin.y' },
|
||||
size: { value: 50 },
|
||||
fill: { value: 'black' }
|
||||
"type": "rule",
|
||||
"encode": {
|
||||
"update": {
|
||||
"y": {
|
||||
"value": 0
|
||||
},
|
||||
"y2": {
|
||||
"field": {
|
||||
"group": "height"
|
||||
}
|
||||
},
|
||||
"stroke": {
|
||||
"value": "#000"
|
||||
},
|
||||
"strokeWidth": {
|
||||
"value": 2
|
||||
},
|
||||
"x": {
|
||||
"scale": "xrelscale",
|
||||
"signal": "videoTime",
|
||||
"offset": 0.5
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'group',
|
||||
from: { data: 'tooltip' },
|
||||
interactive: false,
|
||||
name: 'tooltipGroup',
|
||||
encode: {
|
||||
update: {
|
||||
x: [
|
||||
"type": "symbol",
|
||||
"from": {
|
||||
"data": "tooltip"
|
||||
},
|
||||
"encode": {
|
||||
"update": {
|
||||
"x": {
|
||||
"scale": "xrelscale",
|
||||
"field": "argmin.relTime"
|
||||
},
|
||||
"y": {
|
||||
"scale": "yscale",
|
||||
"field": "argmin.y"
|
||||
},
|
||||
"size": {
|
||||
"value": 50
|
||||
},
|
||||
"fill": {
|
||||
"value": "black"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "group",
|
||||
"from": {
|
||||
"data": "tooltip"
|
||||
},
|
||||
"interactive": false,
|
||||
"name": "tooltipGroup",
|
||||
"encode": {
|
||||
"update": {
|
||||
"x": [
|
||||
{
|
||||
test:
|
||||
"inrange(datum.argmin.relTime + 80, domain('xrelscale'))",
|
||||
scale: 'xrelscale',
|
||||
field: 'argmin.relTime'
|
||||
"test": "inrange(datum.argmin.relTime + 80, domain('xrelscale'))",
|
||||
"scale": "xrelscale",
|
||||
"field": "argmin.relTime"
|
||||
},
|
||||
{ scale: 'xrelscale', field: 'argmin.relTime', offset: -80 }
|
||||
{
|
||||
"scale": "xrelscale",
|
||||
"field": "argmin.relTime",
|
||||
"offset": -80
|
||||
}
|
||||
],
|
||||
y: { scale: 'yscale', field: 'argmin.y' },
|
||||
height: { value: 20 },
|
||||
width: { value: 80 },
|
||||
fill: { value: '#fff' },
|
||||
fillOpacity: { value: 0.85 },
|
||||
stroke: { value: '#aaa' },
|
||||
strokeWidth: { value: 0.5 }
|
||||
"y": {
|
||||
"scale": "yscale",
|
||||
"field": "argmin.y"
|
||||
},
|
||||
"height": {
|
||||
"value": 20
|
||||
},
|
||||
"width": {
|
||||
"value": 80
|
||||
},
|
||||
"fill": {
|
||||
"value": "#fff"
|
||||
},
|
||||
"fillOpacity": {
|
||||
"value": 0.85
|
||||
},
|
||||
"stroke": {
|
||||
"value": "#aaa"
|
||||
},
|
||||
"strokeWidth": {
|
||||
"value": 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
marks: [
|
||||
"marks": [
|
||||
{
|
||||
type: 'text',
|
||||
interactive: false,
|
||||
encode: {
|
||||
update: {
|
||||
text: {
|
||||
signal:
|
||||
"format(parent.argmin.relTime, ',.2f') + ': ' + format(parent.argmin.y, ',.2f') + ' ' + parent.argmin.unit"
|
||||
"type": "text",
|
||||
"interactive": false,
|
||||
"encode": {
|
||||
"update": {
|
||||
"text": {
|
||||
"signal": "format(parent.argmin.relTime, ',.2f') + ': ' + format(parent.argmin.y, ',.2f') + ' ' + parent.argmin.unit"
|
||||
},
|
||||
fill: { value: 'black' },
|
||||
fontWeight: { value: 'bold' },
|
||||
y: { value: 20 }
|
||||
"fill": {
|
||||
"value": "black"
|
||||
},
|
||||
"fontWeight": {
|
||||
"value": "bold"
|
||||
},
|
||||
"y": {
|
||||
"value": 20
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'rect',
|
||||
name: 'boundingRect',
|
||||
interactive: true,
|
||||
encode: {
|
||||
enter: {
|
||||
width: { signal: 'width' },
|
||||
height: { signal: 'height' },
|
||||
fill: { value: 'transparent' }
|
||||
"type": "rect",
|
||||
"name": "boundingRect",
|
||||
"interactive": true,
|
||||
"encode": {
|
||||
"enter": {
|
||||
"width": {
|
||||
"signal": "width"
|
||||
},
|
||||
"height": {
|
||||
"signal": "height"
|
||||
},
|
||||
"fill": {
|
||||
"value": "transparent"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue