Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: show tooltip for external events #698

Merged
merged 19 commits into from
Jun 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 3 additions & 21 deletions .playground/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,15 @@
html,
body {
background: blanchedalmond !important;
/*margin-left: 8px !important;*/
/*padding: 8px !important;*/
/*height: 100%;*/
/*width: 2000px;
}
#root {
position: absolute;
/*
top: 0;
left: 0;
*/
/* width: 100%;
height: 100%;*/
/* overflow-x: hidden; */
}

#root {
height: 500px;
}

.chart {
background: white;
/*display: inline-block;
position: relative;
*/
width: 100%;
height: 500px;
width: 500px;
height: 200px;
overflow: auto;
}

Expand All @@ -47,7 +29,7 @@
}

.page {
padding: 100px;
padding: 10px;
}

label {
Expand Down
260 changes: 196 additions & 64 deletions .playground/playground.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,78 +17,210 @@
* under the License.
*/

import React, { useState } from 'react';

import { Chart, BarSeries, LegendColorPicker, Settings, ScaleType } from '../src';
import { SeededDataGenerator } from '../src/mocks/utils';

const dg = new SeededDataGenerator();

type SetColorFn = (color: string) => void;
const legendColorPickerFn = (setColors: SetColorFn, customColor: string): LegendColorPicker => ({ onClose }) => (
<div id="colorPicker">
<span>Custom Color Picker</span>
<button
id="change"
type="button"
onClick={() => {
setTimeout(() => {
onClose();
setColors(customColor);
}, 0);
}}
>
{customColor}
</button>
<button id="close" type="button" onClick={onClose}>
close
</button>
import React from 'react';

import {
Chart,
Settings,
Axis,
Position,
BarSeries,
ScaleType,
PointerEvent,
LineSeries,
CustomTooltip,
TooltipType,
LineAnnotation, AnnotationDomainTypes,
} from '../src';
import { KIBANA_METRICS } from '../src/utils/data_samples/test_dataset_kibana';


const TestCustomTooltip: CustomTooltip = (props) => (
<div style={{ border: '1px solid black', background: 'white', fontSize: 12, padding: 4 }}>
<p>Testing a custom tooltip </p>
<ul>
{
props.values.map((value) => (
<li key={value.label} style={{ color: value.color }}>
{value.label}
{' - '}
{value.value}
</li>
))
}
</ul>
</div>
);
function LegendColorPickerMock(props: { onLegendItemClick: () => void; customColor: string }) {
const data = dg.generateGroupedSeries(10, 4, 'split');
const [color, setColor] = useState('red');
export const Playground = () => {
const ref1 = React.createRef<Chart>();
const ref2 = React.createRef<Chart>();
const ref3 = React.createRef<Chart>();
const ref4 = React.createRef<Chart>();

const pointerUpdate = (event: PointerEvent) => {
if (ref1.current) {
ref1.current.dispatchExternalPointerEvent(event);
}
if (ref2.current) {
ref2.current.dispatchExternalPointerEvent(event);
}
if (ref3.current) {
ref3.current.dispatchExternalPointerEvent(event);
}
if (ref4.current) {
ref4.current.dispatchExternalPointerEvent(event);
}
};

return (
<>
<div className="testing">
<button
type="button"
onClick={() => {
setColor('violet');
// if (ref1.current) {
// ref1.current.dispatchExternalPointerEvent({
// chartId: 'chart1',
// type: 'Over',
// scale: 'time',
// value: 1551438420000,
// });
// }
if (ref1.current) {
ref1.current.dispatchExternalPointerEvent({ chartId: 'chart2', type: 'Over', unit: undefined, scale: 'time', value: 1551439800000 });
}
}}
>
change
out

</button>
<Chart className="chart">
<Settings
showLegend
onLegendItemClick={props.onLegendItemClick}
legendColorPicker={legendColorPickerFn(setColor, props.customColor)}
/>
<BarSeries
id="areas"
xScaleType={ScaleType.Linear}
yScaleType={ScaleType.Linear}
xAccessor="x"
yAccessors={['y']}
splitSeriesAccessors={['g']}
color={color}
data={data}
/>
</Chart>
</>
);
}

export class Playground extends React.Component {
render() {
return (
<LegendColorPickerMock
customColor="blue"
onLegendItemClick={() => {
// npo

<button
type="button"
onClick={() => {
if (ref1.current) {
ref1.current.dispatchExternalPointerEvent({ chartId: 'chart2', type: 'Over', unit: undefined, scale: 'time', value: 1551439770000 });
}
}}
/>
);
}
}
>
valid

</button>

<div className="chart">
<Chart className="story-chart" ref={ref1} id="chart1">
<Settings onPointerUpdate={pointerUpdate} externalPointerEvents={{ tooltip: { visible: true } }} />
<Axis
id="bottom"
position={Position.Bottom}
title="External tooltip VISIBLE"

/>
<Axis id="left2" position={Position.Left} tickFormat={(d: any) => Number(d).toFixed(2)} />
<LineAnnotation
marker={<div>Hello</div>}
dataValues={[{ dataValue: KIBANA_METRICS.metrics.kibana_os_load[0].data[10][0], details: 'hello' }]}
id="test"
domainType={AnnotationDomainTypes.XDomain}
/>
<BarSeries
id="bars"
xScaleType={ScaleType.Time}
yScaleType={ScaleType.Linear}
xAccessor={0}
yAccessors={[1]}
data={KIBANA_METRICS.metrics.kibana_os_load[0].data.slice(3, 60)}
/>
</Chart>

</div>

<div className="chart">
<Chart className="story-chart" ref={ref2} id="chart2">
<Settings onPointerUpdate={pointerUpdate} externalPointerEvents={{ tooltip: { visible: true, boundary: 'chart' } }} />
<Axis
id="bottom"
position={Position.Bottom}
title="External tooltip VISIBLE - boundary => chart"
/>
<Axis id="left2" title="Left axis" position={Position.Left} tickFormat={(d: any) => Number(d).toFixed(2)} />

<BarSeries
id="bars"
xScaleType={ScaleType.Time}
yScaleType={ScaleType.Linear}
xAccessor={0}
yAccessors={[1]}
data={KIBANA_METRICS.metrics.kibana_os_load[1].data}
/>
</Chart>

</div>


<div className="chart">
<Chart className="story-chart" ref={ref3}>
<Settings
onPointerUpdate={pointerUpdate}
externalPointerEvents={{ tooltip: { visible: true, boundary: 'chart' } }}
tooltip={{
type: TooltipType.Follow,
customTooltip: TestCustomTooltip,
}}
/>
<Axis
id="bottom"
position={Position.Bottom}
title="External tooltip VISIBLE - boundary => chart"
/>
<Axis id="left2" title="Left axis" position={Position.Left} tickFormat={(d: any) => Number(d).toFixed(2)} />

<LineSeries
id="bars"
xScaleType={ScaleType.Time}
yScaleType={ScaleType.Linear}
xAccessor={0}
yAccessors={[1]}
data={KIBANA_METRICS.metrics.kibana_os_load[1].data.slice(0, 50)}
/>
<LineSeries
id="bars2"
xScaleType={ScaleType.Time}
yScaleType={ScaleType.Linear}
xAccessor={0}
yAccessors={[1]}
data={KIBANA_METRICS.metrics.kibana_os_load[2].data.slice(20, 30)}
/>
</Chart>
</div>

<div className="chart">
<Chart className="story-chart" ref={ref4} id="chart4">
<Settings onPointerUpdate={pointerUpdate} tooltip={{ type: TooltipType.None }} externalPointerEvents={{ tooltip: { visible: false } }} />
<Axis
id="bottom"
position={Position.Bottom}
title="External tooltip HIDDEN"
/>
<Axis id="left2" title="Left axis" position={Position.Left} tickFormat={(d: any) => Number(d).toFixed(2)} />

<LineSeries
id="bars"
xScaleType={ScaleType.Time}
yScaleType={ScaleType.Linear}
xAccessor={0}
yAccessors={[1]}
data={KIBANA_METRICS.metrics.kibana_os_load[1].data.slice(0, 50)}
/>
<LineSeries
id="bars2"
xScaleType={ScaleType.Time}
yScaleType={ScaleType.Linear}
xAccessor={0}
yAccessors={[1]}
data={KIBANA_METRICS.metrics.kibana_os_load[2].data.slice(20, 30)}
/>
</Chart>
</div>
</div>
);
};
22 changes: 17 additions & 5 deletions api/charts.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,7 @@ export const DEFAULT_TOOLTIP_TYPE: "vertical";
// Warning: (ae-missing-release-tag) "DefaultSettingsProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export type DefaultSettingsProps = 'id' | 'chartType' | 'specType' | 'rendering' | 'rotation' | 'resizeDebounce' | 'animateData' | 'showLegend' | 'debug' | 'tooltip' | 'showLegendExtra' | 'theme' | 'legendPosition' | 'hideDuplicateAxes' | 'brushAxis' | 'minBrushDelta';
export type DefaultSettingsProps = 'id' | 'chartType' | 'specType' | 'rendering' | 'rotation' | 'resizeDebounce' | 'animateData' | 'showLegend' | 'debug' | 'tooltip' | 'showLegendExtra' | 'theme' | 'legendPosition' | 'hideDuplicateAxes' | 'brushAxis' | 'minBrushDelta' | 'externalPointerEvents';

// Warning: (ae-missing-release-tag) "DisplayValueSpec" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
Expand Down Expand Up @@ -570,6 +570,16 @@ export type ElementClickListener = (elements: Array<XYChartElementEvent | Partit
// @public (undocumented)
export type ElementOverListener = (elements: Array<XYChartElementEvent | PartitionElementEvent>) => void;

// @alpha
export interface ExternalPointerEventsSettings {
tooltip: {
visible?: boolean;
placement?: Placement;
fallbackPlacements?: Placement[];
boundary?: HTMLElement | 'chart';
};
}

// Warning: (ae-missing-release-tag) "FillStyle" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
Expand Down Expand Up @@ -1329,16 +1339,16 @@ export type SeriesTypes = $Values<typeof SeriesTypes>;
// @public (undocumented)
export const Settings: React.FunctionComponent<SettingsSpecProps>;

// Warning: (ae-missing-release-tag) "SettingsSpec" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export interface SettingsSpec extends Spec {
// (undocumented)
animateData: boolean;
baseTheme?: Theme;
brushAxis?: BrushAxis;
// (undocumented)
debug: boolean;
// @alpha
externalPointerEvents: ExternalPointerEventsSettings;
flatLegend?: boolean;
hideDuplicateAxes: boolean;
// (undocumented)
Expand Down Expand Up @@ -1391,7 +1401,9 @@ export interface SettingsSpec extends Spec {
// Warning: (ae-missing-release-tag) "SettingsSpecProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export type SettingsSpecProps = Partial<Omit<SettingsSpec, 'chartType' | 'specType' | 'id'>>;
export type SettingsSpecProps = Partial<Omit<SettingsSpec, 'chartType' | 'specType' | 'id' | 'externalPointerEvents'>> & {
externalPointerEvents?: RecursivePartial<SettingsSpec['externalPointerEvents']>;
};

// Warning: (ae-missing-release-tag) "SharedGeometryStateStyle" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions integration/tests/interactions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,4 +209,16 @@ describe('Interactions', () => {
);
});
});

describe('Tooltip sync', () => {
it('show synced tooltips', async() => {
await common.expectChartWithMouseAtUrlToMatchScreenshot(
'http://localhost:9001/?path=/story/interactions--cursor-update-action',
{ left: 180, top: 80 },
{
screenshotSelector: '#story-root',
}
);
});
});
});
Loading