This commit is contained in:
Nathan Bierema 2022-12-31 20:33:04 -05:00
parent bdf076030a
commit 733f5fb8f5
5 changed files with 56 additions and 20 deletions

View File

@ -28,7 +28,7 @@ const render = tree(document.getElementById('root')!, {
isSorted: false, isSorted: false,
widthBetweenNodesCoeff: 1.5, widthBetweenNodesCoeff: 1.5,
heightBetweenNodesCoeff: 2, heightBetweenNodesCoeff: 2,
style: { border: '1px solid black' }, chartStyles: { border: '1px solid black' },
tooltipOptions: { offset: { left: 30, top: 10 }, indentationSize: 2 }, tooltipOptions: { offset: { left: 30, top: 10 }, indentationSize: 2 },
}); });

View File

@ -1,2 +1,3 @@
export type { StyleValue } from 'd3tooltip';
export { default as tree } from './tree/tree'; export { default as tree } from './tree/tree';
export type { InputOptions, NodeWithId, Primitive } from './tree/tree'; export type { InputOptions, Node } from './tree/tree';

View File

@ -435,10 +435,16 @@ export default function (
if (!tooltipOptions.disabled) { if (!tooltipOptions.disabled) {
nodeEnter.call( nodeEnter.call(
tooltip<HierarchyPointNodeWithPrivateChildren<InternalNode>>( tooltip<
'tooltip', SVGGElement,
{ ...tooltipOptions, root } HierarchyPointNodeWithPrivateChildren<InternalNode>,
) SVGGElement,
unknown,
HTMLElement,
unknown,
null,
undefined
>('tooltip', { ...tooltipOptions, root })
.text((d, i) => getTooltipString(d, i, tooltipOptions)) .text((d, i) => getTooltipString(d, i, tooltipOptions))
.styles(tooltipOptions.style) .styles(tooltipOptions.style)
); );

View File

@ -1,2 +1,3 @@
export type { StyleValue } from 'd3tooltip';
export { tree } from './charts'; export { tree } from './charts';
export type { InputOptions, NodeWithId } from './charts'; export type { InputOptions, Node } from './charts';

View File

@ -3,17 +3,22 @@ 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<ContainerElement, unknown, BaseType, unknown> | undefined; root: Selection<GElement, Datum, PElement, PDatum> | undefined;
} }
const defaultOptions: Options = { const defaultOptions: Options<ContainerElement, unknown, BaseType, unknown> = {
left: undefined, // mouseX left: undefined, // mouseX
top: undefined, // mouseY top: undefined, // mouseY
offset: { left: 0, top: 0 }, offset: { left: 0, top: 0 },
@ -22,8 +27,13 @@ const defaultOptions: Options = {
export type StyleValue = string | number | boolean; export type StyleValue = string | number | boolean;
interface Tip<Datum> { interface Tip<
(selection: Selection<BaseType, Datum, BaseType, unknown>): void; GElement extends BaseType,
Datum,
PElement extends BaseType,
PDatum
> {
(selection: Selection<GElement, Datum, PElement, PDatum>): void;
styles: ( styles: (
this: this, this: this,
value: { [key: string]: StyleValue } | undefined value: { [key: string]: StyleValue } | undefined
@ -36,11 +46,25 @@ interface Tip<Datum> {
) => this; ) => this;
} }
export function tooltip<Datum>( export function tooltip<
GElement extends BaseType,
Datum,
PElement extends BaseType,
PDatum,
RootGElement extends ContainerElement,
RootDatum,
RootPElement extends BaseType,
RootPDatum
>(
className = 'tooltip', className = 'tooltip',
options: Partial<Options> = {} options: Partial<
): Tip<Datum> { Options<RootGElement, RootDatum, RootPElement, RootPDatum>
const { left, top, offset, root } = { ...defaultOptions, ...options }; > = {}
): Tip<GElement, Datum, PElement, PDatum> {
const { left, top, offset, root } = {
...defaultOptions,
...options,
} as Options<RootGElement, RootDatum, RootPElement, RootPDatum>;
let text: ( let text: (
datum: Datum, datum: Datum,
@ -49,12 +73,16 @@ export function tooltip<Datum>(
) => string = () => ''; ) => string = () => '';
let styles: { [key: string]: StyleValue } = {}; let styles: { [key: string]: StyleValue } = {};
let el: Selection<HTMLDivElement, unknown, BaseType, unknown>; let el: Selection<HTMLDivElement, RootDatum, BaseType, unknown>;
const anchor: Selection<ContainerElement, unknown, BaseType, unknown> = const anchor: Selection<
root || d3.select('body'); RootGElement,
RootDatum,
RootPElement | HTMLElement,
RootPDatum
> = root || d3.select<RootGElement, RootDatum>('body');
const rootNode = anchor.node()!; const rootNode = anchor.node()!;
function tip(selection: Selection<BaseType, Datum, BaseType, unknown>) { function tip(selection: Selection<GElement, Datum, PElement, PDatum>) {
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];