From 720716bf7150611e4138af5bda6be3b423bbcb0c Mon Sep 17 00:00:00 2001 From: plouc Date: Thu, 30 Dec 2021 10:25:57 +0900 Subject: [PATCH] feat(website): add the ability to control charts annotations --- packages/network/src/Network.tsx | 2 - .../src/components/controls/ObjectControl.tsx | 5 +- website/src/components/controls/types.ts | 1 + website/src/data/components/network/props.ts | 14 ++ .../src/lib/chart-properties/annotations.ts | 136 ++++++++++++++++++ website/src/lib/chart-properties/index.ts | 1 + website/src/pages/network/index.tsx | 12 +- 7 files changed, 157 insertions(+), 14 deletions(-) create mode 100644 website/src/lib/chart-properties/annotations.ts diff --git a/packages/network/src/Network.tsx b/packages/network/src/Network.tsx index 0abb007a2f..f0aa41eb0b 100644 --- a/packages/network/src/Network.tsx +++ b/packages/network/src/Network.tsx @@ -104,8 +104,6 @@ const InnerNetwork = ({ annotations: null, } - console.log(nodes) - if (layers.includes('links') && links !== null) { layerById.links = ( diff --git a/website/src/components/controls/ObjectControl.tsx b/website/src/components/controls/ObjectControl.tsx index f7c88e4104..98429ad35f 100644 --- a/website/src/components/controls/ObjectControl.tsx +++ b/website/src/components/controls/ObjectControl.tsx @@ -28,9 +28,10 @@ export const ObjectControl = memo( value, onChange, context, - isOpenedByDefault = false, }: ObjectControlProps) => { - const [isOpened, setIsOpened] = useState(isOpenedByDefault) + const [isOpened, setIsOpened] = useState( + config.isOpenedByDefault !== undefined ? config.isOpenedByDefault : false + ) const toggle = useCallback(() => setIsOpened(flag => !flag), [setIsOpened]) const subProps = useMemo( diff --git a/website/src/components/controls/types.ts b/website/src/components/controls/types.ts index fa0a2a77c3..eb6577ea6d 100644 --- a/website/src/components/controls/types.ts +++ b/website/src/components/controls/types.ts @@ -110,6 +110,7 @@ export interface AngleControlConfig { export interface ObjectControlConfig { type: 'object' props: Omit[] + isOpenedByDefault?: boolean } export interface ArrayControlConfig { diff --git a/website/src/data/components/network/props.ts b/website/src/data/components/network/props.ts index c4d63d6452..552446f075 100644 --- a/website/src/data/components/network/props.ts +++ b/website/src/data/components/network/props.ts @@ -5,6 +5,7 @@ import { isInteractive, commonAccessibilityProps, blendMode, + annotations, } from '../../../lib/chart-properties' import { ChartProperty, Flavor } from '../../../types' import { dynamicNodeSizeValue, dynamicLinkThicknessValue } from './mapper' @@ -235,6 +236,19 @@ const props: ChartProperty[] = [ flavors: ['svg'], defaultValue: defaults.linkBlendMode, }), + annotations({ + target: 'nodes', + flavors: allFlavors, + newDefaults: { + type: 'circle', + match: { id: '0' }, + note: 'New annotation', + noteX: 160, + noteY: 36, + offset: 6, + noteTextOffset: 5, + }, + }), isInteractive({ flavors: allFlavors, defaultValue: defaults.isInteractive }), { key: 'nodeTooltip', diff --git a/website/src/lib/chart-properties/annotations.ts b/website/src/lib/chart-properties/annotations.ts new file mode 100644 index 0000000000..dbfb5cdf83 --- /dev/null +++ b/website/src/lib/chart-properties/annotations.ts @@ -0,0 +1,136 @@ +import { ChartProperty, Flavor } from '../../types' + +export const annotations = ({ + key = 'annotations', + target, + group = 'Annotations', + type = 'AnnotationMatcher[]', + flavors, + defaultValue = [], + newDefaults, +}: { + key?: string + target: string + group?: string + type?: string + flavors: Flavor[] + defaultValue: any[] + newDefaults: any +}): ChartProperty => { + return { + key, + group, + help: `Annotations for ${target}.`, + type, + required: false, + flavors, + defaultValue, + control: { + type: 'array', + shouldCreate: true, + addLabel: 'add annotation', + shouldRemove: true, + getItemTitle: (index: number, annotation: any) => + `annotation[${index}] '${annotation.note}' (${annotation.type})`, + defaults: newDefaults, + props: [ + { + key: 'type', + flavors, + help: `Annotation type.`, + type: `'dot' | 'circle' | 'rect'`, + required: true, + control: { + type: 'choices', + choices: [ + { value: 'dot', label: 'dot' }, + { value: 'circle', label: 'circle' }, + { value: 'rect', label: 'rect' }, + ], + }, + }, + { + key: 'match', + flavors, + help: 'Annotation matcher.', + required: true, + type: 'object', + control: { + type: 'object', + isOpenedByDefault: true, + props: [ + { + key: 'id', + required: false, + flavors, + help: 'Match elements having the provided ID.', + type: 'string | number', + control: { + type: 'text', + }, + }, + ], + }, + }, + { + key: 'note', + flavors, + help: `Annotation note.`, + type: 'text', + required: true, + control: { type: 'text' }, + }, + { + key: 'noteX', + flavors, + help: `Annotation note x position.`, + type: 'number', + required: true, + control: { + type: 'range', + min: -300, + max: 300, + step: 5, + }, + }, + { + key: 'noteY', + flavors, + help: `Annotation note y position.`, + type: 'number', + required: true, + control: { + type: 'range', + min: -300, + max: 300, + step: 5, + }, + }, + { + key: 'noteTextOffset', + flavors, + help: `Annotation note text offset.`, + type: 'number', + required: true, + control: { + type: 'range', + min: -64, + max: 64, + }, + }, + { + key: 'offset', + flavors, + help: `Offset from annotated element.`, + type: 'number', + required: false, + control: { + type: 'range', + min: 0, + max: 32, + }, + }, + ], + }, + } +} diff --git a/website/src/lib/chart-properties/index.ts b/website/src/lib/chart-properties/index.ts index a91cfeeb0f..80a18ee8ea 100644 --- a/website/src/lib/chart-properties/index.ts +++ b/website/src/lib/chart-properties/index.ts @@ -1,4 +1,5 @@ export * from './accessibility' +export * from './annotations' export * from './axes' export * from './chart-dimensions' export * from './colors' diff --git a/website/src/pages/network/index.tsx b/website/src/pages/network/index.tsx index 6216ac2b04..1c72866aea 100644 --- a/website/src/pages/network/index.tsx +++ b/website/src/pages/network/index.tsx @@ -35,6 +35,8 @@ const initialProperties = Object.freeze({ linkColor: defaults.linkColor, linkBlendMode: 'multiply', + annotations: defaults.annotations, + isInteractive: true, animate: true, @@ -95,16 +97,6 @@ const Network = () => { } {...properties} theme={theme} - annotations={[ - { - type: 'circle', - match: { id: '10' }, - noteX: 40, - noteY: 40, - offset: 4, - note: 'Node id: 10', - }, - ]} onClick={node => { logAction({ type: 'click',