diff --git a/app/src/components/ChartPanel/ChartActions.tsx b/app/src/components/ChartPanel/ChartActions.tsx
index c10b77c..e83ffb4 100644
--- a/app/src/components/ChartPanel/ChartActions.tsx
+++ b/app/src/components/ChartPanel/ChartActions.tsx
@@ -1,4 +1,4 @@
-import * as React from 'react'
+import React, { useRef } from 'react'
import Play from '@material-ui/icons/PlayArrow'
import Pause from '@material-ui/icons/PauseCircleFilled'
import Clear from '@material-ui/icons/Clear'
@@ -11,16 +11,24 @@ export function ChartActions(props: {
togglePause: () => void
parameters: ChartParameters
onRemove: () => void
+ resetDataAction: () => void
}) {
+ const menuAnchor = useRef()
return (
{props.paused ? : }
-
+
+
+ {/* Helper element to provide an anchor element for the menu,
+ * so the menu prefers not to overlap with the chart
+ */}
+
+
)
}
diff --git a/app/src/components/ChartPanel/ChartSettings/MoveUp.tsx b/app/src/components/ChartPanel/ChartSettings/MoveUp.tsx
index 9b542f9..f1db8c5 100644
--- a/app/src/components/ChartPanel/ChartSettings/MoveUp.tsx
+++ b/app/src/components/ChartPanel/ChartSettings/MoveUp.tsx
@@ -1,9 +1,10 @@
import * as React from 'react'
-import { ChartParameters } from '../../../reducers/Charts'
-import { Menu, MenuItem, TextField, Typography } from '@material-ui/core'
-import { connect } from 'react-redux'
+import ArrowUpward from '@material-ui/icons/ArrowUpward'
import { bindActionCreators } from 'redux'
import { chartActions } from '../../../actions'
+import { ChartParameters } from '../../../reducers/Charts'
+import { connect } from 'react-redux'
+import { MenuItem, Typography, ListItemIcon } from '@material-ui/core'
function MoveUp(props: { actions: { chart: typeof chartActions }; chart: ChartParameters; close: () => void }) {
const moveUp = React.useCallback(() => {
@@ -16,7 +17,10 @@ function MoveUp(props: { actions: { chart: typeof chartActions }; chart: ChartPa
return (
)
}
diff --git a/app/src/components/ChartPanel/ChartSettings/RangeSettings.tsx b/app/src/components/ChartPanel/ChartSettings/RangeSettings.tsx
index 034e33c..042b40b 100644
--- a/app/src/components/ChartPanel/ChartSettings/RangeSettings.tsx
+++ b/app/src/components/ChartPanel/ChartSettings/RangeSettings.tsx
@@ -56,8 +56,8 @@ function RangeSettings(props: Props) {
onClose={props.onClose}
onKeyDownCapture={handleKeyEvents}
>
- Define custom ranges for the Y-Axis
-
+
+
Define custom ranges for the Y-Axis
void
+ menuAnchor: React.MutableRefObject
+}) {
const [visible, setVisible] = React.useState(false)
- const settingsRef = React.useRef()
const toggleSettings = React.useCallback(() => {
setVisible(!visible)
}, [visible])
@@ -17,10 +20,15 @@ export function SettingsButton(props: { parameters: ChartParameters }) {
return (
-
+
diff --git a/app/src/components/ChartPanel/ChartSettings/Size.tsx b/app/src/components/ChartPanel/ChartSettings/Size.tsx
index bbcfa0f..66796fd 100644
--- a/app/src/components/ChartPanel/ChartSettings/Size.tsx
+++ b/app/src/components/ChartPanel/ChartSettings/Size.tsx
@@ -24,16 +24,16 @@ function Size(props: {
return (
)
diff --git a/app/src/components/ChartPanel/ChartSettings/index.tsx b/app/src/components/ChartPanel/ChartSettings/index.tsx
index 5d8501a..4858eff 100644
--- a/app/src/components/ChartPanel/ChartSettings/index.tsx
+++ b/app/src/components/ChartPanel/ChartSettings/index.tsx
@@ -1,16 +1,22 @@
-import * as React from 'react'
+import BarChart from '@material-ui/icons/BarChart'
+import Clear from '@material-ui/icons/Refresh'
+import ColorLens from '@material-ui/icons/ColorLens'
import ColorSettings from './ColorSettings'
import InterpolationSettings from './InterpolationSettings'
import MoveUp from './MoveUp'
+import MultiLineChart from '@material-ui/icons/MultiLineChart'
import RangeSettings from './RangeSettings'
+import React, { memo } from 'react'
import Size from './Size'
+import Sort from '@material-ui/icons/Sort'
import TimeRangeSettings from './TimeRangeSettings'
import { ChartParameters } from '../../../reducers/Charts'
-import { Menu, MenuItem } from '@material-ui/core'
+import { Menu, MenuItem, ListItemIcon, Typography } from '@material-ui/core'
function ChartSettings(props: {
open: boolean
close: () => void
+ resetDataAction: () => void
chart: ChartParameters
anchorEl: React.MutableRefObject
}) {
@@ -59,19 +65,40 @@ function ChartSettings(props: {
@@ -94,4 +121,4 @@ function ChartSettings(props: {
)
}
-export default ChartSettings
+export default memo(ChartSettings)
diff --git a/app/src/components/ChartPanel/TopicChart.tsx b/app/src/components/ChartPanel/TopicChart.tsx
index 689be60..8fbba9c 100644
--- a/app/src/components/ChartPanel/TopicChart.tsx
+++ b/app/src/components/ChartPanel/TopicChart.tsx
@@ -1,16 +1,31 @@
import * as q from '../../../../backend/src/Model'
-import React, { useState } from 'react'
+import ChartTitle from './ChartTitle'
+import React, { useState, useCallback, memo, useRef } from 'react'
import TopicPlot from '../TopicPlot'
import { bindActionCreators } from 'redux'
+import { ChartActions } from './ChartActions'
import { chartActions } from '../../actions'
import { ChartParameters } from '../../reducers/Charts'
import { connect } from 'react-redux'
import { Paper } from '@material-ui/core'
-import ChartTitle from './ChartTitle'
-import { ChartActions } from './ChartActions'
-import { RingBuffer } from '../../../../backend/src/Model'
const throttle = require('lodash.throttle')
+class ClearableMessageBuffer extends q.RingBuffer {
+ public clear() {
+ this.items = []
+ this.start = 0
+ this.end = 0
+ }
+
+ public static fromMessageBuffer(buffer: q.RingBuffer): ClearableMessageBuffer {
+ return new ClearableMessageBuffer(buffer.capacity, buffer.maxItems, buffer.compactionFactor, buffer)
+ }
+
+ public clone(): ClearableMessageBuffer {
+ return ClearableMessageBuffer.fromMessageBuffer(this)
+ }
+}
+
interface Props {
parameters: ChartParameters
treeNode?: q.TreeNode
@@ -24,14 +39,14 @@ interface Props {
*/
function useMessageSubscriptionToUpdate(treeNode?: q.TreeNode) {
const [lastUpdated, setLastUpdate] = useState(0)
- const [messageHistory, setMessageHistory] = useState()
+ const [messageHistory, setMessageHistory] = useState()
let amendMessageCallback: any
function subscribeToMessageUpdates() {
const throttledUpdate = throttle(() => setLastUpdate(treeNode ? treeNode.lastUpdate : 0), 300)
if (treeNode) {
- const newMessageHistory = treeNode.messageHistory.clone()
+ const newMessageHistory = ClearableMessageBuffer.fromMessageBuffer(treeNode.messageHistory)
newMessageHistory.setCapacity(500, 2 * 500 * 10000)
amendMessageCallback = (message: q.Message) => {
@@ -52,12 +67,21 @@ function useMessageSubscriptionToUpdate(treeNode?: q.TreeNode) {
return messageHistory
}
+function useResetDataCallback(messageHistory: ClearableMessageBuffer | undefined) {
+ const [lastUpdated, setLastUpdate] = useState(0)
+
+ return React.useCallback(() => {
+ messageHistory && messageHistory.clear()
+ setLastUpdate(Date.now())
+ }, [messageHistory])
+}
+
function TopicChart(props: Props) {
const { parameters, treeNode } = props
- const [frozenHistory, setFrozenHistory] = React.useState()
+ const [frozenHistory, setFrozenHistory] = useState()
const messageHistory = useMessageSubscriptionToUpdate(treeNode)
- const togglePause = React.useCallback(() => {
+ const togglePause = useCallback(() => {
if (!treeNode) {
return
}
@@ -69,6 +93,8 @@ function TopicChart(props: Props) {
props.actions.chart.removeChart(props.parameters)
}, [props.parameters])
+ const resetData = useResetDataCallback(messageHistory)
+
return (
(1)}
+ history={frozenHistory || messageHistory || new ClearableMessageBuffer(1)}
dotPath={parameters.dotPath}
/>
@@ -109,4 +136,4 @@ const mapDispatchToProps = (dispatch: any) => {
export default connect(
undefined,
mapDispatchToProps
-)(TopicChart)
+)(memo(TopicChart))
diff --git a/app/src/components/ConfirmationDialog.tsx b/app/src/components/ConfirmationDialog.tsx
index d1972a3..2db7397 100644
--- a/app/src/components/ConfirmationDialog.tsx
+++ b/app/src/components/ConfirmationDialog.tsx
@@ -7,7 +7,7 @@ function ConfirmationDialog(props: { confirmationRequests: Array()
const noRef = useRef()
- const arrowKeyHandler = useCallback((event: KeyboardEvent) => {
+ const arrowKeyHandler = useCallback((event: React.KeyboardEvent) => {
const isArrowKey = event.keyCode === KeyCodes.arrow_left || event.keyCode === KeyCodes.arrow_right
if (!isArrowKey) {
return
@@ -45,10 +45,10 @@ function ConfirmationDialog(props: { confirmationRequests: Array{request.inquiry}
-
diff --git a/backend/src/Model/RingBuffer.ts b/backend/src/Model/RingBuffer.ts
index 727662b..d36960a 100644
--- a/backend/src/Model/RingBuffer.ts
+++ b/backend/src/Model/RingBuffer.ts
@@ -1,15 +1,15 @@
-interface Lengthwise {
+export interface MemoryConsumptionExpressedByLength {
length: number
}
-export class RingBuffer {
- private capacity: number
- private maxItems: number
+export class RingBuffer {
+ public capacity: number
+ public maxItems: number
+ public compactionFactor: number
+ protected items: Array = []
+ protected start: number = 0
+ protected end: number = 0
private usage: number = 0
- private items: Array = []
- private start: number = 0
- private end: number = 0
- private compactionFactor: number
constructor(capacity: number, maxItems = Infinity, compactionFactor: number = 10, ringBuffer?: RingBuffer) {
this.capacity = capacity
diff --git a/backend/src/Model/TreeNode.ts b/backend/src/Model/TreeNode.ts
index 296a248..7d8b6fe 100644
--- a/backend/src/Model/TreeNode.ts
+++ b/backend/src/Model/TreeNode.ts
@@ -52,10 +52,6 @@ export class TreeNode {
return this.sourceEdge ? this.sourceEdge.source || undefined : undefined
}
- public hasMessage() {
- return this.message && this.message.value && this.message.value.length !== 0
- }
-
private isTopicEmptyLeaf() {
return !this.hasMessage() && this.isLeaf()
}
@@ -108,6 +104,10 @@ export class TreeNode {
}
}
+ public hasMessage() {
+ return this.message && this.message.value && this.message.value.length !== 0
+ }
+
public destroy() {
this.onDestroy.dispatch(this)
this.onDestroy.removeAllListeners()