Skip to content

Commit

Permalink
feat: optimize data update (#61)
Browse files Browse the repository at this point in the history
* feat: optimize data update

* feat: optimize data update

* fix: avoid listener crashing
  • Loading branch information
kristw committed Sep 22, 2019
1 parent a7e36f1 commit 8e1baab
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 22 deletions.
39 changes: 19 additions & 20 deletions packages/react-vega/src/Vega.tsx
Expand Up @@ -5,9 +5,10 @@ import isFunction from './utils/isFunction';
import { PlainObject, View, ViewListener } from './types';
import shallowEqual from './utils/shallowEqual';
import { NOOP } from './constants';
import getDatasetNamesFromSpec from './utils/getDatasetNamesFromSpec';

export type VegaProps = VegaEmbedProps & {
data: PlainObject;
data?: PlainObject;
};

function updateData(view: View, name: string, value: any) {
Expand All @@ -26,7 +27,13 @@ function updateData(view: View, name: string, value: any) {
}
}

const EMPTY = {};

export default class Vega extends React.PureComponent<VegaProps> {
static defaultProps = {
data: EMPTY,
};

vegaEmbed = React.createRef<VegaEmbed>();

componentDidMount() {
Expand All @@ -47,26 +54,18 @@ export default class Vega extends React.PureComponent<VegaProps> {

update() {
const { data, spec } = this.props;
if (this.vegaEmbed.current) {
this.vegaEmbed.current.modifyView(view => {
if (data && spec.data) {
if (Array.isArray(spec.data)) {
// Array of data
spec.data
.filter(({ name }) => data[name])
.forEach(({ name }) => {
updateData(view, name, data[name]);
});
} else {
// Single data
const { name } = spec.data;
if (typeof name === 'string') {
updateData(view, name, data[name]);
}
}

if (data) {
const datasetNames = getDatasetNamesFromSpec(spec).filter(name => data[name]);

if (this.vegaEmbed.current && datasetNames.length > 0) {
this.vegaEmbed.current.modifyView(view => {
datasetNames.forEach(name => {
updateData(view, name, data[name]);
});
view.run();
}
});
});
}
}
}

Expand Down
7 changes: 5 additions & 2 deletions packages/react-vega/src/VegaEmbed.tsx
Expand Up @@ -66,7 +66,7 @@ export default class VegaEmbed extends React.PureComponent<VegaEmbedProps> {
};

createView() {
const { spec, onNewView = NOOP, onError = NOOP, signalListeners = {}, ...options } = this.props;
const { spec, onNewView, onError = NOOP, signalListeners = {}, ...options } = this.props;
if (this.containerRef.current) {
this.viewPromise = vegaEmbed(this.containerRef.current, spec, options)
.then(({ view }) => {
Expand All @@ -81,11 +81,14 @@ export default class VegaEmbed extends React.PureComponent<VegaEmbedProps> {
if (signalNames.length > 0) {
view.run();
}
onNewView(view);

return view;
})
.catch(this.handleError);

if (onNewView) {
this.modifyView(onNewView);
}
}
}

Expand Down
16 changes: 16 additions & 0 deletions packages/react-vega/src/utils/getDatasetNamesFromSpec.ts
@@ -0,0 +1,16 @@
import { VisualizationSpec } from 'vega-embed';

export default function getDatasetNamesFromSpec(spec: VisualizationSpec) {
const { data } = spec;
if (data) {
if (Array.isArray(data)) {
// Array of data
return data.map(({ name }) => name);
} else if (typeof data.name === 'string') {
// Single data
return [data.name];
}
}

return [];
}

0 comments on commit 8e1baab

Please sign in to comment.