This commit is contained in:
Nathan Bierema 2022-12-31 18:52:06 -05:00
parent d5b77157d6
commit 5f66a15635

View File

@ -3,22 +3,17 @@ import type { BaseType, ContainerElement, Selection } from 'd3';
import { is } from 'ramda'; import { is } from 'ramda';
import functor from './utils/functor'; import functor from './utils/functor';
interface Options< interface Options {
GElement extends ContainerElement,
Datum,
PElement extends BaseType,
PDatum
> {
left: number | undefined; left: number | undefined;
top: number | undefined; top: number | undefined;
offset: { offset: {
left: number; left: number;
top: number; top: number;
}; };
root: Selection<GElement, Datum, PElement, PDatum> | undefined; root: Selection<ContainerElement, unknown, BaseType, unknown> | undefined;
} }
const defaultOptions: Options<ContainerElement, unknown, BaseType, unknown> = { const defaultOptions: Options = {
left: undefined, // mouseX left: undefined, // mouseX
top: undefined, // mouseY top: undefined, // mouseY
offset: { left: 0, top: 0 }, offset: { left: 0, top: 0 },
@ -27,14 +22,12 @@ const defaultOptions: Options<ContainerElement, unknown, BaseType, unknown> = {
export type StyleValue = string | number | boolean; export type StyleValue = string | number | boolean;
interface Tip< interface Tip<Datum> {
GElement extends ContainerElement, (selection: Selection<BaseType, Datum, BaseType, unknown>): void;
Datum, styles: (
PElement extends BaseType, this: this,
PDatum value: { [key: string]: StyleValue } | undefined
> { ) => this;
(selection: Selection<GElement, Datum, PElement, PDatum>): void;
styles: (this: this, value: { [key: string]: StyleValue }) => this;
text: ( text: (
this: this, this: this,
value: value:
@ -43,19 +36,11 @@ interface Tip<
) => this; ) => this;
} }
export function tooltip< export function tooltip<Datum>(
GElement extends ContainerElement,
Datum,
PElement extends BaseType,
PDatum
>(
className = 'tooltip', className = 'tooltip',
options: Partial<Options<GElement, Datum, PElement, PDatum>> = {} options: Partial<Options> = {}
): Tip<GElement, Datum, PElement, PDatum> { ): Tip<Datum> {
const { left, top, offset, root } = { const { left, top, offset, root } = { ...defaultOptions, ...options };
...defaultOptions,
...options,
} as Options<GElement, Datum, PElement, PDatum>;
let text: ( let text: (
datum: Datum, datum: Datum,
@ -64,12 +49,12 @@ export function tooltip<
) => string = () => ''; ) => string = () => '';
let styles: { [key: string]: StyleValue } = {}; let styles: { [key: string]: StyleValue } = {};
let el: Selection<HTMLDivElement, Datum, BaseType, PDatum>; let el: Selection<HTMLDivElement, unknown, BaseType, unknown>;
const anchor: Selection<GElement, Datum, BaseType, PDatum> = const anchor: Selection<ContainerElement, unknown, BaseType, unknown> =
root || d3.select('body'); root || d3.select('body');
const rootNode = anchor.node()!; const rootNode = anchor.node()!;
function tip(selection: Selection<GElement, Datum, PElement, PDatum>) { function tip(selection: Selection<BaseType, Datum, BaseType, unknown>) {
selection.on('mouseover.tip', (node) => { selection.on('mouseover.tip', (node) => {
const [mouseX, mouseY] = d3.mouse(rootNode); const [mouseX, mouseY] = d3.mouse(rootNode);
const [x, y] = [left || mouseX + offset.left, top || mouseY - offset.top]; const [x, y] = [left || mouseX + offset.left, top || mouseY - offset.top];
@ -105,7 +90,7 @@ export function tooltip<
tip.styles = function setStyles( tip.styles = function setStyles(
this: typeof tip, this: typeof tip,
value: { [key: string]: StyleValue } value: { [key: string]: StyleValue } | undefined
) { ) {
if (is(Object, value)) { if (is(Object, value)) {
styles = { ...styles, ...value }; styles = { ...styles, ...value };