Skip to content

Commit

Permalink
feat: store reference to container and update bindings (#180)
Browse files Browse the repository at this point in the history
* feat: store reference to container

* fix: minor adjustment

* feat: forward ref from shell to superchart
  • Loading branch information
kristw authored and zhaoyongjie committed Nov 26, 2021
1 parent 135084c commit 9f8461b
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,17 @@ type PropsWithDefault = Props & Readonly<typeof defaultProps>;
export default class SuperChart extends React.PureComponent<Props, {}> {
static defaultProps = defaultProps;

/**
* SuperChart's core
*/
core?: SuperChartCore | null;

private createChartProps = ChartProps.createSelector();

private setRef = (core: SuperChartCore | null) => {
this.core = core;
};

renderChart(width: number, height: number) {
const {
id,
Expand All @@ -50,6 +59,7 @@ export default class SuperChart extends React.PureComponent<Props, {}> {

const chart = (
<SuperChartCore
ref={this.setRef}
id={id}
className={className}
chartType={chartType}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { createSelector } from 'reselect';
import getChartComponentRegistry from '../registries/ChartComponentRegistrySingleton';
import getChartTransformPropsRegistry from '../registries/ChartTransformPropsRegistrySingleton';
import ChartProps from '../models/ChartProps';
import createLoadableRenderer, { LoadableRenderer } from './createLoadableRenderer';
import createLoadableRenderer from './createLoadableRenderer';
import { ChartType } from '../models/ChartPlugin';
import { PreTransformProps, TransformProps, PostTransformProps } from '../types/TransformFunction';
import { HandlerFunction } from '../types/Base';
Expand Down Expand Up @@ -56,78 +56,70 @@ export type Props = {
export default class SuperChartCore extends React.PureComponent<Props, {}> {
static defaultProps = defaultProps;

processChartProps: (input: {
chartProps: ChartProps;
preTransformProps?: PreTransformProps;
transformProps?: TransformProps;
postTransformProps?: PostTransformProps;
}) => any;

createLoadableRenderer: (input: {
chartType: string;
overrideTransformProps?: TransformProps;
}) => LoadableRenderer<RenderProps, LoadedModules> | (() => null);

constructor(props: Props) {
super(props);

this.renderChart = this.renderChart.bind(this);
this.renderLoading = this.renderLoading.bind(this);

// memoized function so it will not recompute
// and return previous value
// unless one of
// - preTransformProps
// - transformProps
// - postTransformProps
// - chartProps
// is changed.
this.processChartProps = createSelector(
input => input.preTransformProps,
input => input.transformProps,
input => input.postTransformProps,
input => input.chartProps,
(pre = IDENTITY, transform = IDENTITY, post = IDENTITY, chartProps) =>
post(transform(pre(chartProps))),
);

const componentRegistry = getChartComponentRegistry();
const transformPropsRegistry = getChartTransformPropsRegistry();

// memoized function so it will not recompute
// and return previous value
// unless one of
// - chartType
// - overrideTransformProps
// is changed.
this.createLoadableRenderer = createSelector(
input => input.chartType,
input => input.overrideTransformProps,
(chartType, overrideTransformProps) => {
if (chartType) {
const Renderer = createLoadableRenderer({
loader: {
Chart: () => componentRegistry.getAsPromise(chartType),
transformProps: overrideTransformProps
? () => Promise.resolve(overrideTransformProps)
: () => transformPropsRegistry.getAsPromise(chartType),
},
loading: (loadingProps: LoadingProps) => this.renderLoading(loadingProps, chartType),
render: this.renderChart,
});

// Trigger preloading.
Renderer.preload();

return Renderer;
}

return EMPTY;
},
);
}

renderChart(loaded: LoadedModules, props: RenderProps) {
/**
* The HTML element that wraps all chart content
*/
container?: HTMLElement | null;

/**
* memoized function so it will not recompute
* and return previous value
* unless one of
* - preTransformProps
* - transformProps
* - postTransformProps
* - chartProps
* is changed.
*/
processChartProps = createSelector(
(input: {
chartProps: ChartProps;
preTransformProps?: PreTransformProps;
transformProps?: TransformProps;
postTransformProps?: PostTransformProps;
}) => input.preTransformProps,
input => input.transformProps,
input => input.postTransformProps,
input => input.chartProps,
(pre = IDENTITY, transform = IDENTITY, post = IDENTITY, chartProps) =>
post(transform(pre(chartProps))),
);

/**
* memoized function so it will not recompute
* and return previous value
* unless one of
* - chartType
* - overrideTransformProps
* is changed.
*/
private createLoadableRenderer = createSelector(
(input: { chartType: string; overrideTransformProps?: TransformProps }) => input.chartType,
input => input.overrideTransformProps,
(chartType, overrideTransformProps) => {
if (chartType) {
const Renderer = createLoadableRenderer({
loader: {
Chart: () => getChartComponentRegistry().getAsPromise(chartType),
transformProps: overrideTransformProps
? () => Promise.resolve(overrideTransformProps)
: () => getChartTransformPropsRegistry().getAsPromise(chartType),
},
loading: (loadingProps: LoadingProps) => this.renderLoading(loadingProps, chartType),
render: this.renderChart,
});

// Trigger preloading.
Renderer.preload();

return Renderer;
}

return EMPTY;
},
);

private renderChart = (loaded: LoadedModules, props: RenderProps) => {
const { Chart, transformProps } = loaded;
const { chartProps, preTransformProps, postTransformProps } = props;

Expand All @@ -143,9 +135,9 @@ export default class SuperChartCore extends React.PureComponent<Props, {}> {
})}
/>
);
}
};

renderLoading(loadingProps: LoadingProps, chartType: string) {
private renderLoading = (loadingProps: LoadingProps, chartType: string) => {
const { error } = loadingProps;

if (error) {
Expand All @@ -159,7 +151,11 @@ export default class SuperChartCore extends React.PureComponent<Props, {}> {
}

return null;
}
};

private setRef = (container: HTMLElement | null) => {
this.container = container;
};

render() {
const {
Expand Down Expand Up @@ -195,7 +191,7 @@ export default class SuperChartCore extends React.PureComponent<Props, {}> {
}

return (
<div {...containerProps}>
<div {...containerProps} ref={this.setRef}>
<Renderer
preTransformProps={preTransformProps}
postTransformProps={postTransformProps}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type ClassicProps = Omit<

export type Props = ClassicProps | SuperChartProps;

export default function SuperChartShell(props: Props) {
const SuperChartShell = React.forwardRef<SuperChart, Props>((props, ref) => {
if ('chartProps' in props) {
const { chartProps, ...rest } = props;

Expand All @@ -42,6 +42,7 @@ export default function SuperChartShell(props: Props) {

return (
<SuperChart
ref={ref}
{...rest}
annotationData={annotationData}
datasource={datasource}
Expand All @@ -58,5 +59,7 @@ export default function SuperChartShell(props: Props) {
);
}

return <SuperChart {...props} />;
}
return <SuperChart ref={ref} {...props} />;
});

export default SuperChartShell;

0 comments on commit 9f8461b

Please sign in to comment.