diff --git a/src-trader-dashboard/components/FxQuoteMatrix.jsx b/src-trader-dashboard/components/FxQuoteMatrix.jsx index 74e684e..f005bb1 100644 --- a/src-trader-dashboard/components/FxQuoteMatrix.jsx +++ b/src-trader-dashboard/components/FxQuoteMatrix.jsx @@ -16,6 +16,9 @@ class FxQuoteMatrix extends Component { // grid events this.onGridReady = this.onGridReady.bind(this); + + // grid callbacks + this.getRowNodeId = this.getRowNodeId.bind(this); } onGridReady(params) { @@ -27,34 +30,31 @@ class FxQuoteMatrix extends Component { } } + getRowNodeId(data) { + return data.symbol; + } + componentWillReceiveProps(nextProps) { const newRowData = nextProps.rowData; - const updatedNodes = []; - const updatedCols = []; + const updatedRows = []; for (let i = 0; i < newRowData.length; i++) { - // note that for this use case we assume the existing and new row data have the same - // row and column order - let node = this.gridApi.getModel().getRow(i); let newRow = newRowData[i]; + let currentRowNode = this.gridApi.getRowNode(newRow.symbol); - const {data} = node; - let updated = false; + const {data} = currentRowNode; for (const def of this.state.columnDefs) { if (data[def.field] !== newRow[def.field]) { - updatedCols.push(def.field); - - updated = true; + updatedRows.push(newRow); + break; } } - if (updated) { - assign(data, newRow); - updatedNodes.push(node); - } } - this.gridApi.refreshCells(updatedNodes, uniq(updatedCols)); + + this.gridApi.updateRowData({update: updatedRows}); + } render() { @@ -67,6 +67,9 @@ class FxQuoteMatrix extends Component { enableSorting="false" enableFilter="false" + // callbacks + getRowNodeId={this.getRowNodeId} + // events onGridReady={this.onGridReady}> diff --git a/src-trader-dashboard/components/PriceChangesGrid.jsx b/src-trader-dashboard/components/PriceChangesGrid.jsx index 9daf03f..860159a 100644 --- a/src-trader-dashboard/components/PriceChangesGrid.jsx +++ b/src-trader-dashboard/components/PriceChangesGrid.jsx @@ -6,7 +6,6 @@ import map from "lodash/map"; import difference from "lodash/difference"; import forEach from "lodash/forEach"; import includes from "lodash/includes"; -import assign from "lodash/assign"; import ExchangeService from "../services/ExchangeService.jsx"; @@ -51,6 +50,9 @@ export default class extends Component { this.onGridReady = this.onGridReady.bind(this); this.onSelectionChanged = this.onSelectionChanged.bind(this); + // grid callbacks + this.getRowNodeId = this.getRowNodeId.bind(this); + // component events this.updateSymbol = this.updateSymbol.bind(this); } @@ -69,7 +71,7 @@ export default class extends Component { // make realistic - call in a batch let rowData = map(this.props.selectedExchange.supportedStocks, symbol => this.exchangeService.getTicker(symbol)); - this.gridApi.addItems(rowData); + this.gridApi.updateRowData({add: rowData}); // select the first symbol to show the chart this.gridApi.getModel().getRow(0).setSelected(true); @@ -77,6 +79,10 @@ export default class extends Component { this.gridApi.sizeColumnsToFit(); } + getRowNodeId(data) { + return data.symbol; + } + onSelectionChanged() { let selectedNode = this.gridApi.getSelectedNodes()[0]; this.props.onSelectionChanged(selectedNode ? selectedNode.data.symbol : null); @@ -108,25 +114,25 @@ export default class extends Component { this.exchangeService.removeSubscriber(this.updateSymbol, symbol); }); + // Remove ag-grid nodes as necessary + const rowsToRemove = []; + this.gridApi.forEachNode(node => { + const {data} = node; + if (includes(symbolsRemoved, data.symbol)) { + rowsToRemove.push(data); + } + }); + this.gridApi.updateRowData({remove: rowsToRemove}); + // Subscribe to new ones that need to be added const symbolsAdded = difference(nextSymbols, currentSymbols); forEach(symbolsAdded, symbol => { this.exchangeService.addSubscriber(this.updateSymbol, symbol); }); - // Remove ag-grid nodes as necessary - const nodesToRemove = []; - this.gridApi.forEachNode(node => { - const {data} = node; - if (includes(symbolsRemoved, data.symbol)) { - nodesToRemove.push(node); - } - }); - this.gridApi.removeItems(nodesToRemove); - // Insert new ag-grid nodes as necessary let rowData = map(symbolsAdded, symbol => this.exchangeService.getTicker(symbol)); - this.gridApi.addItems(rowData); + this.gridApi.updateRowData({add: rowData}); // select the first symbol to show the chart this.gridApi.getModel().getRow(0).setSelected(true); @@ -139,24 +145,8 @@ export default class extends Component { return; } - const updatedNodes = []; - const updatedCols = []; - - this.gridApi.forEachNode(node => { - const {data} = node; - if (data.symbol === symbol.symbol) { - for (const def of this.state.columnDefs) { - if (data[def.field] !== symbol[def.field]) { - updatedCols.push(def.field); - } - } - assign(data, symbol); - updatedNodes.push(node); - } - }); - - this.gridApi.refreshCells(updatedNodes, updatedCols); - }; + this.gridApi.updateRowData({update: [symbol]}); + } render() { return ( @@ -168,6 +158,9 @@ export default class extends Component { enableSorting="true" rowSelection="single" + // callbacks + getRowNodeId={this.getRowNodeId} + // events onGridReady={this.onGridReady} onSelectionChanged={this.onSelectionChanged}> diff --git a/src-trader-dashboard/components/TopMoversGrid.jsx b/src-trader-dashboard/components/TopMoversGrid.jsx index 1e6fa96..49214ee 100644 --- a/src-trader-dashboard/components/TopMoversGrid.jsx +++ b/src-trader-dashboard/components/TopMoversGrid.jsx @@ -43,6 +43,8 @@ class TopMoversGrid extends Component { // grid events this.onGridReady = this.onGridReady.bind(this); + + // grid callbacks this.getRowNodeId = this.getRowNodeId.bind(this); } diff --git a/src-trader-dashboard/services/ExchangeService.jsx b/src-trader-dashboard/services/ExchangeService.jsx index 90e0e80..1203768 100644 --- a/src-trader-dashboard/services/ExchangeService.jsx +++ b/src-trader-dashboard/services/ExchangeService.jsx @@ -1,5 +1,4 @@ import concat from "lodash/concat"; -import remove from "lodash/remove"; import uniq from "lodash/uniq"; import find from "lodash/find"; import sampleSize from "lodash/sampleSize"; @@ -26,7 +25,12 @@ export default class { } removeSubscriber(subscriber, symbol) { - remove(this.subscribers[symbol], subscriber); + let subscribers = this.subscribers[symbol]; + subscribers.splice(subscribers.indexOf(subscriber), 1); + } + + removeSubscribers() { + this.subscribers = {}; } getTicker(symbol) {