Skip to content

Commit

Permalink
feat(chart_state): add render change event (#365)
Browse files Browse the repository at this point in the history
add onRenderChange event to settings
  • Loading branch information
nickofthyme authored Sep 4, 2019
1 parent 94d5a51 commit 521889b
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 5 deletions.
30 changes: 30 additions & 0 deletions src/chart_types/xy_chart/store/chart_state.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,33 @@ describe('Chart Store', () => {
expect(store.onCursorUpdateListener).toEqual(listener);
});

test('can set a render change listener', () => {
const listener = (): void => {
return;
};
store.setOnRenderChangeListener(listener);

expect(store.onRenderChangeListener).toEqual(listener);
});

test('should observe chartInitialized value', () => {
const listener = jest.fn();
store.chartInitialized.set(false);
store.setOnRenderChangeListener(listener);
store.chartInitialized.set(true);

expect(listener).toBeCalledWith(true);
});

test('should observe chartInitialized value only on change', () => {
const listener = jest.fn();
store.chartInitialized.set(false);
store.setOnRenderChangeListener(listener);
store.chartInitialized.set(false);

expect(listener).not.toBeCalled();
});

test('can remove listeners', () => {
store.removeElementClickListener();
expect(store.onElementClickListener).toBeUndefined();
Expand All @@ -335,6 +362,9 @@ describe('Chart Store', () => {

store.removeOnCursorUpdateListener();
expect(store.onCursorUpdateListener).toBeUndefined();

store.removeOnRenderChangeListener();
expect(store.onRenderChangeListener).toBeUndefined();
});

test('can respond to a brush end event', () => {
Expand Down
28 changes: 24 additions & 4 deletions src/chart_types/xy_chart/store/chart_state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,13 @@ export type ElementOverListener = (values: GeometryValue[]) => void;
export type BrushEndListener = (min: number, max: number) => void;
export type LegendItemListener = (dataSeriesIdentifiers: DataSeriesColorsValues | null) => void;
export type CursorUpdateListener = (event?: CursorEvent) => void;
/**
* Listener to be called when chart render state changes
*
* `isRendered` value is `true` when rendering is complete and `false` otherwise
*/
export type RenderChangeListener = (isRendered: boolean) => void;
export type BasicListener = () => undefined | void;

export class ChartStore {
constructor(id?: string) {
Expand Down Expand Up @@ -206,15 +213,16 @@ export class ChartStore {

onElementClickListener?: ElementClickListener;
onElementOverListener?: ElementOverListener;
onElementOutListener?: () => undefined | void;
onElementOutListener?: BasicListener;
onBrushEndListener?: BrushEndListener;
onLegendItemOverListener?: LegendItemListener;
onLegendItemOutListener?: () => undefined | void;
onLegendItemOutListener?: BasicListener;
onLegendItemClickListener?: LegendItemListener;
onLegendItemPlusClickListener?: LegendItemListener;
onLegendItemMinusClickListener?: LegendItemListener;
onLegendItemVisibilityToggleClickListener?: LegendItemListener;
onCursorUpdateListener?: CursorUpdateListener;
onRenderChangeListener?: RenderChangeListener;

geometries: {
points: PointGeometry[];
Expand Down Expand Up @@ -698,7 +706,7 @@ export class ChartStore {
setOnElementOverListener(listener: ElementOverListener) {
this.onElementOverListener = listener;
}
setOnElementOutListener(listener: () => undefined | void) {
setOnElementOutListener(listener: BasicListener) {
this.onElementOutListener = listener;
}
setOnBrushEndListener(listener: BrushEndListener) {
Expand All @@ -707,7 +715,7 @@ export class ChartStore {
setOnLegendItemOverListener(listener: LegendItemListener) {
this.onLegendItemOverListener = listener;
}
setOnLegendItemOutListener(listener: () => undefined | void) {
setOnLegendItemOutListener(listener: BasicListener) {
this.onLegendItemOutListener = listener;
}
setOnLegendItemClickListener(listener: LegendItemListener) {
Expand All @@ -722,6 +730,15 @@ export class ChartStore {
setOnCursorUpdateListener(listener: CursorUpdateListener) {
this.onCursorUpdateListener = listener;
}
setOnRenderChangeListener(listener: RenderChangeListener) {
this.onRenderChangeListener = listener;

this.chartInitialized.observe(({ newValue, oldValue }) => {
if (this.onRenderChangeListener && newValue !== oldValue) {
this.onRenderChangeListener(newValue);
}
});
}
removeElementClickListener() {
this.onElementClickListener = undefined;
}
Expand All @@ -746,6 +763,9 @@ export class ChartStore {
removeOnCursorUpdateListener() {
this.onCursorUpdateListener = undefined;
}
removeOnRenderChangeListener() {
this.onRenderChangeListener = undefined;
}

isBrushEnabled(): boolean {
if (!this.xScale) {
Expand Down
3 changes: 3 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,7 @@ export {
ElementClickListener,
ElementOverListener,
LegendItemListener,
CursorUpdateListener,
RenderChangeListener,
BasicListener,
} from './chart_types/xy_chart/store/chart_state';
5 changes: 5 additions & 0 deletions src/specs/settings.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ describe('Settings spec component', () => {
const onCursorUpdateEvent = (): void => {
return;
};
const onRenderChangeEvent = (): void => {
return;
};

const chartStoreListeners = {
onElementClick,
Expand All @@ -140,6 +143,7 @@ describe('Settings spec component', () => {
onLegendItemPlusClick: onLegendEvent,
onLegendItemMinusClick: onLegendEvent,
onCursorUpdate: onCursorUpdateEvent,
onRenderChange: onRenderChangeEvent,
};

mount(<SettingsComponent chartStore={chartStore} {...chartStoreListeners} />);
Expand All @@ -153,6 +157,7 @@ describe('Settings spec component', () => {
expect(chartStore.onLegendItemPlusClickListener).toEqual(onLegendEvent);
expect(chartStore.onLegendItemMinusClickListener).toEqual(onLegendEvent);
expect(chartStore.onCursorUpdateListener).toEqual(onCursorUpdateEvent);
expect(chartStore.onRenderChangeListener).toEqual(onRenderChangeEvent);
});

test('should allow partial theme', () => {
Expand Down
6 changes: 6 additions & 0 deletions src/specs/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
ElementOverListener,
LegendItemListener,
CursorUpdateListener,
RenderChangeListener,
} from '../chart_types/xy_chart/store/chart_state';
import { ScaleTypes } from '../utils/scales/scales';
import { LIGHT_THEME } from '../utils/themes/light_theme';
Expand Down Expand Up @@ -87,6 +88,7 @@ export interface SettingSpecProps {
onLegendItemPlusClick?: LegendItemListener;
onLegendItemMinusClick?: LegendItemListener;
onCursorUpdate?: CursorUpdateListener;
onRenderChange?: RenderChangeListener;
xDomain?: Domain | DomainRange;
resizeDebounce?: number;
}
Expand Down Expand Up @@ -123,6 +125,7 @@ function updateChartStore(props: SettingSpecProps) {
onLegendItemClick,
onLegendItemMinusClick,
onLegendItemPlusClick,
onRenderChange,
onCursorUpdate,
debug,
xDomain,
Expand Down Expand Up @@ -187,6 +190,9 @@ function updateChartStore(props: SettingSpecProps) {
if (onCursorUpdate) {
chartStore.setOnCursorUpdateListener(onCursorUpdate);
}
if (onRenderChange) {
chartStore.setOnRenderChangeListener(onRenderChange);
}
}

export class SettingsComponent extends PureComponent<SettingSpecProps> {
Expand Down
64 changes: 63 additions & 1 deletion stories/interactions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ const onLegendItemListeners = {
onLegendItemMinusClick: action('onLegendItemMinusClick'),
};

const onRenderChange = action('onRenderChange');
const onCursorUpdate = action('onCursorUpdate');

storiesOf('Interactions', module)
.add('bar clicks and hovers', () => {
const headerFormatter: TooltipValueFormatter = (tooltipData: TooltipValue) => {
Expand Down Expand Up @@ -573,4 +576,63 @@ storiesOf('Interactions', module)
/>
</Chart>
);
});
})
.add(
'Render change action',
() => {
return (
<Chart className={'story-chart'}>
<Settings showLegend={true} legendPosition={Position.Right} onRenderChange={onRenderChange} />
<Axis id={getAxisId('bottom')} position={Position.Bottom} title={'Bottom axis'} showOverlappingTicks={true} />
<Axis
id={getAxisId('left2')}
title={'Left axis'}
position={Position.Left}
tickFormat={(d) => Number(d).toFixed(2)}
/>

<BarSeries
id={getSpecId('bars')}
xScaleType={ScaleType.Linear}
yScaleType={ScaleType.Linear}
xAccessor="x"
yAccessors={['y']}
data={[{ x: 0, y: 2 }, { x: 1, y: 7 }, { x: 2, y: 3 }, { x: 3, y: 6 }]}
/>
</Chart>
);
},
{
info:
'Sends an event every time the chart render state changes. This is provided to bind attributes to the chart for visulaization loading checks.',
},
)
.add(
'Cursor update action',
() => {
return (
<Chart className={'story-chart'}>
<Settings showLegend={true} legendPosition={Position.Right} onCursorUpdate={onCursorUpdate} />
<Axis id={getAxisId('bottom')} position={Position.Bottom} title={'Bottom axis'} showOverlappingTicks={true} />
<Axis
id={getAxisId('left2')}
title={'Left axis'}
position={Position.Left}
tickFormat={(d) => Number(d).toFixed(2)}
/>

<BarSeries
id={getSpecId('bars')}
xScaleType={ScaleType.Linear}
yScaleType={ScaleType.Linear}
xAccessor="x"
yAccessors={['y']}
data={[{ x: 0, y: 2 }, { x: 1, y: 7 }, { x: 2, y: 3 }, { x: 3, y: 6 }]}
/>
</Chart>
);
},
{
info: 'Sends an event every time the cursor changes. This is provided to sync cursors between multiple charts.',
},
);

0 comments on commit 521889b

Please sign in to comment.