@unovis/ts 1.4.0-version.12 → 1.4.1-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/annotations/config.d.ts +19 -0
- package/components/annotations/config.js +6 -0
- package/components/annotations/config.js.map +1 -0
- package/components/annotations/index.d.ts +26 -0
- package/components/annotations/index.js +110 -0
- package/components/annotations/index.js.map +1 -0
- package/components/annotations/style.d.ts +16 -0
- package/components/annotations/style.js +47 -0
- package/components/annotations/style.js.map +1 -0
- package/components/annotations/types.d.ts +32 -0
- package/components/annotations/types.js +2 -0
- package/components/annotations/types.js.map +1 -0
- package/components/area/config.d.ts +1 -1
- package/components/area/config.js.map +1 -1
- package/components/area/index.js +2 -0
- package/components/area/index.js.map +1 -1
- package/components/bullet-legend/config.d.ts +11 -3
- package/components/bullet-legend/config.js +4 -3
- package/components/bullet-legend/config.js.map +1 -1
- package/components/bullet-legend/index.d.ts +1 -1
- package/components/bullet-legend/index.js +22 -20
- package/components/bullet-legend/index.js.map +1 -1
- package/components/bullet-legend/modules/shape.d.ts +2 -2
- package/components/bullet-legend/modules/shape.js +67 -46
- package/components/bullet-legend/modules/shape.js.map +1 -1
- package/components/bullet-legend/style.d.ts +1 -0
- package/components/bullet-legend/style.js +9 -3
- package/components/bullet-legend/style.js.map +1 -1
- package/components/bullet-legend/types.d.ts +17 -4
- package/components/bullet-legend/types.js +10 -7
- package/components/bullet-legend/types.js.map +1 -1
- package/components/chord-diagram/index.d.ts +3 -3
- package/components/chord-diagram/index.js +24 -15
- package/components/chord-diagram/index.js.map +1 -1
- package/components/chord-diagram/modules/label.js +16 -18
- package/components/chord-diagram/modules/label.js.map +1 -1
- package/components/chord-diagram/modules/layout.js +9 -5
- package/components/chord-diagram/modules/layout.js.map +1 -1
- package/components/chord-diagram/modules/link.js +1 -1
- package/components/chord-diagram/modules/link.js.map +1 -1
- package/components/chord-diagram/style.js +1 -1
- package/components/chord-diagram/style.js.map +1 -1
- package/components/crosshair/config.d.ts +4 -0
- package/components/crosshair/config.js +1 -1
- package/components/crosshair/config.js.map +1 -1
- package/components/crosshair/index.js +12 -4
- package/components/crosshair/index.js.map +1 -1
- package/components/crosshair/style.js +4 -2
- package/components/crosshair/style.js.map +1 -1
- package/components/crosshair/types.d.ts +2 -0
- package/components/nested-donut/config.d.ts +14 -2
- package/components/nested-donut/config.js +1 -1
- package/components/nested-donut/config.js.map +1 -1
- package/components/nested-donut/index.js +16 -10
- package/components/nested-donut/index.js.map +1 -1
- package/components/sankey/modules/node.js +1 -1
- package/components/sankey/modules/node.js.map +1 -1
- package/components/stacked-bar/index.js.map +1 -1
- package/components/vis-controls/index.d.ts +0 -3
- package/components/vis-controls/index.js +1 -6
- package/components/vis-controls/index.js.map +1 -1
- package/components/xy-labels/index.js +1 -1
- package/components/xy-labels/index.js.map +1 -1
- package/components.d.ts +2 -0
- package/components.js +1 -0
- package/components.js.map +1 -1
- package/containers/single-container/config.d.ts +3 -0
- package/containers/single-container/config.js +1 -1
- package/containers/single-container/config.js.map +1 -1
- package/containers/single-container/index.d.ts +1 -1
- package/containers/single-container/index.js +11 -1
- package/containers/single-container/index.js.map +1 -1
- package/containers/xy-container/config.d.ts +3 -0
- package/containers/xy-container/config.js +1 -1
- package/containers/xy-container/config.js.map +1 -1
- package/containers/xy-container/index.d.ts +2 -2
- package/containers/xy-container/index.js +19 -6
- package/containers/xy-container/index.js.map +1 -1
- package/index.js +2 -1
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/types/misc.d.ts +1 -0
- package/types/scale.d.ts +3 -2
- package/types/scale.js +2 -1
- package/types/scale.js.map +1 -1
- package/types.d.ts +1 -0
- package/types.js +2 -1
- package/types.js.map +1 -1
- package/utils/data.js +1 -1
- package/utils/data.js.map +1 -1
- package/utils/misc.d.ts +2 -1
- package/utils/misc.js +13 -1
- package/utils/misc.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"label.js","sources":["../../../../src/components/chord-diagram/modules/label.ts"],"sourcesContent":["import { select, Selection } from 'd3-selection'\nimport { ScaleContinuousNumeric } from 'd3-scale'\nimport { color } from 'd3-color'\n\n// Utils\nimport { trimSVGText } from 'utils/text'\nimport { smartTransition } from 'utils/d3'\nimport { getNumber, getString, getValue } from 'utils/data'\nimport { getColor, hexToBrightness } from 'utils/color'\n\n// Config\nimport { ChordDiagramConfigInterface } from '../config'\n\n// Local Types\nimport { ChordInputLink, ChordInputNode, ChordLabelAlignment, ChordNode } from '../types'\n\n// Styles\nimport * as s from '../style'\n\nexport const LABEL_PADDING = 3\n\nfunction getLabelFillColor<N extends ChordInputNode, L extends ChordInputLink> (\n d: ChordNode<N>,\n config: ChordDiagramConfigInterface<N, L>\n): string {\n const nodeLabelAlignment = getValue(d.data, config.nodeLabelAlignment) ?? ChordLabelAlignment.Along\n switch (nodeLabelAlignment) {\n case ChordLabelAlignment.Perpendicular: {\n return getColor(d.data, config.nodeColor, d.height)\n }\n case ChordLabelAlignment.Along: {\n const c = getColor(d.data, config.nodeColor, d.height)\n const colorParsed = color(c)\n const brightness = colorParsed ? hexToBrightness(colorParsed.hex()) : 0\n return brightness > 0.65 ? 'var(--vis-chord-diagram-label-text-fill-color-dark)' : 'var(--vis-chord-diagram-label-text-fill-color-bright)'\n }\n }\n}\n\nfunction getLabelTextAnchor<N extends ChordInputNode, L extends ChordInputLink> (\n d: ChordNode<N>,\n config: ChordDiagramConfigInterface<N, L>\n): string | null {\n const nodeLabelAlignment = getValue(d.data, config.nodeLabelAlignment) ?? ChordLabelAlignment.Along\n switch (nodeLabelAlignment) {\n case ChordLabelAlignment.Perpendicular: {\n const angleCenter = (d.x0 + d.x1) / 2\n const angleDegree = angleCenter * 180 / Math.PI\n return angleDegree < 180 ? 'start' : 'end'\n }\n case ChordLabelAlignment.Along: {\n return null\n }\n }\n}\n\nfunction getLabelTransform<N extends ChordInputNode, L extends ChordInputLink> (\n d: ChordNode<N>,\n config: ChordDiagramConfigInterface<N, L>,\n radiusScale: ScaleContinuousNumeric<number, number>\n): string | null {\n const nodeLabelAlignment = getValue(d.data, config.nodeLabelAlignment) ?? ChordLabelAlignment.Along\n switch (nodeLabelAlignment) {\n case ChordLabelAlignment.Perpendicular: {\n const r = radiusScale(d.y1) + LABEL_PADDING\n const angleCenter = (d.x0 + d.x1) / 2\n const angle = angleCenter - Math.PI / 2\n const x = r * Math.cos(angle)\n const y = r * Math.sin(angle)\n return `translate(${x}, ${y})`\n }\n case ChordLabelAlignment.Along:\n return null\n }\n}\n\nexport function createLabel<N extends ChordInputNode, L extends ChordInputLink> (\n selection: Selection<SVGGElement, ChordNode<N>, SVGGElement, unknown>,\n config: ChordDiagramConfigInterface<N, L>,\n radiusScale: ScaleContinuousNumeric<number, number>\n): void {\n selection.style('opacity', 0)\n .attr('transform', d => getLabelTransform(d, config, radiusScale))\n\n selection.append('text')\n .attr('class', s.labelText)\n .style('fill', d => getColor(d.data, config.nodeColor, d.height))\n}\n\nexport function updateLabel<N extends ChordInputNode, L extends ChordInputLink> (\n selection: Selection<SVGGElement, ChordNode<N>, SVGGElement, unknown>,\n config: ChordDiagramConfigInterface<N, L>,\n width: number,\n radiusScale: ScaleContinuousNumeric<number, number>,\n duration: number\n): void {\n const { nodeLabel, nodeLabelColor, nodeWidth } = config\n\n smartTransition(selection, duration)\n .attr('transform', d => getLabelTransform(d, config, radiusScale))\n .style('opacity', 1)\n\n const label: Selection<SVGTextElement, ChordNode<N>, SVGElement, unknown> = selection.select(`.${s.labelText}`)\n label.select('textPath').remove()\n label\n .text(d => getString(d.data, nodeLabel))\n .style('fill', d => getColor(d.data, nodeLabelColor) ?? getLabelFillColor(d, config))\n .style('text-anchor', d => getLabelTextAnchor(d, config))\n\n label.each((d: ChordNode<N>, i: number, elements) => {\n const nodeLabelAlignment = getValue(d.data, config.nodeLabelAlignment) ?? ChordLabelAlignment.Along\n const radianArcLength = d.x1 - d.x0 - getNumber(d.data, config.padAngle) * 2\n const radius = radiusScale(d.y1) - getNumber(d, config.nodeWidth) / 2\n const arcLength = radius * radianArcLength\n const maxWidth = (nodeLabelAlignment === ChordLabelAlignment.Along ? arcLength : width) - LABEL_PADDING * 2\n\n const textElementSelection = select(elements[i])\n trimSVGText(textElementSelection, maxWidth)\n textElementSelection\n .attr('dx', nodeLabelAlignment === ChordLabelAlignment.Along ? LABEL_PADDING : null)\n .attr('dy', nodeLabelAlignment === ChordLabelAlignment.Along ? getNumber(d.data, nodeWidth) / 2 : null)\n\n if (nodeLabelAlignment === ChordLabelAlignment.Along) {\n const textElement = select(elements[i])\n const textWidth = textElement.node().getBoundingClientRect().width\n const labelText = textElement.text()\n\n select(elements[i])\n .text('')\n .style('display', textWidth > maxWidth && 'none')\n\n select(elements[i]).append('textPath')\n .attr('href', `#${d.uid}`)\n .text(labelText)\n }\n })\n\n smartTransition(label, duration)\n .attr('transform', d => {\n const nodeLabelAlignment = getValue(d.data, config.nodeLabelAlignment)\n if (nodeLabelAlignment !== ChordLabelAlignment.Perpendicular) return null\n const angleCenter = (d.x0 + d.x1) / 2\n const angleDegree = angleCenter * 180 / Math.PI\n return `rotate(${angleDegree < 180 ? angleDegree - 90 : angleDegree + 90})`\n })\n}\n\nexport function removeLabel (\n selection: Selection<SVGGElement, unknown, SVGGElement, unknown>,\n duration: number\n): void {\n smartTransition(selection, duration)\n .style('opacity', 0)\n .remove()\n}\n"],"names":["s.labelText"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"label.js","sources":["../../../../src/components/chord-diagram/modules/label.ts"],"sourcesContent":["import { select, Selection } from 'd3-selection'\nimport { ScaleContinuousNumeric } from 'd3-scale'\nimport { color } from 'd3-color'\n\n// Utils\nimport { trimSVGText } from 'utils/text'\nimport { smartTransition } from 'utils/d3'\nimport { getNumber, getString, getValue } from 'utils/data'\nimport { getColor, hexToBrightness } from 'utils/color'\n\n// Config\nimport { ChordDiagramConfigInterface } from '../config'\n\n// Local Types\nimport { ChordInputLink, ChordInputNode, ChordLabelAlignment, ChordNode } from '../types'\n\n// Styles\nimport * as s from '../style'\n\nexport const LABEL_PADDING = 3\n\nfunction getLabelFillColor<N extends ChordInputNode, L extends ChordInputLink> (\n d: ChordNode<N>,\n config: ChordDiagramConfigInterface<N, L>\n): string {\n const nodeLabelAlignment = getValue(d.data, config.nodeLabelAlignment) ?? ChordLabelAlignment.Along\n switch (nodeLabelAlignment) {\n case ChordLabelAlignment.Perpendicular: {\n return getColor(d.data, config.nodeColor, d.height)\n }\n case ChordLabelAlignment.Along: {\n const c = getColor(d.data, config.nodeColor, d.height)\n const colorParsed = color(c)\n const brightness = colorParsed ? hexToBrightness(colorParsed.hex()) : 0\n return brightness > 0.65 ? 'var(--vis-chord-diagram-label-text-fill-color-dark)' : 'var(--vis-chord-diagram-label-text-fill-color-bright)'\n }\n }\n}\n\nfunction getLabelTextAnchor<N extends ChordInputNode, L extends ChordInputLink> (\n d: ChordNode<N>,\n config: ChordDiagramConfigInterface<N, L>\n): string | null {\n const nodeLabelAlignment = getValue(d.data, config.nodeLabelAlignment) ?? ChordLabelAlignment.Along\n switch (nodeLabelAlignment) {\n case ChordLabelAlignment.Perpendicular: {\n const angleCenter = (d.x0 + d.x1) / 2\n const angleDegree = angleCenter * 180 / Math.PI\n return angleDegree < 180 ? 'start' : 'end'\n }\n case ChordLabelAlignment.Along: {\n return null\n }\n }\n}\n\nfunction getLabelTransform<N extends ChordInputNode, L extends ChordInputLink> (\n d: ChordNode<N>,\n config: ChordDiagramConfigInterface<N, L>,\n radiusScale: ScaleContinuousNumeric<number, number>\n): string | null {\n const nodeLabelAlignment = getValue(d.data, config.nodeLabelAlignment) ?? ChordLabelAlignment.Along\n switch (nodeLabelAlignment) {\n case ChordLabelAlignment.Perpendicular: {\n const r = radiusScale(d.y1) + LABEL_PADDING\n const angleCenter = (d.x0 + d.x1) / 2\n const angle = angleCenter - Math.PI / 2\n const x = r * Math.cos(angle)\n const y = r * Math.sin(angle)\n return `translate(${x}, ${y})`\n }\n case ChordLabelAlignment.Along:\n return null\n }\n}\n\nexport function createLabel<N extends ChordInputNode, L extends ChordInputLink> (\n selection: Selection<SVGGElement, ChordNode<N>, SVGGElement, unknown>,\n config: ChordDiagramConfigInterface<N, L>,\n radiusScale: ScaleContinuousNumeric<number, number>\n): void {\n selection.style('opacity', 0)\n .attr('transform', d => getLabelTransform(d, config, radiusScale))\n\n selection.append('text')\n .attr('class', s.labelText)\n .style('fill', d => getColor(d.data, config.nodeColor, d.height))\n}\n\nexport function updateLabel<N extends ChordInputNode, L extends ChordInputLink> (\n selection: Selection<SVGGElement, ChordNode<N>, SVGGElement, unknown>,\n config: ChordDiagramConfigInterface<N, L>,\n width: number,\n radiusScale: ScaleContinuousNumeric<number, number>,\n duration: number\n): void {\n const { nodeLabel, nodeLabelColor, nodeWidth } = config\n\n smartTransition(selection, duration)\n .attr('transform', d => getLabelTransform(d, config, radiusScale))\n .style('opacity', 1)\n\n const label: Selection<SVGTextElement, ChordNode<N>, SVGElement, unknown> = selection.select(`.${s.labelText}`)\n label.selectAll('textPath').remove()\n\n label.text(d => getString(d.data, nodeLabel))\n .style('transition', `fill ${duration}ms`)\n .style('fill', d => getColor(d.data, nodeLabelColor) ?? getLabelFillColor(d, config))\n .style('text-anchor', d => getLabelTextAnchor(d, config))\n .each((d: ChordNode<N>, i: number, elements) => {\n const nodeLabelAlignment = getValue(d.data, config.nodeLabelAlignment) ?? ChordLabelAlignment.Along\n const radianArcLength = d.x1 - d.x0 - getNumber(d.data, config.padAngle) * 2\n const radius = radiusScale(d.y1) - getNumber(d, config.nodeWidth) / 2\n const arcLength = radius * radianArcLength\n const maxWidth = (nodeLabelAlignment === ChordLabelAlignment.Along ? arcLength : width - LABEL_PADDING * 2)\n\n const textElement = select(elements[i])\n .call(trimSVGText, maxWidth)\n .attr('dx', nodeLabelAlignment === ChordLabelAlignment.Along ? LABEL_PADDING : null)\n .attr('dy', nodeLabelAlignment === ChordLabelAlignment.Along ? getNumber(d.data, nodeWidth) / 2 : null)\n\n const textWidth = textElement.node().getComputedTextLength()\n const labelText = textElement.text()\n if (nodeLabelAlignment === ChordLabelAlignment.Along) {\n textElement.text('')\n if (textWidth <= maxWidth) {\n textElement.append('textPath')\n .attr('href', `#${d.uid}`)\n .text(labelText)\n }\n }\n })\n\n smartTransition(label, duration)\n .attr('transform', d => {\n const nodeLabelAlignment = getValue(d.data, config.nodeLabelAlignment)\n if (nodeLabelAlignment !== ChordLabelAlignment.Perpendicular) return null\n const angleCenter = (d.x0 + d.x1) / 2\n const angleDegree = angleCenter * 180 / Math.PI\n return `rotate(${angleDegree < 180 ? angleDegree - 90 : angleDegree + 90})`\n })\n}\n\nexport function removeLabel (\n selection: Selection<SVGGElement, unknown, SVGGElement, unknown>,\n duration: number\n): void {\n smartTransition(selection, duration)\n .style('opacity', 0)\n .remove()\n}\n"],"names":["s.labelText"],"mappings":"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"}
|
|
@@ -22,21 +22,25 @@ function getHierarchyNodes(data, value, levels = []) {
|
|
|
22
22
|
function positionChildren(node, padding, scalingCoeff = 0.95) {
|
|
23
23
|
if (!node.children)
|
|
24
24
|
return;
|
|
25
|
+
// We need to ensure levels with empty links still take up full space
|
|
26
|
+
const containsLinks = node.value > 0;
|
|
25
27
|
const length = node.x1 - node.x0;
|
|
26
|
-
const scaledLength = length * scalingCoeff;
|
|
28
|
+
const scaledLength = length * (node.y0 === 0 ? 1 : scalingCoeff);
|
|
27
29
|
const delta = length - scaledLength;
|
|
30
|
+
const padAngle = containsLinks ? padding : scaledLength / node.children.length;
|
|
28
31
|
const positions = pie()
|
|
29
32
|
.startAngle(node.x0 + delta / 2)
|
|
30
33
|
.endAngle(node.x1 - delta / 2)
|
|
31
|
-
.padAngle(
|
|
32
|
-
.value(d => d.value)
|
|
34
|
+
.padAngle(padAngle)
|
|
35
|
+
.value(d => containsLinks ? d.value : 1)
|
|
33
36
|
.sort((a, b) => node.children.indexOf(a) - node.children.indexOf(b))(node.children);
|
|
34
37
|
node.children.forEach((child, i) => {
|
|
35
38
|
const x0 = positions[i].startAngle;
|
|
36
39
|
const x1 = positions[i].endAngle;
|
|
37
40
|
const childDelta = (x1 - x0) * (1 - scalingCoeff);
|
|
38
|
-
|
|
39
|
-
child.
|
|
41
|
+
const xmid = (x0 + x1) / 2;
|
|
42
|
+
child.x0 = containsLinks ? x0 + childDelta / 2 : xmid - padding / 2;
|
|
43
|
+
child.x1 = containsLinks ? x1 - childDelta / 2 : xmid + padding / 2;
|
|
40
44
|
});
|
|
41
45
|
}
|
|
42
46
|
function getRibbons(data, links, padding) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.js","sources":["../../../../src/components/chord-diagram/modules/layout.ts"],"sourcesContent":["import { group, index } from 'd3-array'\nimport { HierarchyNode, hierarchy } from 'd3-hierarchy'\nimport { pie } from 'd3-shape'\n\n// Utils\nimport { getNumber, groupBy } from 'utils/data'\n\n// Types\nimport { NumericAccessor } from 'types/accessor'\n\n// Local Types\nimport { ChordNode, ChordRibbon, ChordLinkDatum, ChordHierarchyNode, ChordLeafNode } from '../types'\n\nfunction transformData <T> (node: HierarchyNode<T>): void {\n const { height, depth } = node\n if (height > 0) {\n const d = node.data as unknown as [string, T[]]\n const n = node as unknown as HierarchyNode<ChordHierarchyNode<T>>\n n.data = { key: d[0], values: d[1], depth, height, ancestors: n.ancestors().map(d => d.data.key) }\n }\n}\n\nexport function getHierarchyNodes<N> (\n data: N[],\n value: NumericAccessor<N>,\n levels: string[] = []\n): HierarchyNode<ChordHierarchyNode<N>> {\n const nodeLevels = levels.map(level => (d: N) => d[level as keyof N]) as unknown as [(d: N) => string]\n const nestedData = levels.length ? group<N, string>(data, ...nodeLevels) : { key: 'root', children: data }\n\n const root = hierarchy(nestedData)\n .sum(d => getNumber(d as unknown as N, value))\n .each(transformData)\n\n return root as unknown as HierarchyNode<ChordHierarchyNode<N>>\n}\n\nexport function positionChildren<N> (node: ChordNode<N>, padding: number, scalingCoeff = 0.95): void {\n if (!node.children) return\n\n const length = node.x1 - node.x0\n const scaledLength = length * scalingCoeff\n const delta = length - scaledLength\n\n const positions = pie<ChordNode<N>>()\n .startAngle(node.x0 + delta / 2)\n .endAngle(node.x1 - delta / 2)\n .padAngle(
|
|
1
|
+
{"version":3,"file":"layout.js","sources":["../../../../src/components/chord-diagram/modules/layout.ts"],"sourcesContent":["import { group, index } from 'd3-array'\nimport { HierarchyNode, hierarchy } from 'd3-hierarchy'\nimport { pie } from 'd3-shape'\n\n// Utils\nimport { getNumber, groupBy } from 'utils/data'\n\n// Types\nimport { NumericAccessor } from 'types/accessor'\n\n// Local Types\nimport { ChordNode, ChordRibbon, ChordLinkDatum, ChordHierarchyNode, ChordLeafNode } from '../types'\n\nfunction transformData <T> (node: HierarchyNode<T>): void {\n const { height, depth } = node\n if (height > 0) {\n const d = node.data as unknown as [string, T[]]\n const n = node as unknown as HierarchyNode<ChordHierarchyNode<T>>\n n.data = { key: d[0], values: d[1], depth, height, ancestors: n.ancestors().map(d => d.data.key) }\n }\n}\n\nexport function getHierarchyNodes<N> (\n data: N[],\n value: NumericAccessor<N>,\n levels: string[] = []\n): HierarchyNode<ChordHierarchyNode<N>> {\n const nodeLevels = levels.map(level => (d: N) => d[level as keyof N]) as unknown as [(d: N) => string]\n const nestedData = levels.length ? group<N, string>(data, ...nodeLevels) : { key: 'root', children: data }\n\n const root = hierarchy(nestedData)\n .sum(d => getNumber(d as unknown as N, value))\n .each(transformData)\n\n return root as unknown as HierarchyNode<ChordHierarchyNode<N>>\n}\n\nexport function positionChildren<N> (node: ChordNode<N>, padding: number, scalingCoeff = 0.95): void {\n if (!node.children) return\n\n // We need to ensure levels with empty links still take up full space\n const containsLinks = node.value > 0\n\n const length = node.x1 - node.x0\n const scaledLength = length * (node.y0 === 0 ? 1 : scalingCoeff)\n const delta = length - scaledLength\n const padAngle = containsLinks ? padding : scaledLength / node.children.length\n\n const positions = pie<ChordNode<N>>()\n .startAngle(node.x0 + delta / 2)\n .endAngle(node.x1 - delta / 2)\n .padAngle(padAngle)\n .value(d => containsLinks ? d.value : 1)\n .sort((a, b) => node.children.indexOf(a) - node.children.indexOf(b))(node.children)\n\n node.children.forEach((child, i) => {\n const x0 = positions[i].startAngle\n const x1 = positions[i].endAngle\n const childDelta = (x1 - x0) * (1 - scalingCoeff)\n const xmid = (x0 + x1) / 2\n child.x0 = containsLinks ? x0 + childDelta / 2 : xmid - padding / 2\n child.x1 = containsLinks ? x1 - childDelta / 2 : xmid + padding / 2\n })\n}\n\nexport function getRibbons<N> (data: ChordNode<N>, links: ChordLinkDatum<N>[], padding: number): ChordRibbon<N>[] {\n type LinksArrayType = typeof links\n const groupedBySource: Record<string, LinksArrayType> = groupBy(links, d => d.source._id)\n const groupedByTarget: Record<string, LinksArrayType> = groupBy(links, d => d.target._id)\n\n const leafNodes = data.leaves() as ChordLeafNode<N>[]\n const leafNodesById: Map<string, ChordLeafNode<N>> = index(leafNodes, d => d.data._id)\n\n const getNodesInRibbon = (\n source: ChordLeafNode<N>,\n target: ChordLeafNode<N>,\n partitionHeight: number,\n nodes: ChordNode<N>[] = []\n ): ChordNode<N>[] => {\n nodes[source.height] = source\n nodes[partitionHeight * 2 - target.height] = target\n if (source.parent && target.parent) getNodesInRibbon(source.parent, target.parent, partitionHeight, nodes)\n return nodes\n }\n const calculatePoints = (links: LinksArrayType, type: 'in' | 'out', depth: number, maxDepth: number): void => {\n links.forEach(link => {\n if (!link._state.points) link._state.points = []\n\n const sourceLeaf = leafNodesById.get(link.source._id)\n const targetLeaf = leafNodesById.get(link.target._id)\n const nodesInRibbon = getNodesInRibbon(\n type === 'out' ? sourceLeaf : targetLeaf,\n type === 'out' ? targetLeaf : sourceLeaf,\n maxDepth\n )\n const currNode = nodesInRibbon[depth]\n const len = currNode.x1 - currNode.x0 - padding\n const x0 = currNode._prevX1 ?? (currNode.x0 + padding / 2)\n const x1 = x0 + len * link._state.value / currNode.value\n currNode._prevX1 = x1\n\n const pointIdx = type === 'out' ? depth : maxDepth * 2 - 1 - depth\n link._state.points[pointIdx] = { a0: x0, a1: x1, r: currNode.y1 }\n })\n }\n\n leafNodes.forEach(leafNode => {\n const outLinks = groupedBySource[leafNode.data._id] || []\n const inLinks = groupedByTarget[leafNode.data._id] || []\n for (let depth = 0; depth < leafNode.depth; depth += 1) {\n calculatePoints(outLinks, 'out', depth, leafNode.depth)\n calculatePoints(inLinks, 'in', depth, leafNode.depth)\n }\n })\n\n return links.map(l => ({\n source: leafNodesById.get(l.source._id),\n target: leafNodesById.get(l.target._id),\n data: l,\n points: l._state.points,\n _state: {},\n }))\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -43,7 +43,7 @@ function createLink(selection, radiusScale) {
|
|
|
43
43
|
}
|
|
44
44
|
function updateLink(selection, config, radiusScale, duration) {
|
|
45
45
|
selection
|
|
46
|
-
.style('transition', `fill
|
|
46
|
+
.style('transition', `fill ${duration}ms`)
|
|
47
47
|
.style('fill', d => getColor(d.data, config.linkColor))
|
|
48
48
|
.style('stroke', d => getColor(d.data, config.linkColor));
|
|
49
49
|
const transition = smartTransition(selection, duration)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"link.js","sources":["../../../../src/components/chord-diagram/modules/link.ts"],"sourcesContent":["import { Selection, select } from 'd3-selection'\nimport { ribbon } from 'd3-chord'\nimport { ScalePower } from 'd3-scale'\nimport { areaRadial } from 'd3-shape'\nimport { Transition } from 'd3-transition'\nimport { interpolatePath } from 'd3-interpolate-path'\n\n// Types\nimport { Curve } from 'types/curve'\n\n// Utils\nimport { getColor } from 'utils/color'\nimport { smartTransition } from 'utils/d3'\nimport { convertLineToArc } from 'utils/path'\n\n// Local Types\nimport { ChordInputLink, ChordInputNode, ChordRibbon, ChordRibbonPoint } from '../types'\nimport { ChordDiagramConfigInterface } from '../config'\n\n// Generators\nexport function emptyPath (): string {\n return 'M0,0 L0,0'\n}\n\n// Generators\nconst ribbonGen = ribbon<ChordRibbonPoint[], ChordRibbonPoint>()\n .source(d => d[0])\n .target(d => d[d.length - 1])\n .startAngle(d => d.a0)\n .endAngle(d => d.a1)\n\nconst areaGen = areaRadial<ChordRibbonPoint>()\n .curve(Curve.catmullRom.alpha(0.5))\n .startAngle((d, i, points) => i < points.length / 2 ? d.a1 : d.a0)\n .endAngle((d, i, points) => i < points.length / 2 ? d.a0 : d.a1)\n\n\n// Creates a path from set of points\nfunction linkGen (points: ChordRibbonPoint[], radiusScale: ScalePower<number, number>): string {\n const link = (points.length === 2 ? ribbonGen : areaGen)\n link.radius(d => radiusScale(d.r))\n\n const linkPath = link(points) as string\n\n if (points.length === 2) return linkPath\n\n // Replace closePath with line to starting point\n const area = linkPath.slice(0, -1)\n const path = area.concat(`L${area.match(/M-?\\d*\\.?\\d*[,\\s*]-?\\d*\\.?\\d*/)?.[0].slice(1)}`)\n\n // Convert line edges to arcs\n const radius = Math.max(radiusScale(points[0].r), 0)\n return convertLineToArc(path, radius)\n}\n\nexport function createLink<N extends ChordInputNode> (\n selection: Selection<SVGPathElement, ChordRibbon<N>, SVGGElement, unknown>,\n radiusScale: ScalePower<number, number>\n): void {\n selection\n .attr('d', d => linkGen(d.points, radiusScale) || emptyPath())\n .style('opacity', 0)\n}\n\nexport function updateLink<N extends ChordInputNode, L extends ChordInputLink> (\n selection: Selection<SVGPathElement, ChordRibbon<N, L>, SVGGElement, unknown>,\n config: ChordDiagramConfigInterface<N, L>,\n radiusScale: ScalePower<number, number>,\n duration: number\n): void {\n selection\n .style('transition', `fill
|
|
1
|
+
{"version":3,"file":"link.js","sources":["../../../../src/components/chord-diagram/modules/link.ts"],"sourcesContent":["import { Selection, select } from 'd3-selection'\nimport { ribbon } from 'd3-chord'\nimport { ScalePower } from 'd3-scale'\nimport { areaRadial } from 'd3-shape'\nimport { Transition } from 'd3-transition'\nimport { interpolatePath } from 'd3-interpolate-path'\n\n// Types\nimport { Curve } from 'types/curve'\n\n// Utils\nimport { getColor } from 'utils/color'\nimport { smartTransition } from 'utils/d3'\nimport { convertLineToArc } from 'utils/path'\n\n// Local Types\nimport { ChordInputLink, ChordInputNode, ChordRibbon, ChordRibbonPoint } from '../types'\nimport { ChordDiagramConfigInterface } from '../config'\n\n// Generators\nexport function emptyPath (): string {\n return 'M0,0 L0,0'\n}\n\n// Generators\nconst ribbonGen = ribbon<ChordRibbonPoint[], ChordRibbonPoint>()\n .source(d => d[0])\n .target(d => d[d.length - 1])\n .startAngle(d => d.a0)\n .endAngle(d => d.a1)\n\nconst areaGen = areaRadial<ChordRibbonPoint>()\n .curve(Curve.catmullRom.alpha(0.5))\n .startAngle((d, i, points) => i < points.length / 2 ? d.a1 : d.a0)\n .endAngle((d, i, points) => i < points.length / 2 ? d.a0 : d.a1)\n\n\n// Creates a path from set of points\nfunction linkGen (points: ChordRibbonPoint[], radiusScale: ScalePower<number, number>): string {\n const link = (points.length === 2 ? ribbonGen : areaGen)\n link.radius(d => radiusScale(d.r))\n\n const linkPath = link(points) as string\n\n if (points.length === 2) return linkPath\n\n // Replace closePath with line to starting point\n const area = linkPath.slice(0, -1)\n const path = area.concat(`L${area.match(/M-?\\d*\\.?\\d*[,\\s*]-?\\d*\\.?\\d*/)?.[0].slice(1)}`)\n\n // Convert line edges to arcs\n const radius = Math.max(radiusScale(points[0].r), 0)\n return convertLineToArc(path, radius)\n}\n\nexport function createLink<N extends ChordInputNode> (\n selection: Selection<SVGPathElement, ChordRibbon<N>, SVGGElement, unknown>,\n radiusScale: ScalePower<number, number>\n): void {\n selection\n .attr('d', d => linkGen(d.points, radiusScale) || emptyPath())\n .style('opacity', 0)\n}\n\nexport function updateLink<N extends ChordInputNode, L extends ChordInputLink> (\n selection: Selection<SVGPathElement, ChordRibbon<N, L>, SVGGElement, unknown>,\n config: ChordDiagramConfigInterface<N, L>,\n radiusScale: ScalePower<number, number>,\n duration: number\n): void {\n selection\n .style('transition', `fill ${duration}ms`)\n .style('fill', d => getColor(d.data, config.linkColor))\n .style('stroke', d => getColor(d.data, config.linkColor))\n\n const transition = smartTransition(selection, duration)\n .style('opacity', 1) as Transition<SVGPathElement, ChordRibbon<N, L>, SVGGElement, unknown>\n\n if (duration) {\n transition.attrTween('d', (d, i, el) => {\n const previous = select(el[i]).attr('d')\n const next = linkGen(d.points, radiusScale) || emptyPath()\n return interpolatePath(previous, next)\n })\n } else {\n transition.attr('d', d => linkGen(d.points, radiusScale) || emptyPath())\n }\n}\n\nexport function removeLink (\n selection: Selection<SVGPathElement, unknown, SVGGElement, unknown>,\n duration: number\n): void {\n smartTransition(selection, duration)\n .style('opacity', 0)\n .remove()\n}\n"],"names":[],"mappings":";;;;;;;;;AAmBA;SACgB,SAAS,GAAA;AACvB,IAAA,OAAO,WAAW,CAAA;AACpB,CAAC;AAED;AACA,MAAM,SAAS,GAAG,MAAM,EAAwC;KAC7D,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AACjB,KAAA,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;KAC5B,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;KACrB,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAA;AAEtB,MAAM,OAAO,GAAG,UAAU,EAAoB;KAC3C,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AAClC,KAAA,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;AACjE,KAAA,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAA;AAGlE;AACA,SAAS,OAAO,CAAE,MAA0B,EAAE,WAAuC,EAAA;;AACnF,IAAA,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,GAAG,SAAS,GAAG,OAAO,CAAC,CAAA;AACxD,IAAA,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAElC,IAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAW,CAAA;AAEvC,IAAA,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;AAAE,QAAA,OAAO,QAAQ,CAAA;;IAGxC,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IAClC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAA,CAAA,EAAI,CAAA,EAAA,GAAA,IAAI,CAAC,KAAK,CAAC,+BAA+B,CAAC,MAAG,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,CAAC,CAAE,CAAA,KAAK,CAAC,CAAC,CAAC,CAAE,CAAA,CAAC,CAAA;;AAGzF,IAAA,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AACpD,IAAA,OAAO,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;AACvC,CAAC;AAEe,SAAA,UAAU,CACxB,SAA0E,EAC1E,WAAuC,EAAA;IAEvC,SAAS;AACN,SAAA,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,WAAW,CAAC,IAAI,SAAS,EAAE,CAAC;AAC7D,SAAA,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAA;AACxB,CAAC;AAEK,SAAU,UAAU,CACxB,SAA6E,EAC7E,MAAyC,EACzC,WAAuC,EACvC,QAAgB,EAAA;IAEhB,SAAS;AACN,SAAA,KAAK,CAAC,YAAY,EAAE,CAAQ,KAAA,EAAA,QAAQ,IAAI,CAAC;AACzC,SAAA,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;AACtD,SAAA,KAAK,CAAC,QAAQ,EAAE,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAA;AAE3D,IAAA,MAAM,UAAU,GAAG,eAAe,CAAC,SAAS,EAAE,QAAQ,CAAC;AACpD,SAAA,KAAK,CAAC,SAAS,EAAE,CAAC,CAAwE,CAAA;AAE7F,IAAA,IAAI,QAAQ,EAAE;AACZ,QAAA,UAAU,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,KAAI;AACrC,YAAA,MAAM,QAAQ,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACxC,YAAA,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,WAAW,CAAC,IAAI,SAAS,EAAE,CAAA;AAC1D,YAAA,OAAO,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;AACxC,SAAC,CAAC,CAAA;AACH,KAAA;AAAM,SAAA;QACL,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,WAAW,CAAC,IAAI,SAAS,EAAE,CAAC,CAAA;AACzE,KAAA;AACH,CAAC;AAEe,SAAA,UAAU,CACxB,SAAmE,EACnE,QAAgB,EAAA;AAEhB,IAAA,eAAe,CAAC,SAAS,EAAE,QAAQ,CAAC;AACjC,SAAA,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;AACnB,SAAA,MAAM,EAAE,CAAA;AACb;;;;"}
|
|
@@ -17,7 +17,7 @@ const variables = injectGlobal `
|
|
|
17
17
|
|
|
18
18
|
--vis-chord-diagram-label-text-fill-color-bright: #ffffff;
|
|
19
19
|
--vis-chord-diagram-label-text-fill-color-dark: #a5abb2;
|
|
20
|
-
--vis-chord-diagram-label-text-font-size:
|
|
20
|
+
--vis-chord-diagram-label-text-font-size: 1em;
|
|
21
21
|
|
|
22
22
|
--vis-dark-chord-diagram-link-fill-color: #575c65;
|
|
23
23
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.js","sources":["../../../src/components/chord-diagram/style.ts"],"sourcesContent":["import { css, injectGlobal } from '@emotion/css'\n\nexport const root = css`\n label: chord-diagram-component;\n`\n\nexport const variables = injectGlobal`\n :root {\n --vis-chord-diagram-link-fill-color: #cad5f6;\n --vis-chord-diagram-link-stroke-color: #777777;\n --vis-chord-diagram-link-opacity: 0.5;\n --vis-chord-diagram-link-stroke-opacity: 0.15;\n --vis-chord-diagram-link-highlighted-opacity: 0.9;\n --vis-chord-diagram-link-dimmed-opacity: 0.25;\n\n --vis-chord-diagram-node-highlighted-opacity: 0.9;\n --vis-chord-diagram-node-dimmed-opacity: 0.25;\n\n --vis-chord-diagram-label-text-fill-color-bright: #ffffff;\n --vis-chord-diagram-label-text-fill-color-dark: #a5abb2;\n --vis-chord-diagram-label-text-font-size:
|
|
1
|
+
{"version":3,"file":"style.js","sources":["../../../src/components/chord-diagram/style.ts"],"sourcesContent":["import { css, injectGlobal } from '@emotion/css'\n\nexport const root = css`\n label: chord-diagram-component;\n`\n\nexport const variables = injectGlobal`\n :root {\n --vis-chord-diagram-link-fill-color: #cad5f6;\n --vis-chord-diagram-link-stroke-color: #777777;\n --vis-chord-diagram-link-opacity: 0.5;\n --vis-chord-diagram-link-stroke-opacity: 0.15;\n --vis-chord-diagram-link-highlighted-opacity: 0.9;\n --vis-chord-diagram-link-dimmed-opacity: 0.25;\n\n --vis-chord-diagram-node-highlighted-opacity: 0.9;\n --vis-chord-diagram-node-dimmed-opacity: 0.25;\n\n --vis-chord-diagram-label-text-fill-color-bright: #ffffff;\n --vis-chord-diagram-label-text-fill-color-dark: #a5abb2;\n --vis-chord-diagram-label-text-font-size: 1em;\n\n --vis-dark-chord-diagram-link-fill-color: #575c65;\n }\n\n body.theme-dark ${`.${root}`} {\n --vis-chord-diagram-link-fill-color: var(--vis-dark-chord-diagram-link-fill-color);\n }\n`\n\nexport const background = css`\n label: background;\n`\n\nexport const nodes = css`\n label: nodes;\n`\n\nexport const links = css`\n label: links;\n`\n\nexport const labels = css`\n label: labels;\n`\n\nexport const node = css`\n label: node;\n stroke-width: 0;\n fill: var(--vis-color-main);\n stroke: var(--vis-color-main);\n transition: .1s fill-opacity;\n`\n\nexport const highlightedNode = css`\n label: highlighted;\n fill-opacity: var(--vis-chord-diagram-node-highlighted-opacity);\n stroke-width: 1.5;\n`\n\nexport const label = css`\n label: label;\n`\n\nexport const labelText = css`\n label: label-text;\n\n dominant-baseline: middle;\n user-select: none;\n font-size: var(--vis-chord-diagram-label-text-font-size);\n \n > textPath {\n dominant-baseline: central;\n }\n`\n\nexport const labelExit = css`\n label: label-exit;\n`\n\nexport const link = css`\n label: link;\n\n fill: var(--vis-chord-diagram-link-fill-color);\n fill-opacity: var(--vis-chord-diagram-link-opacity);\n stroke: var(--vis-chord-diagram-link-stroke-color);\n stroke-opacity: var(--vis-chord-diagram-link-stroke-opacity);\n transition: .1s fill-opacity;\n`\nexport const highlightedLink = css`\n label: highlighted;\n fill-opacity: var(--vis-chord-diagram-link-highlighted-opacity);\n`\n\nexport const transparent = css`\n label: transparent;\n\n ${`.${link}`}:not(${`.${highlightedLink}`}) {\n fill-opacity: var(--vis-chord-diagram-link-dimmed-opacity);\n }\n\n ${`.${node}`}:not(${`.${highlightedNode}`}) {\n fill-opacity: var(--vis-chord-diagram-node-dimmed-opacity);\n }\n`\n"],"names":[],"mappings":";;AAEO,MAAM,IAAI,GAAG,GAAG,CAAA,CAAA;;EAEtB;AAEM,MAAM,SAAS,GAAG,YAAY,CAAA,CAAA;;;;;;;;;;;;;;;;;;;AAmBjB,kBAAA,EAAA,CAAA,CAAA,EAAI,IAAI,CAAE,CAAA,CAAA;;;EAG7B;AAEM,MAAM,UAAU,GAAG,GAAG,CAAA,CAAA;;EAE5B;AAEM,MAAM,KAAK,GAAG,GAAG,CAAA,CAAA;;EAEvB;AAEM,MAAM,KAAK,GAAG,GAAG,CAAA,CAAA;;EAEvB;AAEM,MAAM,MAAM,GAAG,GAAG,CAAA,CAAA;;EAExB;AAEM,MAAM,IAAI,GAAG,GAAG,CAAA,CAAA;;;;;;EAMtB;AAEM,MAAM,eAAe,GAAG,GAAG,CAAA,CAAA;;;;EAIjC;AAEM,MAAM,KAAK,GAAG,GAAG,CAAA,CAAA;;EAEvB;AAEM,MAAM,SAAS,GAAG,GAAG,CAAA,CAAA;;;;;;;;;;EAU3B;AAEM,MAAM,SAAS,GAAG,GAAG,CAAA,CAAA;;EAE3B;AAEM,MAAM,IAAI,GAAG,GAAG,CAAA,CAAA;;;;;;;;EAQtB;AACM,MAAM,eAAe,GAAG,GAAG,CAAA,CAAA;;;EAGjC;AAEM,MAAM,WAAW,GAAG,GAAG,CAAA,CAAA;;;AAG1B,EAAA,EAAA,CAAA,CAAA,EAAI,IAAI,CAAA,CAAE,CAAQ,KAAA,EAAA,CAAA,CAAA,EAAI,eAAe,CAAE,CAAA,CAAA;;;;AAIvC,EAAA,EAAA,CAAA,CAAA,EAAI,IAAI,CAAA,CAAE,CAAQ,KAAA,EAAA,CAAA,CAAA,EAAI,eAAe,CAAE,CAAA,CAAA;;;;;;;"}
|
|
@@ -11,6 +11,10 @@ export interface CrosshairConfigInterface<Datum> extends WithOptional<XYComponen
|
|
|
11
11
|
y?: NumericAccessor<Datum> | NumericAccessor<Datum>[];
|
|
12
12
|
/** Optional color array or color accessor function for crosshair circles. Default: `d => d.color` */
|
|
13
13
|
color?: ColorAccessor<Datum>;
|
|
14
|
+
/** Optional stroke color accessor function for crosshair circles. Default: `undefined` */
|
|
15
|
+
strokeColor?: ColorAccessor<Datum>;
|
|
16
|
+
/** Optional stroke width for crosshair circles. Default: `undefined` */
|
|
17
|
+
strokeWidth?: NumericAccessor<Datum>;
|
|
14
18
|
/** Separate array of accessors for stacked components (eg StackedBar, Area). Default: `undefined` */
|
|
15
19
|
yStacked?: NumericAccessor<Datum>[];
|
|
16
20
|
/** Baseline accessor function for stacked values, useful with stacked areas. Default: `null` */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { XYComponentDefaultConfig } from '../../core/xy-component/config.js';
|
|
2
2
|
|
|
3
|
-
const CrosshairDefaultConfig = Object.assign(Object.assign({}, XYComponentDefaultConfig), { yStacked: undefined, baseline: null, duration: 100, tooltip: undefined, template: (d, x) => '', hideWhenFarFromPointer: true, hideWhenFarFromPointerDistance: 100, snapToData: true, getCircles: undefined, color: undefined });
|
|
3
|
+
const CrosshairDefaultConfig = Object.assign(Object.assign({}, XYComponentDefaultConfig), { yStacked: undefined, baseline: null, duration: 100, tooltip: undefined, template: (d, x) => '', hideWhenFarFromPointer: true, hideWhenFarFromPointerDistance: 100, snapToData: true, getCircles: undefined, color: undefined, strokeColor: undefined, strokeWidth: undefined });
|
|
4
4
|
|
|
5
5
|
export { CrosshairDefaultConfig };
|
|
6
6
|
//# sourceMappingURL=config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sources":["../../../src/components/crosshair/config.ts"],"sourcesContent":["import { XYComponentConfigInterface, XYComponentDefaultConfig } from 'core/xy-component/config'\nimport { Tooltip } from 'components/tooltip'\n\n// Types\nimport { NumericAccessor, ColorAccessor } from 'types/accessor'\nimport { ContinuousScale } from 'types/scale'\nimport { WithOptional } from 'types/misc'\nimport { CrosshairCircle } from './types'\n\n// We extend partial XY config interface because x and y properties are optional for Crosshair\nexport interface CrosshairConfigInterface<Datum> extends WithOptional<XYComponentConfigInterface<Datum>, 'x' | 'y'> {\n /** Optional accessor function for getting the values along the X axis. Default: `undefined` */\n x?: NumericAccessor<Datum>;\n /** Optional single of multiple accessor functions for getting the values along the Y axis. Default: `undefined` */\n y?: NumericAccessor<Datum> | NumericAccessor<Datum>[];\n /** Optional color array or color accessor function for crosshair circles. Default: `d => d.color` */\n color?: ColorAccessor<Datum>;\n /** Separate array of accessors for stacked components (eg StackedBar, Area). Default: `undefined` */\n yStacked?: NumericAccessor<Datum>[];\n /** Baseline accessor function for stacked values, useful with stacked areas. Default: `null` */\n baseline?: NumericAccessor<Datum>;\n /** An instance of the Tooltip component to be used with Crosshair. Default: `undefined` */\n tooltip?: Tooltip | undefined;\n /** Tooltip template accessor. The function is supposed to return either a valid HTML string or an HTMLElement. Default: `d => ''` */\n template?: (data: Datum, x: number | Date) => string | HTMLElement;\n /** Hide Crosshair when the corresponding element is far from mouse pointer. Default: `true` */\n hideWhenFarFromPointer?: boolean;\n /** Distance in pixels to check in the hideWhenFarFromPointer condition. Default: `100` */\n hideWhenFarFromPointerDistance?: number;\n /** Snap to the nearest data point.\n * If disabled, the tooltip template will receive only the horizontal position of the crosshair and you'll be responsible\n * for getting the underlying data records and crosshair circles (see the `getCircles` configuration option).\n * Default: `true`\n */\n snapToData?: boolean;\n /** Custom function for setting up the crosshair circles, usually needed when `snapToData` is set to `false`.\n * The function receives the horizontal position of the crosshair (in the data space, not in pixels), the data array\n * and the `yScale` instance to help you calculate the correct vertical position of the circles.\n * It has to return an array of the CrosshairCircle objects: `{ y: number; color: string; opacity?: number }[]`.\n * Default: `undefined`\n */\n getCircles?: (x: number | Date | Date, data: Datum[], yScale: ContinuousScale) => CrosshairCircle[];\n}\n\nexport const CrosshairDefaultConfig: CrosshairConfigInterface<unknown> = {\n ...XYComponentDefaultConfig,\n yStacked: undefined,\n baseline: null,\n duration: 100,\n tooltip: undefined,\n template: <Datum>(d: Datum, x: number | Date): string => '',\n hideWhenFarFromPointer: true,\n hideWhenFarFromPointerDistance: 100,\n snapToData: true,\n getCircles: undefined,\n color: undefined,\n}\n\n"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"config.js","sources":["../../../src/components/crosshair/config.ts"],"sourcesContent":["import { XYComponentConfigInterface, XYComponentDefaultConfig } from 'core/xy-component/config'\nimport { Tooltip } from 'components/tooltip'\n\n// Types\nimport { NumericAccessor, ColorAccessor } from 'types/accessor'\nimport { ContinuousScale } from 'types/scale'\nimport { WithOptional } from 'types/misc'\nimport { CrosshairCircle } from './types'\n\n// We extend partial XY config interface because x and y properties are optional for Crosshair\nexport interface CrosshairConfigInterface<Datum> extends WithOptional<XYComponentConfigInterface<Datum>, 'x' | 'y'> {\n /** Optional accessor function for getting the values along the X axis. Default: `undefined` */\n x?: NumericAccessor<Datum>;\n /** Optional single of multiple accessor functions for getting the values along the Y axis. Default: `undefined` */\n y?: NumericAccessor<Datum> | NumericAccessor<Datum>[];\n /** Optional color array or color accessor function for crosshair circles. Default: `d => d.color` */\n color?: ColorAccessor<Datum>;\n /** Optional stroke color accessor function for crosshair circles. Default: `undefined` */\n strokeColor?: ColorAccessor<Datum>;\n /** Optional stroke width for crosshair circles. Default: `undefined` */\n strokeWidth?: NumericAccessor<Datum>;\n /** Separate array of accessors for stacked components (eg StackedBar, Area). Default: `undefined` */\n yStacked?: NumericAccessor<Datum>[];\n /** Baseline accessor function for stacked values, useful with stacked areas. Default: `null` */\n baseline?: NumericAccessor<Datum>;\n /** An instance of the Tooltip component to be used with Crosshair. Default: `undefined` */\n tooltip?: Tooltip | undefined;\n /** Tooltip template accessor. The function is supposed to return either a valid HTML string or an HTMLElement. Default: `d => ''` */\n template?: (data: Datum, x: number | Date) => string | HTMLElement;\n /** Hide Crosshair when the corresponding element is far from mouse pointer. Default: `true` */\n hideWhenFarFromPointer?: boolean;\n /** Distance in pixels to check in the hideWhenFarFromPointer condition. Default: `100` */\n hideWhenFarFromPointerDistance?: number;\n /** Snap to the nearest data point.\n * If disabled, the tooltip template will receive only the horizontal position of the crosshair and you'll be responsible\n * for getting the underlying data records and crosshair circles (see the `getCircles` configuration option).\n * Default: `true`\n */\n snapToData?: boolean;\n /** Custom function for setting up the crosshair circles, usually needed when `snapToData` is set to `false`.\n * The function receives the horizontal position of the crosshair (in the data space, not in pixels), the data array\n * and the `yScale` instance to help you calculate the correct vertical position of the circles.\n * It has to return an array of the CrosshairCircle objects: `{ y: number; color: string; opacity?: number }[]`.\n * Default: `undefined`\n */\n getCircles?: (x: number | Date | Date, data: Datum[], yScale: ContinuousScale) => CrosshairCircle[];\n}\n\nexport const CrosshairDefaultConfig: CrosshairConfigInterface<unknown> = {\n ...XYComponentDefaultConfig,\n yStacked: undefined,\n baseline: null,\n duration: 100,\n tooltip: undefined,\n template: <Datum>(d: Datum, x: number | Date): string => '',\n hideWhenFarFromPointer: true,\n hideWhenFarFromPointerDistance: 100,\n snapToData: true,\n getCircles: undefined,\n color: undefined,\n strokeColor: undefined,\n strokeWidth: undefined,\n}\n\n"],"names":[],"mappings":";;AAgDO,MAAM,sBAAsB,GAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,EAAA,EAC9B,wBAAwB,CAAA,EAAA,EAC3B,QAAQ,EAAE,SAAS,EACnB,QAAQ,EAAE,IAAI,EACd,QAAQ,EAAE,GAAG,EACb,OAAO,EAAE,SAAS,EAClB,QAAQ,EAAE,CAAQ,CAAQ,EAAE,CAAgB,KAAa,EAAE,EAC3D,sBAAsB,EAAE,IAAI,EAC5B,8BAA8B,EAAE,GAAG,EACnC,UAAU,EAAE,IAAI,EAChB,UAAU,EAAE,SAAS,EACrB,KAAK,EAAE,SAAS,EAChB,WAAW,EAAE,SAAS,EACtB,WAAW,EAAE,SAAS;;;;"}
|
|
@@ -71,13 +71,17 @@ class Crosshair extends XYComponentCore {
|
|
|
71
71
|
.attr('r', 0)
|
|
72
72
|
.attr('cx', this.x)
|
|
73
73
|
.attr('cy', d => d.y)
|
|
74
|
-
.style('fill', d => d.color)
|
|
74
|
+
.style('fill', d => d.color)
|
|
75
|
+
.style('stroke', d => d.strokeColor)
|
|
76
|
+
.style('stroke-width', d => d.strokeWidth);
|
|
75
77
|
smartTransition(circlesEnter.merge(circles), duration, easeLinear)
|
|
76
78
|
.attr('cx', this.x)
|
|
77
79
|
.attr('cy', d => d.y)
|
|
78
80
|
.attr('r', 4)
|
|
79
81
|
.style('opacity', d => d.opacity)
|
|
80
|
-
.style('fill', d => d.color)
|
|
82
|
+
.style('fill', d => d.color)
|
|
83
|
+
.style('stroke', d => d.strokeColor)
|
|
84
|
+
.style('stroke-width', d => d.strokeWidth);
|
|
81
85
|
circles.exit().remove();
|
|
82
86
|
}
|
|
83
87
|
hide() {
|
|
@@ -161,16 +165,20 @@ class Crosshair extends XYComponentCore {
|
|
|
161
165
|
const stackedValues = getStackedValues(this.datum, this.datumIndex, ...yStackedAccessors)
|
|
162
166
|
.map((value, index, arr) => ({
|
|
163
167
|
y: this.yScale(value + baselineValue),
|
|
164
|
-
opacity: getNumber(this.datum, yStackedAccessors[index]) ? 1 : 0,
|
|
168
|
+
opacity: isNumber(getNumber(this.datum, yStackedAccessors[index])) ? 1 : 0,
|
|
165
169
|
color: getColor(this.datum, config.color, index),
|
|
170
|
+
strokeColor: config.strokeColor ? getColor(this.datum, config.strokeColor, index) : undefined,
|
|
171
|
+
strokeWidth: config.strokeWidth ? getNumber(this.datum, config.strokeWidth, index) : undefined,
|
|
166
172
|
}));
|
|
167
173
|
const regularValues = yAccessors
|
|
168
174
|
.map((a, index) => {
|
|
169
175
|
const value = getNumber(this.datum, a);
|
|
170
176
|
return {
|
|
171
177
|
y: this.yScale(value),
|
|
172
|
-
opacity: value ? 1 : 0,
|
|
178
|
+
opacity: isNumber(value) ? 1 : 0,
|
|
173
179
|
color: getColor(this.datum, config.color, stackedValues.length + index),
|
|
180
|
+
strokeColor: config.strokeColor ? getColor(this.datum, config.strokeColor, index) : undefined,
|
|
181
|
+
strokeWidth: config.strokeWidth ? getNumber(this.datum, config.strokeWidth, index) : undefined,
|
|
174
182
|
};
|
|
175
183
|
});
|
|
176
184
|
return stackedValues.concat(regularValues);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/components/crosshair/index.ts"],"sourcesContent":["import { Selection, pointer } from 'd3-selection'\nimport { easeLinear } from 'd3-ease'\n\n// Core\nimport { XYComponentCore } from 'core/xy-component'\nimport { Tooltip } from 'components/tooltip'\n\n// Utils\nimport { isNumber, isArray, getNumber, clamp, getStackedValues, getNearest, isFunction } from 'utils/data'\nimport { smartTransition } from 'utils/d3'\nimport { getColor } from 'utils/color'\n\n// Local Types\nimport { CrosshairAccessors, CrosshairCircle } from './types'\n\n// Config\nimport { CrosshairDefaultConfig, CrosshairConfigInterface } from './config'\n\n// Styles\nimport * as s from './style'\n\nexport class Crosshair<Datum> extends XYComponentCore<Datum, CrosshairConfigInterface<Datum>> {\n static selectors = s\n clippable = true // Don't apply clipping path to this component. See XYContainer\n protected _defaultConfig = CrosshairDefaultConfig as CrosshairConfigInterface<Datum>\n public config: CrosshairConfigInterface<Datum> = this._defaultConfig\n container: Selection<SVGSVGElement, any, SVGSVGElement, any>\n line: Selection<SVGLineElement, any, SVGElement, any>\n x = 0\n datum: Datum\n datumIndex: number\n show = false\n private _animFrameId: number = null\n\n /** Tooltip component to be used by Crosshair if not provided by the config.\n * This property is supposed to be set externally by a container component like XYContainer. */\n public tooltip: Tooltip\n\n /** Accessors passed externally (e.g. from XYContainer) */\n private _accessors: CrosshairAccessors<Datum> = {\n x: undefined,\n y: undefined,\n yStacked: undefined,\n baseline: undefined,\n }\n\n public set accessors (accessors: CrosshairAccessors<Datum>) { this._accessors = accessors }\n public get accessors (): CrosshairAccessors<Datum> {\n const { config } = this\n\n const hasConfig = !!(config.x || config.y || config.yStacked)\n const x = hasConfig ? config.x : this._accessors.x\n const yAcc = hasConfig ? config.y : this._accessors.y\n const y = yAcc ? (isArray(yAcc) ? yAcc : [yAcc]) : undefined\n const yStacked = hasConfig ? config.yStacked : this._accessors.yStacked\n const baseline = config.baseline ?? this._accessors.baseline\n\n return { x, y, yStacked, baseline }\n }\n\n constructor (config?: CrosshairConfigInterface<Datum>) {\n super()\n if (config) this.setConfig(config)\n\n this.g.style('opacity', this.show ? 1 : 0)\n this.line = this.g.append('line')\n .attr('class', s.line)\n }\n\n setContainer (containerSvg: Selection<SVGSVGElement, unknown, SVGSVGElement, unknown>): void {\n // Set up mousemove event for Crosshair\n this.container = containerSvg\n this.container.on('mousemove.crosshair', this._onMouseMove.bind(this))\n this.container.on('mouseout.crosshair', this._onMouseOut.bind(this))\n }\n\n _render (customDuration?: number): void {\n const { config } = this\n if (config.snapToData && !this.datum) return\n const duration = isNumber(customDuration) ? customDuration : config.duration\n\n smartTransition(this.g, duration)\n .style('opacity', this.show ? 1 : 0)\n\n this.line\n .attr('y1', 0)\n .attr('y1', this._height)\n\n smartTransition(this.line, duration, easeLinear)\n .attr('x1', this.x)\n .attr('x2', this.x)\n\n const circleData = this.getCircleData()\n const circles = this.g\n .selectAll<SVGCircleElement, CrosshairCircle>('circle')\n .data(circleData, (d, i) => d.id ?? i)\n\n const circlesEnter = circles.enter()\n .append('circle')\n .attr('class', s.circle)\n .attr('r', 0)\n .attr('cx', this.x)\n .attr('cy', d => d.y)\n .style('fill', d => d.color)\n\n smartTransition(circlesEnter.merge(circles), duration, easeLinear)\n .attr('cx', this.x)\n .attr('cy', d => d.y)\n .attr('r', 4)\n .style('opacity', d => d.opacity)\n .style('fill', d => d.color)\n\n circles.exit().remove()\n }\n\n hide (): void {\n this._onMouseOut()\n }\n\n _onMouseMove (event: MouseEvent): void {\n const { config, datamodel, element } = this\n if (!this.accessors.x && datamodel.data?.length) {\n console.warn('Unovis | Crosshair: X accessor function has not been configured. Please check if it\\'s present in the configuration object')\n }\n const [x] = pointer(event, element)\n const xRange = this.xScale.range()\n\n if (config.snapToData) {\n if (!this.accessors.y && !this.accessors.yStacked && datamodel.data?.length) {\n console.warn('Unovis | Crosshair: Y accessors have not been configured. Please check if they\\'re present in the configuration object')\n }\n const scaleX = this.xScale\n const valueX = scaleX.invert(x) as number\n\n this.datum = getNearest(datamodel.data, valueX, this.accessors.x)\n this.datumIndex = datamodel.data.indexOf(this.datum)\n if (!this.datum) return\n\n this.x = clamp(Math.round(scaleX(getNumber(this.datum, this.accessors.x, this.datumIndex))), 0, this._width)\n\n // Show the crosshair only if it's in the chart range and not far from mouse pointer (if configured)\n this.show = (this.x >= 0) && (this.x <= this._width) && (!config.hideWhenFarFromPointer || (Math.abs(this.x - x) < config.hideWhenFarFromPointerDistance))\n } else {\n const tolerance = 2 // Show the crosshair when it is at least 2 pixels close to the chart area\n this.x = clamp(x, xRange[0], xRange[1])\n this.show = (x >= (xRange[0] - tolerance)) && (x <= (xRange[1] + tolerance))\n }\n\n window.cancelAnimationFrame(this._animFrameId)\n this._animFrameId = window.requestAnimationFrame(() => {\n this._render()\n })\n\n if (this.show) this._showTooltip(event)\n else this._hideTooltip()\n }\n\n _onMouseOut (): void {\n this.show = false\n\n window.cancelAnimationFrame(this._animFrameId)\n this._animFrameId = window.requestAnimationFrame(() => {\n this._render()\n })\n this._hideTooltip()\n }\n\n _showTooltip (event: MouseEvent): void {\n const { config } = this\n const tooltip = config.tooltip ?? this.tooltip\n if (!tooltip) return\n\n const container = tooltip.getContainer() || this.container.node()\n const [x, y] = tooltip.isContainerBody() ? [event.clientX, event.clientY] : pointer(event, container)\n const content = config.template(this.datum, this.xScale.invert(this.x))\n if (content) tooltip.show(content, { x, y })\n }\n\n _hideTooltip (): void {\n const { config } = this\n const tooltip = config.tooltip ?? this.tooltip\n tooltip?.hide()\n }\n\n // We don't want Crosshair to be be taken in to account in domain calculations\n getYDataExtent (): number[] {\n return [undefined, undefined]\n }\n\n private getCircleData (): CrosshairCircle[] {\n const { config, datamodel: { data } } = this\n\n if (isFunction(config.getCircles)) return config.getCircles(this.xScale.invert(this.x), data, this.yScale)\n\n if (config.snapToData && this.datum) {\n const yAccessors = this.accessors.y ?? []\n const yStackedAccessors = this.accessors.yStacked ?? []\n const baselineValue = getNumber(this.datum, this.accessors.baseline, this.datumIndex) || 0\n const stackedValues: CrosshairCircle[] = getStackedValues(this.datum, this.datumIndex, ...yStackedAccessors)\n .map((value, index, arr) => ({\n y: this.yScale(value + baselineValue),\n opacity: getNumber(this.datum, yStackedAccessors[index]) ? 1 : 0,\n color: getColor(this.datum, config.color, index),\n }))\n\n const regularValues: CrosshairCircle[] = yAccessors\n .map((a, index) => {\n const value = getNumber(this.datum, a)\n return {\n y: this.yScale(value),\n opacity: value ? 1 : 0,\n color: getColor(this.datum, config.color, stackedValues.length + index),\n }\n })\n\n return stackedValues.concat(regularValues)\n }\n\n return []\n }\n}\n"],"names":["s.line","s.circle","s"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/components/crosshair/index.ts"],"sourcesContent":["import { Selection, pointer } from 'd3-selection'\nimport { easeLinear } from 'd3-ease'\n\n// Core\nimport { XYComponentCore } from 'core/xy-component'\nimport { Tooltip } from 'components/tooltip'\n\n// Utils\nimport { isNumber, isArray, getNumber, clamp, getStackedValues, getNearest, isFunction } from 'utils/data'\nimport { smartTransition } from 'utils/d3'\nimport { getColor } from 'utils/color'\n\n// Local Types\nimport { CrosshairAccessors, CrosshairCircle } from './types'\n\n// Config\nimport { CrosshairDefaultConfig, CrosshairConfigInterface } from './config'\n\n// Styles\nimport * as s from './style'\n\nexport class Crosshair<Datum> extends XYComponentCore<Datum, CrosshairConfigInterface<Datum>> {\n static selectors = s\n clippable = true // Don't apply clipping path to this component. See XYContainer\n protected _defaultConfig = CrosshairDefaultConfig as CrosshairConfigInterface<Datum>\n public config: CrosshairConfigInterface<Datum> = this._defaultConfig\n container: Selection<SVGSVGElement, any, SVGSVGElement, any>\n line: Selection<SVGLineElement, any, SVGElement, any>\n x = 0\n datum: Datum\n datumIndex: number\n show = false\n private _animFrameId: number = null\n\n /** Tooltip component to be used by Crosshair if not provided by the config.\n * This property is supposed to be set externally by a container component like XYContainer. */\n public tooltip: Tooltip\n\n /** Accessors passed externally (e.g. from XYContainer) */\n private _accessors: CrosshairAccessors<Datum> = {\n x: undefined,\n y: undefined,\n yStacked: undefined,\n baseline: undefined,\n }\n\n public set accessors (accessors: CrosshairAccessors<Datum>) { this._accessors = accessors }\n public get accessors (): CrosshairAccessors<Datum> {\n const { config } = this\n\n const hasConfig = !!(config.x || config.y || config.yStacked)\n const x = hasConfig ? config.x : this._accessors.x\n const yAcc = hasConfig ? config.y : this._accessors.y\n const y = yAcc ? (isArray(yAcc) ? yAcc : [yAcc]) : undefined\n const yStacked = hasConfig ? config.yStacked : this._accessors.yStacked\n const baseline = config.baseline ?? this._accessors.baseline\n\n return { x, y, yStacked, baseline }\n }\n\n constructor (config?: CrosshairConfigInterface<Datum>) {\n super()\n if (config) this.setConfig(config)\n\n this.g.style('opacity', this.show ? 1 : 0)\n this.line = this.g.append('line')\n .attr('class', s.line)\n }\n\n setContainer (containerSvg: Selection<SVGSVGElement, unknown, SVGSVGElement, unknown>): void {\n // Set up mousemove event for Crosshair\n this.container = containerSvg\n this.container.on('mousemove.crosshair', this._onMouseMove.bind(this))\n this.container.on('mouseout.crosshair', this._onMouseOut.bind(this))\n }\n\n _render (customDuration?: number): void {\n const { config } = this\n if (config.snapToData && !this.datum) return\n const duration = isNumber(customDuration) ? customDuration : config.duration\n\n smartTransition(this.g, duration)\n .style('opacity', this.show ? 1 : 0)\n\n this.line\n .attr('y1', 0)\n .attr('y1', this._height)\n\n smartTransition(this.line, duration, easeLinear)\n .attr('x1', this.x)\n .attr('x2', this.x)\n\n const circleData = this.getCircleData()\n const circles = this.g\n .selectAll<SVGCircleElement, CrosshairCircle>('circle')\n .data(circleData, (d, i) => d.id ?? i)\n\n const circlesEnter = circles.enter()\n .append('circle')\n .attr('class', s.circle)\n .attr('r', 0)\n .attr('cx', this.x)\n .attr('cy', d => d.y)\n .style('fill', d => d.color)\n .style('stroke', d => d.strokeColor)\n .style('stroke-width', d => d.strokeWidth)\n\n smartTransition(circlesEnter.merge(circles), duration, easeLinear)\n .attr('cx', this.x)\n .attr('cy', d => d.y)\n .attr('r', 4)\n .style('opacity', d => d.opacity)\n .style('fill', d => d.color)\n .style('stroke', d => d.strokeColor)\n .style('stroke-width', d => d.strokeWidth)\n\n circles.exit().remove()\n }\n\n hide (): void {\n this._onMouseOut()\n }\n\n _onMouseMove (event: MouseEvent): void {\n const { config, datamodel, element } = this\n if (!this.accessors.x && datamodel.data?.length) {\n console.warn('Unovis | Crosshair: X accessor function has not been configured. Please check if it\\'s present in the configuration object')\n }\n const [x] = pointer(event, element)\n const xRange = this.xScale.range()\n\n if (config.snapToData) {\n if (!this.accessors.y && !this.accessors.yStacked && datamodel.data?.length) {\n console.warn('Unovis | Crosshair: Y accessors have not been configured. Please check if they\\'re present in the configuration object')\n }\n const scaleX = this.xScale\n const valueX = scaleX.invert(x) as number\n\n this.datum = getNearest(datamodel.data, valueX, this.accessors.x)\n this.datumIndex = datamodel.data.indexOf(this.datum)\n if (!this.datum) return\n\n this.x = clamp(Math.round(scaleX(getNumber(this.datum, this.accessors.x, this.datumIndex))), 0, this._width)\n\n // Show the crosshair only if it's in the chart range and not far from mouse pointer (if configured)\n this.show = (this.x >= 0) && (this.x <= this._width) && (!config.hideWhenFarFromPointer || (Math.abs(this.x - x) < config.hideWhenFarFromPointerDistance))\n } else {\n const tolerance = 2 // Show the crosshair when it is at least 2 pixels close to the chart area\n this.x = clamp(x, xRange[0], xRange[1])\n this.show = (x >= (xRange[0] - tolerance)) && (x <= (xRange[1] + tolerance))\n }\n\n window.cancelAnimationFrame(this._animFrameId)\n this._animFrameId = window.requestAnimationFrame(() => {\n this._render()\n })\n\n if (this.show) this._showTooltip(event)\n else this._hideTooltip()\n }\n\n _onMouseOut (): void {\n this.show = false\n\n window.cancelAnimationFrame(this._animFrameId)\n this._animFrameId = window.requestAnimationFrame(() => {\n this._render()\n })\n this._hideTooltip()\n }\n\n _showTooltip (event: MouseEvent): void {\n const { config } = this\n const tooltip = config.tooltip ?? this.tooltip\n if (!tooltip) return\n\n const container = tooltip.getContainer() || this.container.node()\n const [x, y] = tooltip.isContainerBody() ? [event.clientX, event.clientY] : pointer(event, container)\n const content = config.template(this.datum, this.xScale.invert(this.x))\n if (content) tooltip.show(content, { x, y })\n }\n\n _hideTooltip (): void {\n const { config } = this\n const tooltip = config.tooltip ?? this.tooltip\n tooltip?.hide()\n }\n\n // We don't want Crosshair to be be taken in to account in domain calculations\n getYDataExtent (): number[] {\n return [undefined, undefined]\n }\n\n private getCircleData (): CrosshairCircle[] {\n const { config, datamodel: { data } } = this\n\n if (isFunction(config.getCircles)) return config.getCircles(this.xScale.invert(this.x), data, this.yScale)\n\n if (config.snapToData && this.datum) {\n const yAccessors = this.accessors.y ?? []\n const yStackedAccessors = this.accessors.yStacked ?? []\n const baselineValue = getNumber(this.datum, this.accessors.baseline, this.datumIndex) || 0\n const stackedValues: CrosshairCircle[] = getStackedValues(this.datum, this.datumIndex, ...yStackedAccessors)\n .map((value, index, arr) => ({\n y: this.yScale(value + baselineValue),\n opacity: isNumber(getNumber(this.datum, yStackedAccessors[index])) ? 1 : 0,\n color: getColor(this.datum, config.color, index),\n strokeColor: config.strokeColor ? getColor(this.datum, config.strokeColor, index) : undefined,\n strokeWidth: config.strokeWidth ? getNumber(this.datum, config.strokeWidth, index) : undefined,\n }))\n\n const regularValues: CrosshairCircle[] = yAccessors\n .map((a, index) => {\n const value = getNumber(this.datum, a)\n return {\n y: this.yScale(value),\n opacity: isNumber(value) ? 1 : 0,\n color: getColor(this.datum, config.color, stackedValues.length + index),\n strokeColor: config.strokeColor ? getColor(this.datum, config.strokeColor, index) : undefined,\n strokeWidth: config.strokeWidth ? getNumber(this.datum, config.strokeWidth, index) : undefined,\n }\n })\n\n return stackedValues.concat(regularValues)\n }\n\n return []\n }\n}\n"],"names":["s.line","s.circle","s"],"mappings":"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"}
|
|
@@ -4,8 +4,10 @@ const globalStyles = injectGlobal `
|
|
|
4
4
|
:root {
|
|
5
5
|
--vis-crosshair-line-stroke-color: #888;
|
|
6
6
|
--vis-crosshair-line-stroke-width: 1px;
|
|
7
|
+
--vis-crosshair-line-stroke-opacity: 1;
|
|
7
8
|
--vis-crosshair-circle-stroke-color: #fff;
|
|
8
9
|
--vis-crosshair-circle-stroke-width: 1px;
|
|
10
|
+
--vis-crosshair-circle-stroke-opacity: 0.75;
|
|
9
11
|
}
|
|
10
12
|
`;
|
|
11
13
|
const root = css `
|
|
@@ -14,13 +16,13 @@ const root = css `
|
|
|
14
16
|
const line = css `
|
|
15
17
|
stroke: var(--vis-crosshair-line-stroke-color);
|
|
16
18
|
stroke-width: var(--vis-crosshair-line-stroke-width);
|
|
17
|
-
stroke-opacity:
|
|
19
|
+
stroke-opacity: var(--vis-crosshair-line-stroke-opacity);
|
|
18
20
|
pointer-events: none;
|
|
19
21
|
`;
|
|
20
22
|
const circle = css `
|
|
21
23
|
stroke: var(--vis-crosshair-circle-stroke-color);
|
|
22
24
|
stroke-width: var(--vis-crosshair-circle-stroke-width);
|
|
23
|
-
stroke-opacity:
|
|
25
|
+
stroke-opacity: var(--vis-crosshair-circle-stroke-opacity);
|
|
24
26
|
pointer-events: none;
|
|
25
27
|
`;
|
|
26
28
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.js","sources":["../../../src/components/crosshair/style.ts"],"sourcesContent":["import { css, injectGlobal } from '@emotion/css'\n\nexport const globalStyles = injectGlobal`\n :root {\n --vis-crosshair-line-stroke-color: #888;\n --vis-crosshair-line-stroke-width: 1px;\n --vis-crosshair-circle-stroke-color: #fff;\n --vis-crosshair-circle-stroke-width: 1px;\n }\n`\n\nexport const root = css`\n label: crosshair-component;\n`\n\nexport const line = css`\n stroke: var(--vis-crosshair-line-stroke-color);\n stroke-width: var(--vis-crosshair-line-stroke-width);\n stroke-opacity:
|
|
1
|
+
{"version":3,"file":"style.js","sources":["../../../src/components/crosshair/style.ts"],"sourcesContent":["import { css, injectGlobal } from '@emotion/css'\n\nexport const globalStyles = injectGlobal`\n :root {\n --vis-crosshair-line-stroke-color: #888;\n --vis-crosshair-line-stroke-width: 1px;\n --vis-crosshair-line-stroke-opacity: 1;\n --vis-crosshair-circle-stroke-color: #fff;\n --vis-crosshair-circle-stroke-width: 1px;\n --vis-crosshair-circle-stroke-opacity: 0.75;\n }\n`\n\nexport const root = css`\n label: crosshair-component;\n`\n\nexport const line = css`\n stroke: var(--vis-crosshair-line-stroke-color);\n stroke-width: var(--vis-crosshair-line-stroke-width);\n stroke-opacity: var(--vis-crosshair-line-stroke-opacity);\n pointer-events: none;\n`\n\nexport const circle = css`\n stroke: var(--vis-crosshair-circle-stroke-color);\n stroke-width: var(--vis-crosshair-circle-stroke-width);\n stroke-opacity: var(--vis-crosshair-circle-stroke-opacity);\n pointer-events: none;\n`\n"],"names":[],"mappings":";;AAEO,MAAM,YAAY,GAAG,YAAY,CAAA,CAAA;;;;;;;;;EASvC;AAEM,MAAM,IAAI,GAAG,GAAG,CAAA,CAAA;;EAEtB;AAEM,MAAM,IAAI,GAAG,GAAG,CAAA,CAAA;;;;;EAKtB;AAEM,MAAM,MAAM,GAAG,GAAG,CAAA,CAAA;;;;;;;;;"}
|
|
@@ -4,7 +4,8 @@ import { NestedDonutDirection, NestedDonutLayerSettings, NestedDonutSegment } fr
|
|
|
4
4
|
export interface NestedDonutConfigInterface<Datum> extends ComponentConfigInterface {
|
|
5
5
|
/** Diagram angle range. Default: `[0, 2 * Math.PI]` */
|
|
6
6
|
angleRange?: [number, number];
|
|
7
|
-
/**
|
|
7
|
+
/**
|
|
8
|
+
* Direction of hierarchy flow from root to leaf.
|
|
8
9
|
* `NestedDonutDirection.Inwards` starts from the outer most radius and works towards center
|
|
9
10
|
* `NestedDonutDirection.Outwards` starts from the inner most radius the consecutive layers outward.
|
|
10
11
|
* Default: `NestedDonutDirection.Inwards`
|
|
@@ -27,6 +28,14 @@ export interface NestedDonutConfigInterface<Datum> extends ComponentConfigInterf
|
|
|
27
28
|
sort?: (a: NestedDonutSegment<Datum>, b: NestedDonutSegment<Datum>) => number;
|
|
28
29
|
/** Array of accessor functions to defined the nested groups */
|
|
29
30
|
layers: StringAccessor<Datum>[];
|
|
31
|
+
/**
|
|
32
|
+
* Configuration properties for individual layers. Accepts an accessor or constant of type:
|
|
33
|
+
* {
|
|
34
|
+
* backgroundColor?: string;
|
|
35
|
+
* labelAlignment?: NestedDonutSegmentLabelAlignment;
|
|
36
|
+
* width?: number | string;
|
|
37
|
+
* }
|
|
38
|
+
*/
|
|
30
39
|
layerSettings?: GenericAccessor<NestedDonutLayerSettings, number>;
|
|
31
40
|
layerPadding?: number;
|
|
32
41
|
/** Corner Radius. Default: `0` */
|
|
@@ -41,9 +50,12 @@ export interface NestedDonutConfigInterface<Datum> extends ComponentConfigInterf
|
|
|
41
50
|
segmentLabel?: StringAccessor<NestedDonutSegment<Datum>>;
|
|
42
51
|
/** Color accessor function for segment labels */
|
|
43
52
|
segmentLabelColor?: ColorAccessor<NestedDonutSegment<Datum>>;
|
|
44
|
-
/**
|
|
53
|
+
/**
|
|
54
|
+
* When true, the component will display empty segments (the ones that have `0` values) as tiny slices.
|
|
45
55
|
* Default: `false`
|
|
46
56
|
*/
|
|
47
57
|
showEmptySegments?: boolean;
|
|
58
|
+
/** Show labels for individual segments. Default: `true` */
|
|
59
|
+
showSegmentLabels?: boolean;
|
|
48
60
|
}
|
|
49
61
|
export declare const NestedDonutDefaultConfig: NestedDonutConfigInterface<unknown>;
|
|
@@ -2,7 +2,7 @@ import { ComponentDefaultConfig } from '../../core/component/config.js';
|
|
|
2
2
|
import { NestedDonutDirection } from './types.js';
|
|
3
3
|
|
|
4
4
|
// Core
|
|
5
|
-
const NestedDonutDefaultConfig = Object.assign(Object.assign({}, ComponentDefaultConfig), { angleRange: [0, 2 * Math.PI], centralLabel: undefined, centralSubLabel: undefined, centralSubLabelWrap: true, cornerRadius: 0, direction: NestedDonutDirection.Inwards, emptySegmentAngle: Math.PI / 180, hideOverflowingSegmentLabels: true, layers: [], layerPadding: 0, layerSettings: undefined, segmentColor: undefined, segmentLabel: undefined, segmentLabelColor: undefined, showBackground: false, showEmptySegments: false, sort: undefined, value: undefined });
|
|
5
|
+
const NestedDonutDefaultConfig = Object.assign(Object.assign({}, ComponentDefaultConfig), { angleRange: [0, 2 * Math.PI], centralLabel: undefined, centralSubLabel: undefined, centralSubLabelWrap: true, cornerRadius: 0, direction: NestedDonutDirection.Inwards, emptySegmentAngle: Math.PI / 180, hideOverflowingSegmentLabels: true, layers: [], layerPadding: 0, layerSettings: undefined, segmentColor: undefined, segmentLabel: undefined, segmentLabelColor: undefined, showBackground: false, showEmptySegments: false, showSegmentLabels: true, sort: undefined, value: undefined });
|
|
6
6
|
|
|
7
7
|
export { NestedDonutDefaultConfig };
|
|
8
8
|
//# sourceMappingURL=config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sources":["../../../src/components/nested-donut/config.ts"],"sourcesContent":["// Core\nimport { ComponentConfigInterface, ComponentDefaultConfig } from 'core/component/config'\n\n// Types\nimport { ColorAccessor, GenericAccessor, NumericAccessor, StringAccessor } from 'types/accessor'\nimport { NestedDonutDirection, NestedDonutLayerSettings, NestedDonutSegment } from './types'\n\nexport interface NestedDonutConfigInterface<Datum> extends ComponentConfigInterface {\n /** Diagram angle range. Default: `[0, 2 * Math.PI]` */\n angleRange?: [number, number];\n
|
|
1
|
+
{"version":3,"file":"config.js","sources":["../../../src/components/nested-donut/config.ts"],"sourcesContent":["// Core\nimport { ComponentConfigInterface, ComponentDefaultConfig } from 'core/component/config'\n\n// Types\nimport { ColorAccessor, GenericAccessor, NumericAccessor, StringAccessor } from 'types/accessor'\nimport { NestedDonutDirection, NestedDonutLayerSettings, NestedDonutSegment } from './types'\n\nexport interface NestedDonutConfigInterface<Datum> extends ComponentConfigInterface {\n /** Diagram angle range. Default: `[0, 2 * Math.PI]` */\n angleRange?: [number, number];\n /**\n * Direction of hierarchy flow from root to leaf.\n * `NestedDonutDirection.Inwards` starts from the outer most radius and works towards center\n * `NestedDonutDirection.Outwards` starts from the inner most radius the consecutive layers outward.\n * Default: `NestedDonutDirection.Inwards`\n */\n direction?: NestedDonutDirection | string;\n /* Numeric accessor for segment size value. Default: `undefined`. */\n value?: NumericAccessor<Datum>;\n\n /** Central label text. Default: `undefined` */\n centralLabel?: string;\n /** Central sub-label accessor function or text. Default: `undefined` */\n centralSubLabel?: string;\n /** Enables wrapping for the sub-label. Default: `true` */\n centralSubLabelWrap?: boolean;\n /**\n * Show donut background. The color is configurable via\n * the `--vis-nested-donut-background-color` and `--vis-dark-nested-donut-background-color` CSS variables.\n * Default: `false`\n */\n showBackground?: boolean;\n /** Sort function for segments. Default `undefined` */\n sort?: (a: NestedDonutSegment<Datum>, b: NestedDonutSegment<Datum>) => number;\n\n // Layers\n /** Array of accessor functions to defined the nested groups */\n layers: StringAccessor<Datum>[];\n /**\n * Configuration properties for individual layers. Accepts an accessor or constant of type:\n * {\n * backgroundColor?: string;\n * labelAlignment?: NestedDonutSegmentLabelAlignment;\n * width?: number | string;\n * }\n */\n layerSettings?: GenericAccessor<NestedDonutLayerSettings, number>;\n /* Space between layers */\n layerPadding?: number;\n\n // Segments\n /** Corner Radius. Default: `0` */\n cornerRadius?: number;\n /** Angular size for empty segments in radians. Default: `Math.PI / 180` */\n emptySegmentAngle?: number;\n /** Hide segment labels when they don't fit. Default: `true` */\n hideOverflowingSegmentLabels?: boolean;\n /** Color accessor function for segments. Default: `undefined` */\n segmentColor?: ColorAccessor<NestedDonutSegment<Datum>>;\n /** Segment label accessor function. Default `undefined` */\n segmentLabel?: StringAccessor<NestedDonutSegment<Datum>>;\n /** Color accessor function for segment labels */\n segmentLabelColor?: ColorAccessor<NestedDonutSegment<Datum>>;\n /**\n * When true, the component will display empty segments (the ones that have `0` values) as tiny slices.\n * Default: `false`\n */\n showEmptySegments?: boolean;\n /** Show labels for individual segments. Default: `true` */\n showSegmentLabels?: boolean;\n}\n\nexport const NestedDonutDefaultConfig: NestedDonutConfigInterface<unknown> = {\n ...ComponentDefaultConfig,\n angleRange: [0, 2 * Math.PI],\n centralLabel: undefined,\n centralSubLabel: undefined,\n centralSubLabelWrap: true,\n cornerRadius: 0,\n direction: NestedDonutDirection.Inwards,\n emptySegmentAngle: Math.PI / 180,\n hideOverflowingSegmentLabels: true,\n layers: [],\n layerPadding: 0,\n layerSettings: undefined,\n segmentColor: undefined,\n segmentLabel: undefined,\n segmentLabelColor: undefined,\n showBackground: false,\n showEmptySegments: false,\n showSegmentLabels: true,\n sort: undefined,\n value: undefined,\n}\n"],"names":[],"mappings":";;;AAAA;MAwEa,wBAAwB,GAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,EAAA,EAChC,sBAAsB,CACzB,EAAA,EAAA,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,EAC5B,YAAY,EAAE,SAAS,EACvB,eAAe,EAAE,SAAS,EAC1B,mBAAmB,EAAE,IAAI,EACzB,YAAY,EAAE,CAAC,EACf,SAAS,EAAE,oBAAoB,CAAC,OAAO,EACvC,iBAAiB,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,EAChC,4BAA4B,EAAE,IAAI,EAClC,MAAM,EAAE,EAAE,EACV,YAAY,EAAE,CAAC,EACf,aAAa,EAAE,SAAS,EACxB,YAAY,EAAE,SAAS,EACvB,YAAY,EAAE,SAAS,EACvB,iBAAiB,EAAE,SAAS,EAC5B,cAAc,EAAE,KAAK,EACrB,iBAAiB,EAAE,KAAK,EACxB,iBAAiB,EAAE,IAAI,EACvB,IAAI,EAAE,SAAS,EACf,KAAK,EAAE,SAAS,EAAA;;;;"}
|
|
@@ -41,6 +41,10 @@ class NestedDonut extends ComponentCore {
|
|
|
41
41
|
var _a, _b;
|
|
42
42
|
const { config } = this;
|
|
43
43
|
const duration = isNumber(customDuration) ? customDuration : config.duration;
|
|
44
|
+
if (config.layers === undefined || config.layers.length === 0) {
|
|
45
|
+
console.warn('Unovis | Nested Donut: No layers defined.');
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
44
48
|
const layers = this._getLayerSettings();
|
|
45
49
|
const data = this._getHierarchyData(layers);
|
|
46
50
|
this.arcGen
|
|
@@ -100,16 +104,18 @@ class NestedDonut extends ComponentCore {
|
|
|
100
104
|
.attr('class', segmentExit)
|
|
101
105
|
.call(removeArc, duration);
|
|
102
106
|
// Segment labels
|
|
103
|
-
|
|
104
|
-
.
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
.
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
.
|
|
111
|
-
|
|
112
|
-
.
|
|
107
|
+
if (config.showSegmentLabels) {
|
|
108
|
+
const labels = this.arcGroup
|
|
109
|
+
.selectAll(`.${segmentLabel}`)
|
|
110
|
+
.data(data, d => d._id);
|
|
111
|
+
const labelsEnter = segmentsEnter.append('text')
|
|
112
|
+
.attr('class', segmentLabel)
|
|
113
|
+
.call(createLabel, this.arcGen);
|
|
114
|
+
labels.merge(labelsEnter)
|
|
115
|
+
.call(updateLabel, config, this.arcGen, duration);
|
|
116
|
+
labels.exit()
|
|
117
|
+
.call(removeLabel, duration);
|
|
118
|
+
}
|
|
113
119
|
// Chart labels
|
|
114
120
|
this.centralLabel
|
|
115
121
|
.attr('dy', config.centralSubLabel ? '-0.55em' : null)
|