@unovis/ts 1.2.1-beta.2 → 1.2.1-beta.25
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/axis/config.d.ts +6 -0
- package/components/axis/config.js +2 -0
- package/components/axis/config.js.map +1 -1
- package/components/axis/index.js +5 -3
- package/components/axis/index.js.map +1 -1
- package/components/axis/style.js +3 -2
- package/components/axis/style.js.map +1 -1
- package/components/bullet-legend/config.d.ts +5 -2
- package/components/bullet-legend/config.js +2 -0
- package/components/bullet-legend/config.js.map +1 -1
- package/components/bullet-legend/index.js +6 -16
- package/components/bullet-legend/index.js.map +1 -1
- package/components/bullet-legend/modules/shape.d.ts +6 -0
- package/components/bullet-legend/modules/shape.js +58 -0
- package/components/bullet-legend/modules/shape.js.map +1 -0
- package/components/bullet-legend/style.js +6 -9
- package/components/bullet-legend/style.js.map +1 -1
- package/components/bullet-legend/types.d.ts +5 -0
- package/components/bullet-legend/types.js +7 -0
- package/components/bullet-legend/types.js.map +1 -1
- package/components/chord-diagram/config.d.ts +6 -0
- package/components/chord-diagram/config.js +2 -0
- package/components/chord-diagram/config.js.map +1 -1
- package/components/chord-diagram/index.d.ts +1 -0
- package/components/chord-diagram/index.js +22 -12
- package/components/chord-diagram/index.js.map +1 -1
- package/components/chord-diagram/modules/link.js +6 -5
- package/components/chord-diagram/modules/link.js.map +1 -1
- package/components/chord-diagram/style.d.ts +2 -2
- package/components/chord-diagram/style.js +21 -18
- package/components/chord-diagram/style.js.map +1 -1
- package/components/chord-diagram/types.d.ts +2 -2
- package/components/chord-diagram/types.js.map +1 -1
- package/components/nested-donut/index.js +11 -9
- package/components/nested-donut/index.js.map +1 -1
- package/components/nested-donut/modules/arc.js +2 -1
- package/components/nested-donut/modules/arc.js.map +1 -1
- package/components/nested-donut/modules/label.js +9 -6
- package/components/nested-donut/modules/label.js.map +1 -1
- package/components/nested-donut/types.d.ts +1 -0
- package/components/nested-donut/types.js.map +1 -1
- package/components/scatter/config.d.ts +3 -0
- package/components/scatter/config.js +1 -0
- package/components/scatter/config.js.map +1 -1
- package/components/scatter/index.d.ts +1 -1
- package/components/scatter/index.js +9 -4
- package/components/scatter/index.js.map +1 -1
- package/containers/single-container/index.d.ts +3 -2
- package/containers/single-container/index.js +6 -2
- package/containers/single-container/index.js.map +1 -1
- package/containers/xy-container/config.d.ts +7 -5
- package/containers/xy-container/config.js +1 -1
- package/containers/xy-container/config.js.map +1 -1
- package/containers/xy-container/index.d.ts +8 -7
- package/containers/xy-container/index.js +20 -13
- package/containers/xy-container/index.js.map +1 -1
- package/core/container/index.d.ts +5 -4
- package/core/container/index.js +7 -1
- package/core/container/index.js.map +1 -1
- package/index.js +2 -1
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/types/text.d.ts +3 -3
- package/types/text.js.map +1 -1
- package/types.js +1 -1
- package/utils/color.d.ts +7 -3
- package/utils/color.js +18 -2
- package/utils/color.js.map +1 -1
- package/utils/text.d.ts +1 -0
- package/utils/text.js +22 -10
- package/utils/text.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"arc.js","sources":["../../../../src/components/nested-donut/modules/arc.ts"],"sourcesContent":["import { Selection } from 'd3-selection'\nimport { Transition } from 'd3-transition'\nimport { interpolate } from 'd3-interpolate'\nimport { Arc } from 'd3-shape'\n\n// Utils\nimport { getColor } from 'utils/color'\nimport { smartTransition } from 'utils/d3'\n\n// Local Types\nimport { NestedDonutSegment } from '../types'\n\n// Config\nimport { NestedDonutConfig } from '../config'\n\ntype AnimState = { x0: number; x1: number; y0: number; y1: number }\nexport interface ArcNode extends SVGElement {\n _animState?: AnimState;\n}\n\nexport function createArc<Datum> (\n selection: Selection<SVGPathElement, NestedDonutSegment<Datum>, SVGGElement, unknown>,\n config: NestedDonutConfig<Datum>\n): void {\n selection\n .style('fill', d => getColor(d, config.segmentColor) ?? d._state?.fill)\n .style('opacity', 0)\n .each((d, i, els) => {\n const arcNode: ArcNode = els[i]\n const angleCenter = (d.x0 + d.x1) / 2\n const angleHalfWidth = (d.x1 - d.x0) / 2\n arcNode._animState = {\n x0: angleCenter - angleHalfWidth,\n x1: angleCenter + angleHalfWidth,\n y0: d.y0,\n y1: d.y1,\n }\n })\n}\n\nexport function updateArc<Datum> (\n selection: Selection<SVGPathElement, NestedDonutSegment<Datum>, SVGGElement, unknown>,\n config: NestedDonutConfig<Datum>,\n arcGen: Arc<any, AnimState>,\n duration: number\n): void {\n selection\n .style('transition', `fill ${duration}ms`) // Animate color with CSS because we're using CSS-variables\n .style('fill', d =>
|
|
1
|
+
{"version":3,"file":"arc.js","sources":["../../../../src/components/nested-donut/modules/arc.ts"],"sourcesContent":["import { Selection } from 'd3-selection'\nimport { Transition } from 'd3-transition'\nimport { interpolate } from 'd3-interpolate'\nimport { Arc } from 'd3-shape'\n\n// Utils\nimport { getColor } from 'utils/color'\nimport { smartTransition } from 'utils/d3'\n\n// Local Types\nimport { NestedDonutSegment } from '../types'\n\n// Config\nimport { NestedDonutConfig } from '../config'\n\ntype AnimState = { x0: number; x1: number; y0: number; y1: number }\nexport interface ArcNode extends SVGElement {\n _animState?: AnimState;\n}\n\nexport function createArc<Datum> (\n selection: Selection<SVGPathElement, NestedDonutSegment<Datum>, SVGGElement, unknown>,\n config: NestedDonutConfig<Datum>\n): void {\n selection\n .style('fill', d => getColor(d, config.segmentColor) ?? d._state?.fill)\n .style('opacity', 0)\n .each((d, i, els) => {\n const arcNode: ArcNode = els[i]\n const angleCenter = (d.x0 + d.x1) / 2\n const angleHalfWidth = (d.x1 - d.x0) / 2\n arcNode._animState = {\n x0: angleCenter - angleHalfWidth,\n x1: angleCenter + angleHalfWidth,\n y0: d.y0,\n y1: d.y1,\n }\n })\n}\n\nexport function updateArc<Datum> (\n selection: Selection<SVGPathElement, NestedDonutSegment<Datum>, SVGGElement, unknown>,\n config: NestedDonutConfig<Datum>,\n arcGen: Arc<any, AnimState>,\n duration: number\n): void {\n selection\n .style('transition', `fill ${duration}ms`) // Animate color with CSS because we're using CSS-variables\n .style('fill', d => d._state.fill)\n .style('fill-opacity', d => d._state.fillOpacity)\n\n if (duration) {\n const transition = smartTransition(selection, duration)\n .style('opacity', 1) as Transition<SVGPathElement, NestedDonutSegment<Datum>, SVGGElement, ArcNode>\n\n transition.attrTween('d', (d, i, els) => {\n const arcNode: ArcNode = els[i]\n const nextAnimState = { x0: d.x0, x1: d.x1, y0: d.y0, y1: d.y1 }\n const datum = interpolate(arcNode._animState, nextAnimState)\n return (t: number): string => {\n arcNode._animState = datum(t)\n return arcGen(arcNode._animState)\n }\n })\n } else {\n selection.attr('d', arcGen)\n .style('opacity', 1)\n }\n}\n\nexport function removeArc<Datum> (\n selection: Selection<SVGPathElement, NestedDonutSegment<Datum>, SVGGElement, unknown>,\n duration: number\n): void {\n smartTransition(selection, duration)\n .style('opacity', 0)\n .remove()\n}\n"],"names":[],"mappings":";;;;AAoBgB,SAAA,SAAS,CACvB,SAAqF,EACrF,MAAgC,EAAA;IAEhC,SAAS;SACN,KAAK,CAAC,MAAM,EAAE,CAAC,IAAG,EAAA,IAAA,EAAA,EAAA,EAAA,CAAA,CAAC,OAAA,CAAA,EAAA,GAAA,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,YAAY,CAAC,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA,GAAI,CAAA,EAAA,GAAA,CAAC,CAAC,MAAM,MAAE,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,IAAI,CAAA,EAAA,CAAC;AACtE,SAAA,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;SACnB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,KAAI;AAClB,QAAA,MAAM,OAAO,GAAY,GAAG,CAAC,CAAC,CAAC,CAAA;AAC/B,QAAA,MAAM,WAAW,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;AACrC,QAAA,MAAM,cAAc,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;QACxC,OAAO,CAAC,UAAU,GAAG;YACnB,EAAE,EAAE,WAAW,GAAG,cAAc;YAChC,EAAE,EAAE,WAAW,GAAG,cAAc;YAChC,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,EAAE,EAAE,CAAC,CAAC,EAAE;SACT,CAAA;AACH,KAAC,CAAC,CAAA;AACN,CAAC;AAEK,SAAU,SAAS,CACvB,SAAqF,EACrF,MAAgC,EAChC,MAA2B,EAC3B,QAAgB,EAAA;IAEhB,SAAS;SACN,KAAK,CAAC,YAAY,EAAE,CAAA,KAAA,EAAQ,QAAQ,CAAI,EAAA,CAAA,CAAC;AACzC,SAAA,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;AACjC,SAAA,KAAK,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;AAEnD,IAAA,IAAI,QAAQ,EAAE;AACZ,QAAA,MAAM,UAAU,GAAG,eAAe,CAAC,SAAS,EAAE,QAAQ,CAAC;AACpD,aAAA,KAAK,CAAC,SAAS,EAAE,CAAC,CAAgF,CAAA;AAErG,QAAA,UAAU,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,KAAI;AACtC,YAAA,MAAM,OAAO,GAAY,GAAG,CAAC,CAAC,CAAC,CAAA;YAC/B,MAAM,aAAa,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAA;YAChE,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,UAAU,EAAE,aAAa,CAAC,CAAA;YAC5D,OAAO,CAAC,CAAS,KAAY;AAC3B,gBAAA,OAAO,CAAC,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;AAC7B,gBAAA,OAAO,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;AACnC,aAAC,CAAA;AACH,SAAC,CAAC,CAAA;AACH,KAAA;AAAM,SAAA;AACL,QAAA,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC;AACxB,aAAA,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAA;AACvB,KAAA;AACH,CAAC;AAEe,SAAA,SAAS,CACvB,SAAqF,EACrF,QAAgB,EAAA;AAEhB,IAAA,eAAe,CAAC,SAAS,EAAE,QAAQ,CAAC;AACjC,SAAA,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;AACnB,SAAA,MAAM,EAAE,CAAA;AACb;;;;"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { select } from 'd3-selection';
|
|
2
2
|
import { color } from 'd3-color';
|
|
3
|
-
import {
|
|
3
|
+
import { getHexValue, rgbaToRgb, rgbToBrightness, getColor } from '../../../utils/color.js';
|
|
4
4
|
import { smartTransition } from '../../../utils/d3.js';
|
|
5
5
|
import { getString } from '../../../utils/data.js';
|
|
6
6
|
import { getCSSVariableValueInPixels } from '../../../utils/misc.js';
|
|
@@ -9,11 +9,14 @@ import { wrapSVGText } from '../../../utils/text.js';
|
|
|
9
9
|
import { NestedDonutSegmentLabelAlignment } from '../types.js';
|
|
10
10
|
import { variables } from '../style.js';
|
|
11
11
|
|
|
12
|
-
function getLabelFillColor(d,
|
|
12
|
+
function getLabelFillColor(d, element) {
|
|
13
13
|
var _a;
|
|
14
|
-
const c = (_a =
|
|
15
|
-
const
|
|
16
|
-
|
|
14
|
+
const c = (_a = color(d._state.fill)) !== null && _a !== void 0 ? _a : color(getHexValue(d._state.fill, element));
|
|
15
|
+
const rgb = c === null || c === void 0 ? void 0 : c.rgb();
|
|
16
|
+
// If shading, we adjust segment color before calculating brightness ratio
|
|
17
|
+
const colorParsed = rgb && d._state.fillOpacity
|
|
18
|
+
? rgbaToRgb(`rgba(${rgb.r},${rgb.g},${rgb.b},${d._state.fillOpacity})`, getHexValue(cssvar(variables.nestedDonutBackgroundColor), element)) : rgb;
|
|
19
|
+
const brightness = colorParsed ? rgbToBrightness(colorParsed) : 0;
|
|
17
20
|
return cssvar(brightness > 0.65 ? variables.nestedDonutSegmentLabelTextColorLight : variables.nestedDonutSegmentLabelTextColorDark);
|
|
18
21
|
}
|
|
19
22
|
function getLabelTransform(d, arcGen) {
|
|
@@ -51,7 +54,7 @@ function updateLabel(selection, config, arcGen, duration) {
|
|
|
51
54
|
selection
|
|
52
55
|
.text(d => { var _a; return (_a = getString(d, config.segmentLabel)) !== null && _a !== void 0 ? _a : d.data.key; })
|
|
53
56
|
.style('transition', `fill ${duration}ms`)
|
|
54
|
-
.style('fill', d => { var _a; return (_a = getColor(d, config.segmentLabelColor)) !== null && _a !== void 0 ? _a : getLabelFillColor(d,
|
|
57
|
+
.style('fill', (d, i, els) => { var _a; return (_a = getColor(d, config.segmentLabelColor)) !== null && _a !== void 0 ? _a : getLabelFillColor(d, els[i]); })
|
|
55
58
|
.each((d, i, els) => {
|
|
56
59
|
const bounds = getLabelBounds(d);
|
|
57
60
|
const label = select(els[i]).call(wrapSVGText, bounds.width);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"label.js","sources":["../../../../src/components/nested-donut/modules/label.ts"],"sourcesContent":["import { Selection, select } from 'd3-selection'\nimport { color } from 'd3-color'\nimport { Arc } from 'd3-shape'\n\n// Utils\nimport { getColor,
|
|
1
|
+
{"version":3,"file":"label.js","sources":["../../../../src/components/nested-donut/modules/label.ts"],"sourcesContent":["import { Selection, select } from 'd3-selection'\nimport { color } from 'd3-color'\nimport { Arc } from 'd3-shape'\n\n// Utils\nimport { getColor, getHexValue, rgbaToRgb, rgbToBrightness } from 'utils/color'\nimport { smartTransition } from 'utils/d3'\nimport { getString } from 'utils/data'\nimport { getCSSVariableValueInPixels } from 'utils/misc'\nimport { cssvar } from 'utils/style'\nimport { wrapSVGText } from 'utils/text'\n\n// Config\nimport { NestedDonutConfig } from '../config'\n\n// Local Types\nimport { NestedDonutSegment, NestedDonutSegmentLabelAlignment } from '../types'\n\n// Styles\nimport { variables } from '../style'\n\nfunction getLabelFillColor<Datum> (\n d: NestedDonutSegment<Datum>,\n element: SVGElement\n): string {\n const c = color(d._state.fill) ?? color(getHexValue(d._state.fill, element))\n const rgb = c?.rgb()\n\n // If shading, we adjust segment color before calculating brightness ratio\n const colorParsed = rgb && d._state.fillOpacity\n ? rgbaToRgb(\n `rgba(${rgb.r},${rgb.g},${rgb.b},${d._state.fillOpacity})`,\n getHexValue(cssvar(variables.nestedDonutBackgroundColor), element)\n ) : rgb\n\n const brightness = colorParsed ? rgbToBrightness(colorParsed) : 0\n return cssvar(brightness > 0.65 ? variables.nestedDonutSegmentLabelTextColorLight : variables.nestedDonutSegmentLabelTextColorDark)\n}\n\nfunction getLabelTransform<Datum> (\n d: NestedDonutSegment<Datum>,\n arcGen: Arc<unknown, NestedDonutSegment<Datum>>\n): string {\n const translate = `translate(${arcGen.centroid(d)})`\n const degree = 180 / Math.PI * (arcGen.startAngle()(d) + arcGen.endAngle()(d)) / 2 - 90\n switch (d._layer.labelAlignment) {\n case NestedDonutSegmentLabelAlignment.Along:\n return `${translate} rotate(${degree + 90})`\n case NestedDonutSegmentLabelAlignment.Perpendicular:\n return `${translate} rotate(${degree > 90 ? degree - 180 : degree})`\n default:\n return `${translate}`\n }\n}\n\nfunction getLabelBounds<Datum> (\n d: NestedDonutSegment<Datum>\n): { width: number; height: number } {\n const arcWidth = d.y1 - d.y0\n const arcLength = d._layer._innerRadius * (d.x1 - d.x0)\n const bandwidth = Math.max(Math.abs(Math.cos(d.x0 + (d.x1 - d.x0) / 2 - Math.PI / 2) * arcWidth), arcWidth)\n switch (d._layer.labelAlignment) {\n case NestedDonutSegmentLabelAlignment.Perpendicular:\n return { width: arcWidth, height: arcLength }\n case NestedDonutSegmentLabelAlignment.Along:\n return { width: arcLength, height: arcWidth }\n case NestedDonutSegmentLabelAlignment.Straight:\n return { width: bandwidth, height: bandwidth }\n }\n}\n\nexport function createLabel<Datum> (\n selection: Selection<SVGTextElement, NestedDonutSegment<Datum>, SVGGElement, unknown>,\n arcGen: Arc<unknown, NestedDonutSegment<Datum>>\n): void {\n selection\n .attr('transform', d => getLabelTransform(d, arcGen))\n .style('visibility', null)\n .style('opacity', 0)\n}\n\n\nexport function updateLabel<Datum> (\n selection: Selection<SVGTextElement, NestedDonutSegment<Datum>, SVGGElement, unknown>,\n config: NestedDonutConfig<Datum>,\n arcGen: Arc<unknown, NestedDonutSegment<Datum>>,\n duration: number\n): void {\n selection\n .text(d => getString(d, config.segmentLabel) ?? d.data.key)\n .style('transition', `fill ${duration}ms`)\n .style('fill', (d, i, els) => getColor(d, config.segmentLabelColor) ?? getLabelFillColor(d, els[i]))\n .each((d, i, els) => {\n const bounds = getLabelBounds(d)\n const label = select(els[i]).call(wrapSVGText, bounds.width)\n\n const { width, height } = label.node().getBBox()\n\n if (config.hideOverflowingSegmentLabels && (width > bounds.width || height > bounds.height) && 'hidden') {\n label.attr('visibility', 'hidden')\n } else {\n const fontSize = getCSSVariableValueInPixels(cssvar(variables.nestedDonutSegmentLabelFontSize), els[i])\n const len = label.selectChildren().size() - 1\n label.attr('dy', -fontSize / 2 * len)\n }\n })\n\n smartTransition(selection, duration)\n .attr('transform', d => getLabelTransform(d, arcGen))\n .style('opacity', 1)\n}\n\nexport function removeLabel<Datum> (\n selection: Selection<SVGTextElement, NestedDonutSegment<Datum>, SVGGElement, unknown>,\n duration: number\n): void {\n smartTransition(selection, duration)\n .style('opacity', 0)\n .remove()\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sources":["../../../src/components/nested-donut/types.ts"],"sourcesContent":["import { HierarchyRectangularNode } from 'd3-hierarchy'\n\nexport type NestedDonutSegmentDatum<Datum> = {\n key: string;\n root: string;\n values: Datum[];\n}\n\nexport type NestedDonutSegment<Datum> = HierarchyRectangularNode<NestedDonutSegmentDatum<Datum>> & {\n _id: string;\n _layer: NestedDonutLayer;\n _index?: number;\n _state?: {\n fill?: string;\n };\n}\n\nexport enum NestedDonutDirection {\n Inwards = 'inwards',\n Outwards = 'outwards',\n}\n\nexport enum NestedDonutSegmentLabelAlignment {\n Along = 'along',\n Perpendicular = 'perpendicular',\n Straight = 'straight',\n}\n\nexport type NestedDonutLayerSettings = {\n backgroundColor?: string;\n labelAlignment?: NestedDonutSegmentLabelAlignment;\n width?: number | string;\n}\n\nexport type NestedDonutLayer = NestedDonutLayerSettings & {\n _id: number;\n _innerRadius: number;\n _outerRadius: number;\n}\n\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sources":["../../../src/components/nested-donut/types.ts"],"sourcesContent":["import { HierarchyRectangularNode } from 'd3-hierarchy'\n\nexport type NestedDonutSegmentDatum<Datum> = {\n key: string;\n root: string;\n values: Datum[];\n}\n\nexport type NestedDonutSegment<Datum> = HierarchyRectangularNode<NestedDonutSegmentDatum<Datum>> & {\n _id: string;\n _layer: NestedDonutLayer;\n _index?: number;\n _state?: {\n fill?: string;\n fillOpacity?: number | null;\n };\n}\n\nexport enum NestedDonutDirection {\n Inwards = 'inwards',\n Outwards = 'outwards',\n}\n\nexport enum NestedDonutSegmentLabelAlignment {\n Along = 'along',\n Perpendicular = 'perpendicular',\n Straight = 'straight',\n}\n\nexport type NestedDonutLayerSettings = {\n backgroundColor?: string;\n labelAlignment?: NestedDonutSegmentLabelAlignment;\n width?: number | string;\n}\n\nexport type NestedDonutLayer = NestedDonutLayerSettings & {\n _id: number;\n _innerRadius: number;\n _outerRadius: number;\n}\n\n"],"names":[],"mappings":"IAkBY,qBAGX;AAHD,CAAA,UAAY,oBAAoB,EAAA;AAC9B,IAAA,oBAAA,CAAA,SAAA,CAAA,GAAA,SAAmB,CAAA;AACnB,IAAA,oBAAA,CAAA,UAAA,CAAA,GAAA,UAAqB,CAAA;AACvB,CAAC,EAHW,oBAAoB,KAApB,oBAAoB,GAG/B,EAAA,CAAA,CAAA,CAAA;IAEW,iCAIX;AAJD,CAAA,UAAY,gCAAgC,EAAA;AAC1C,IAAA,gCAAA,CAAA,OAAA,CAAA,GAAA,OAAe,CAAA;AACf,IAAA,gCAAA,CAAA,eAAA,CAAA,GAAA,eAA+B,CAAA;AAC/B,IAAA,gCAAA,CAAA,UAAA,CAAA,GAAA,UAAqB,CAAA;AACvB,CAAC,EAJW,gCAAgC,KAAhC,gCAAgC,GAI3C,EAAA,CAAA,CAAA;;;;"}
|
|
@@ -24,6 +24,8 @@ export interface ScatterConfigInterface<Datum> extends XYComponentConfigInterfac
|
|
|
24
24
|
label?: StringAccessor<Datum>;
|
|
25
25
|
/** Label color. Default: `undefined` */
|
|
26
26
|
labelColor?: ColorAccessor<Datum>;
|
|
27
|
+
/** Hide overlapping labels. Default: `true` */
|
|
28
|
+
labelHideOverlapping?: boolean;
|
|
27
29
|
/** Optional point cursor. Default: `null` */
|
|
28
30
|
cursor?: StringAccessor<Datum>;
|
|
29
31
|
/** Point color brightness ratio for switching between dark and light text label color. Default: `0.65` */
|
|
@@ -43,6 +45,7 @@ export declare class ScatterConfig<Datum> extends XYComponentConfig<Datum> imple
|
|
|
43
45
|
label: any;
|
|
44
46
|
labelColor: any;
|
|
45
47
|
labelPosition: Position;
|
|
48
|
+
labelHideOverlapping: boolean;
|
|
46
49
|
cursor: any;
|
|
47
50
|
labelTextBrightnessRatio: number;
|
|
48
51
|
strokeColor: ScatterConfigInterface<Datum>['strokeColor'];
|
|
@@ -14,6 +14,7 @@ class ScatterConfig extends XYComponentConfig {
|
|
|
14
14
|
this.label = undefined;
|
|
15
15
|
this.labelColor = undefined;
|
|
16
16
|
this.labelPosition = Position.Bottom;
|
|
17
|
+
this.labelHideOverlapping = true;
|
|
17
18
|
this.cursor = null;
|
|
18
19
|
this.labelTextBrightnessRatio = 0.65;
|
|
19
20
|
this.strokeColor = undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sources":["../../../src/components/scatter/config.ts"],"sourcesContent":["import { ScalePower } from 'd3-scale'\n// Core\nimport { XYComponentConfigInterface, XYComponentConfig } from 'core/xy-component/config'\n\n// Types\nimport { Scale, ContinuousScale } from 'types/scale'\nimport { SymbolType } from 'types/symbol'\nimport { ColorAccessor, GenericAccessor, NumericAccessor, StringAccessor } from 'types/accessor'\nimport { Position } from 'types/position'\n\nexport interface ScatterConfigInterface<Datum> extends XYComponentConfigInterface<Datum> {\n /**\n * Size of the scatter plot marker (e.g. diameter if `SymbolType.Circle` is used for `shape`) in pixels.\n * Can be a constant value or an accessor function. But if `sizeRange` is set, then the values will be treated\n * as an input to `sizeScale`, and the resulting size will be different.\n * Default: `10`\n */\n size?: NumericAccessor<Datum>;\n /** Size scale to be used if the `sizeRange` was set. Default: `Scale.scaleSqrt()` */\n sizeScale?: ContinuousScale;\n /** Size range in the format of `[number, number]` to rescale the input values. Default: `undefined` */\n sizeRange?: [number, number];\n /** Shape of the scatter point. Accessor function or constant value: `SymbolType.Circle`, `SymbolType.Cross`, `SymbolType.Diamond`, `SymbolType.Square`,\n * `SymbolType.Star`, `SymbolType.Triangle` or `SymbolType.Wye`.\n * Default: `SymbolType.Circle` */\n shape?: ((d: Datum, i?: number, ...any) => (SymbolType | string)) | SymbolType | string;\n /** Label accessor function or string. Default: `undefined` */\n label?: StringAccessor<Datum>;\n /** Label color. Default: `undefined` */\n labelColor?: ColorAccessor<Datum>;\n /** Optional point cursor. Default: `null` */\n cursor?: StringAccessor<Datum>;\n /** Point color brightness ratio for switching between dark and light text label color. Default: `0.65` */\n labelTextBrightnessRatio?: number;\n /** Label position. Default: `Position.Bottom` */\n labelPosition?: GenericAccessor<Position | string, Datum>;\n /** Point stroke color. Default: `undefined` */\n strokeColor?: ColorAccessor<Datum>;\n /** Point stroke width. Default: `undefined` */\n strokeWidth?: NumericAccessor<Datum>;\n}\n\nexport class ScatterConfig<Datum> extends XYComponentConfig<Datum> implements ScatterConfigInterface<Datum> {\n size = 10\n sizeScale: ScalePower<number, number> = Scale.scaleSqrt()\n sizeRange = undefined\n shape = SymbolType.Circle\n label = undefined\n labelColor = undefined\n labelPosition = Position.Bottom\n cursor = null\n labelTextBrightnessRatio = 0.65\n strokeColor: ScatterConfigInterface<Datum>['strokeColor'] = undefined\n strokeWidth: ScatterConfigInterface<Datum>['strokeWidth'] = undefined\n}\n"],"names":[],"mappings":";;;;;AACA;
|
|
1
|
+
{"version":3,"file":"config.js","sources":["../../../src/components/scatter/config.ts"],"sourcesContent":["import { ScalePower } from 'd3-scale'\n// Core\nimport { XYComponentConfigInterface, XYComponentConfig } from 'core/xy-component/config'\n\n// Types\nimport { Scale, ContinuousScale } from 'types/scale'\nimport { SymbolType } from 'types/symbol'\nimport { ColorAccessor, GenericAccessor, NumericAccessor, StringAccessor } from 'types/accessor'\nimport { Position } from 'types/position'\n\nexport interface ScatterConfigInterface<Datum> extends XYComponentConfigInterface<Datum> {\n /**\n * Size of the scatter plot marker (e.g. diameter if `SymbolType.Circle` is used for `shape`) in pixels.\n * Can be a constant value or an accessor function. But if `sizeRange` is set, then the values will be treated\n * as an input to `sizeScale`, and the resulting size will be different.\n * Default: `10`\n */\n size?: NumericAccessor<Datum>;\n /** Size scale to be used if the `sizeRange` was set. Default: `Scale.scaleSqrt()` */\n sizeScale?: ContinuousScale;\n /** Size range in the format of `[number, number]` to rescale the input values. Default: `undefined` */\n sizeRange?: [number, number];\n /** Shape of the scatter point. Accessor function or constant value: `SymbolType.Circle`, `SymbolType.Cross`, `SymbolType.Diamond`, `SymbolType.Square`,\n * `SymbolType.Star`, `SymbolType.Triangle` or `SymbolType.Wye`.\n * Default: `SymbolType.Circle` */\n shape?: ((d: Datum, i?: number, ...any) => (SymbolType | string)) | SymbolType | string;\n /** Label accessor function or string. Default: `undefined` */\n label?: StringAccessor<Datum>;\n /** Label color. Default: `undefined` */\n labelColor?: ColorAccessor<Datum>;\n /** Hide overlapping labels. Default: `true` */\n labelHideOverlapping?: boolean;\n /** Optional point cursor. Default: `null` */\n cursor?: StringAccessor<Datum>;\n /** Point color brightness ratio for switching between dark and light text label color. Default: `0.65` */\n labelTextBrightnessRatio?: number;\n /** Label position. Default: `Position.Bottom` */\n labelPosition?: GenericAccessor<Position | string, Datum>;\n /** Point stroke color. Default: `undefined` */\n strokeColor?: ColorAccessor<Datum>;\n /** Point stroke width. Default: `undefined` */\n strokeWidth?: NumericAccessor<Datum>;\n}\n\nexport class ScatterConfig<Datum> extends XYComponentConfig<Datum> implements ScatterConfigInterface<Datum> {\n size = 10\n sizeScale: ScalePower<number, number> = Scale.scaleSqrt()\n sizeRange = undefined\n shape = SymbolType.Circle\n label = undefined\n labelColor = undefined\n labelPosition = Position.Bottom\n labelHideOverlapping = true\n cursor = null\n labelTextBrightnessRatio = 0.65\n strokeColor: ScatterConfigInterface<Datum>['strokeColor'] = undefined\n strokeWidth: ScatterConfigInterface<Datum>['strokeWidth'] = undefined\n}\n"],"names":[],"mappings":";;;;;AACA;AA2CM,MAAO,aAAqB,SAAQ,iBAAwB,CAAA;AAAlE,IAAA,WAAA,GAAA;;QACE,IAAI,CAAA,IAAA,GAAG,EAAE,CAAA;AACT,QAAA,IAAA,CAAA,SAAS,GAA+B,KAAK,CAAC,SAAS,EAAE,CAAA;QACzD,IAAS,CAAA,SAAA,GAAG,SAAS,CAAA;AACrB,QAAA,IAAA,CAAA,KAAK,GAAG,UAAU,CAAC,MAAM,CAAA;QACzB,IAAK,CAAA,KAAA,GAAG,SAAS,CAAA;QACjB,IAAU,CAAA,UAAA,GAAG,SAAS,CAAA;AACtB,QAAA,IAAA,CAAA,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAA;QAC/B,IAAoB,CAAA,oBAAA,GAAG,IAAI,CAAA;QAC3B,IAAM,CAAA,MAAA,GAAG,IAAI,CAAA;QACb,IAAwB,CAAA,wBAAA,GAAG,IAAI,CAAA;QAC/B,IAAW,CAAA,WAAA,GAAiD,SAAS,CAAA;QACrE,IAAW,CAAA,WAAA,GAAiD,SAAS,CAAA;KACtE;AAAA;;;;"}
|
|
@@ -20,7 +20,7 @@ export declare class Scatter<Datum> extends XYComponentCore<Datum, ScatterConfig
|
|
|
20
20
|
setData(data: Datum[]): void;
|
|
21
21
|
get bleed(): Spacing;
|
|
22
22
|
_render(customDuration?: number): void;
|
|
23
|
-
private
|
|
23
|
+
private _resolveLabelOverlap;
|
|
24
24
|
private _updateSizeScale;
|
|
25
25
|
private _getOnScreenData;
|
|
26
26
|
private _onPointMouseOver;
|
|
@@ -92,9 +92,14 @@ class Scatter extends XYComponentCore {
|
|
|
92
92
|
updatePoints(this._points, config, this.xScale, this.yScale, duration);
|
|
93
93
|
removePoints(points.exit(), this.xScale, this.yScale, duration);
|
|
94
94
|
// Take care of overlapping labels
|
|
95
|
-
this.
|
|
95
|
+
this._resolveLabelOverlap();
|
|
96
96
|
}
|
|
97
|
-
|
|
97
|
+
_resolveLabelOverlap() {
|
|
98
|
+
if (!this.config.labelHideOverlapping) {
|
|
99
|
+
const label = this._points.selectAll('text');
|
|
100
|
+
label.attr('opacity', null);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
98
103
|
cancelAnimationFrame(this._collideLabelsAnimFrameId);
|
|
99
104
|
this._collideLabelsAnimFrameId = requestAnimationFrame(() => {
|
|
100
105
|
collideLabels(this._points, this.config, this.xScale, this.yScale);
|
|
@@ -154,13 +159,13 @@ class Scatter extends XYComponentCore {
|
|
|
154
159
|
if (pointNode)
|
|
155
160
|
pointNode._forceShowLabel = true;
|
|
156
161
|
point.raise();
|
|
157
|
-
this.
|
|
162
|
+
this._resolveLabelOverlap();
|
|
158
163
|
}
|
|
159
164
|
_onPointMouseOut(d, event) {
|
|
160
165
|
const pointNode = select(event.target).node();
|
|
161
166
|
if (pointNode)
|
|
162
167
|
delete pointNode._forceShowLabel;
|
|
163
|
-
this.
|
|
168
|
+
this._resolveLabelOverlap();
|
|
164
169
|
}
|
|
165
170
|
}
|
|
166
171
|
Scatter.selectors = style;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/components/scatter/index.ts"],"sourcesContent":["import { Selection, select } from 'd3-selection'\nimport { max, min } from 'd3-array'\n\n// Core\nimport { XYComponentCore } from 'core/xy-component'\n\n// Utils\nimport { isNumber, getExtent, getNumber, getString, isArray, flatten, getValue } from 'utils/data'\nimport { getColor } from 'utils/color'\nimport { smartTransition } from 'utils/d3'\nimport { getCSSVariableValueInPixels } from 'utils/misc'\n\n// Types\nimport { Spacing } from 'types/spacing'\nimport { SymbolType } from 'types/symbol'\nimport { NumericAccessor } from 'types/accessor'\n\n// Local Types\nimport { ScatterPointGroupNode, ScatterPoint } from './types'\n\n// Config\nimport { ScatterConfig, ScatterConfigInterface } from './config'\n\n// Modules\nimport { createPoints, updatePoints, removePoints } from './modules/point'\nimport { collideLabels, getEstimatedLabelBBox } from './modules/utils'\n\n// Styles\nimport * as s from './style'\n\nexport class Scatter<Datum> extends XYComponentCore<Datum, ScatterConfig<Datum>, ScatterConfigInterface<Datum>> {\n static selectors = s\n config: ScatterConfig<Datum> = new ScatterConfig()\n events = {\n [Scatter.selectors.point]: {\n mouseenter: this._onPointMouseOver.bind(this),\n mouseleave: this._onPointMouseOut.bind(this),\n },\n }\n\n private _pointData: ScatterPoint<Datum>[][] = []\n private _points: Selection<SVGGElement, ScatterPoint<Datum>, SVGGElement, ScatterPoint<Datum>[]>\n private _collideLabelsAnimFrameId: ReturnType<typeof requestAnimationFrame>\n\n constructor (config?: ScatterConfigInterface<Datum>) {\n super()\n if (config) this.setConfig(config)\n }\n\n setConfig (config: ScatterConfigInterface<Datum>): void {\n super.setConfig(config)\n this._updateSizeScale()\n }\n\n setData (data: Datum[]): void {\n super.setData(data)\n this._updateSizeScale()\n }\n\n get bleed (): Spacing {\n this._pointData = this._getOnScreenData()\n const pointDataFlat: ScatterPoint<Datum>[] = flatten(this._pointData)\n\n const yRangeStart = min(this.yScale.range())\n const yRangeEnd = max(this.yScale.range())\n const xRangeStart = this.xScale.range()[0]\n const xRangeEnd = this.xScale.range()[1]\n\n const fontSizePx = getCSSVariableValueInPixels('var(--vis-scatter-point-label-text-font-size)', this.element)\n\n const extent = pointDataFlat.reduce((ext, d) => {\n const labelPosition = getValue(d, this.config.labelPosition, d._point.pointIndex)\n const labelBBox = getEstimatedLabelBBox(d, labelPosition, this.xScale, this.yScale, fontSizePx)\n const x = this.xScale(d._point.xValue)\n const y = this.yScale(d._point.yValue)\n const r = d._point.sizePx / 2\n\n ext.minX = Math.min(ext.minX, x - r, labelBBox.x)\n ext.maxX = Math.max(ext.maxX, x + r, labelBBox.x + labelBBox.width)\n ext.minY = Math.min(ext.minY, y - r, labelBBox.y)\n ext.maxY = Math.max(ext.maxY, y + r, labelBBox.y + labelBBox.height)\n return ext\n }, {\n minX: Number.POSITIVE_INFINITY,\n maxX: Number.NEGATIVE_INFINITY,\n minY: Number.POSITIVE_INFINITY,\n maxY: Number.NEGATIVE_INFINITY,\n })\n\n const coeff = 1.2 // Multiplier to take into account subsequent scale range changes and shape irregularities\n const top = extent.minY < yRangeStart ? coeff * (yRangeStart - extent.minY) : 0\n const bottom = extent.maxY > yRangeEnd ? coeff * (extent.maxY - yRangeEnd) : 0\n const left = extent.minX < xRangeStart ? coeff * (xRangeStart - extent.minX) : 0\n const right = extent.maxX > xRangeEnd ? coeff * (extent.maxX - xRangeEnd) : 0\n\n return { top, bottom, left, right }\n }\n\n _render (customDuration?: number): void {\n const { config } = this\n const duration = isNumber(customDuration) ? customDuration : config.duration\n\n // Groups\n const pointGroups = this.g\n .selectAll<SVGGElement, ScatterPoint<Datum>[]>(`.${s.pointGroup}`)\n .data(this._pointData)\n\n const pointGroupsEnter = pointGroups\n .enter()\n .append('g')\n .attr('class', s.pointGroup)\n\n const pointGroupsMerged = pointGroupsEnter.merge(pointGroups)\n smartTransition(pointGroupsMerged, duration)\n .style('opacity', 1)\n\n const pointGroupExit = pointGroups.exit().attr('class', s.pointGroupExit)\n smartTransition(pointGroupExit, duration).style('opacity', 0).remove()\n\n // Points\n const points = pointGroupsMerged\n .selectAll<SVGGElement, ScatterPoint<Datum>>(`.${s.point}`)\n .data(\n d => d,\n d => `${getString(d, config.id, d._point.pointIndex) ?? d._point.pointIndex}`\n )\n\n const pointsEnter = points.enter().append('g')\n .attr('class', s.point)\n createPoints(pointsEnter, this.xScale, this.yScale)\n\n this._points = pointsEnter.merge(points)\n updatePoints(this._points, config, this.xScale, this.yScale, duration)\n\n removePoints(points.exit<ScatterPoint<Datum>>(), this.xScale, this.yScale, duration)\n\n // Take care of overlapping labels\n this._collideLabels()\n }\n\n private _collideLabels (): void {\n cancelAnimationFrame(this._collideLabelsAnimFrameId)\n this._collideLabelsAnimFrameId = requestAnimationFrame(() => {\n collideLabels(this._points, this.config, this.xScale, this.yScale)\n })\n }\n\n private _updateSizeScale (): void {\n const { config, datamodel } = this\n\n config.sizeScale\n .domain(getExtent(datamodel.data, config.size))\n .range(config.sizeRange ?? [0, 0])\n }\n\n private _getOnScreenData (): ScatterPoint<Datum>[][] {\n const { config, datamodel: { data } } = this\n\n const xDomain = this.xScale.domain().map(d => +d) // Convert Date to number\n const yDomain = this.yScale.domain().map(d => +d) // Convert Date to number\n const yAccessors = (isArray(config.y) ? config.y : [config.y]) as NumericAccessor<Datum>[]\n\n const maxSizeValue = max<number>(flatten(yAccessors.map((y, j) => data?.map(d => getNumber(d, config.size, j)))))\n const maxSizePx = config.sizeRange ? config.sizeScale(maxSizeValue) : maxSizeValue\n const maxSizeXDomain = (this.xScale.invert(maxSizePx) as number) - (this.xScale.invert(0) as number)\n const maxSizeYDomain = Math.abs((this.yScale.invert(maxSizePx) as number) - (this.yScale.invert(0) as number))\n\n return yAccessors.map((y, j) => {\n return data?.reduce<ScatterPoint<Datum>[]>((acc, d, i) => {\n const xValue = getNumber(d, config.x, i)\n const yValue = getNumber(d, y, j)\n const pointSize = getNumber(d, config.size, i)\n const pointSizeScaled = config.sizeRange ? config.sizeScale(pointSize) : pointSize\n const pointSizeXDomain = (this.xScale.invert(pointSizeScaled) as number) - (this.xScale.invert(0) as number)\n const pointSizeYDomain = Math.abs((this.yScale.invert(pointSizeScaled) as number) - (this.yScale.invert(0) as number))\n\n if (\n ((xValue - pointSizeXDomain / 2) >= (xDomain[0] - maxSizeXDomain / 2)) &&\n ((xValue + pointSizeXDomain / 2) <= (xDomain[1] + maxSizeXDomain / 2)) &&\n ((yValue - pointSizeYDomain / 2) >= (yDomain[0] - maxSizeYDomain / 2)) &&\n ((yValue + pointSizeYDomain / 2) <= (yDomain[1] + maxSizeYDomain / 2))\n ) {\n acc.push({\n ...d,\n _point: {\n xValue: xValue,\n yValue: yValue,\n sizePx: pointSizeScaled,\n color: getColor(d, config.color, j),\n strokeColor: getColor(d, config.strokeColor, j, true),\n strokeWidthPx: getNumber(d, config.strokeWidth, j),\n shape: getString(d, config.shape, j) as SymbolType,\n label: getString(d, config.label, j),\n labelColor: getValue(d, config.labelColor, j),\n cursor: getString(d, config.cursor, j),\n groupIndex: j,\n pointIndex: i,\n },\n })\n }\n\n return acc\n }, []) ?? []\n })\n }\n\n private _onPointMouseOver (d: ScatterPoint<Datum>, event: MouseEvent): void {\n const point = select(event.target as SVGGElement)\n const pointNode = point.node() as ScatterPointGroupNode | null\n if (pointNode) pointNode._forceShowLabel = true\n\n point.raise()\n this._collideLabels()\n }\n\n private _onPointMouseOut (d: ScatterPoint<Datum>, event: MouseEvent): void {\n const pointNode = select(event.target as SVGGElement).node() as ScatterPointGroupNode | null\n if (pointNode) delete pointNode._forceShowLabel\n\n this._collideLabels()\n }\n}\n"],"names":["s.pointGroup","pointGroupExit","s.pointGroupExit","s.point","s"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/components/scatter/index.ts"],"sourcesContent":["import { Selection, select } from 'd3-selection'\nimport { max, min } from 'd3-array'\n\n// Core\nimport { XYComponentCore } from 'core/xy-component'\n\n// Utils\nimport { isNumber, getExtent, getNumber, getString, isArray, flatten, getValue } from 'utils/data'\nimport { getColor } from 'utils/color'\nimport { smartTransition } from 'utils/d3'\nimport { getCSSVariableValueInPixels } from 'utils/misc'\n\n// Types\nimport { Spacing } from 'types/spacing'\nimport { SymbolType } from 'types/symbol'\nimport { NumericAccessor } from 'types/accessor'\n\n// Local Types\nimport { ScatterPointGroupNode, ScatterPoint } from './types'\n\n// Config\nimport { ScatterConfig, ScatterConfigInterface } from './config'\n\n// Modules\nimport { createPoints, updatePoints, removePoints } from './modules/point'\nimport { collideLabels, getEstimatedLabelBBox } from './modules/utils'\n\n// Styles\nimport * as s from './style'\n\nexport class Scatter<Datum> extends XYComponentCore<Datum, ScatterConfig<Datum>, ScatterConfigInterface<Datum>> {\n static selectors = s\n config: ScatterConfig<Datum> = new ScatterConfig()\n events = {\n [Scatter.selectors.point]: {\n mouseenter: this._onPointMouseOver.bind(this),\n mouseleave: this._onPointMouseOut.bind(this),\n },\n }\n\n private _pointData: ScatterPoint<Datum>[][] = []\n private _points: Selection<SVGGElement, ScatterPoint<Datum>, SVGGElement, ScatterPoint<Datum>[]>\n private _collideLabelsAnimFrameId: ReturnType<typeof requestAnimationFrame>\n\n constructor (config?: ScatterConfigInterface<Datum>) {\n super()\n if (config) this.setConfig(config)\n }\n\n setConfig (config: ScatterConfigInterface<Datum>): void {\n super.setConfig(config)\n this._updateSizeScale()\n }\n\n setData (data: Datum[]): void {\n super.setData(data)\n this._updateSizeScale()\n }\n\n get bleed (): Spacing {\n this._pointData = this._getOnScreenData()\n const pointDataFlat: ScatterPoint<Datum>[] = flatten(this._pointData)\n\n const yRangeStart = min(this.yScale.range())\n const yRangeEnd = max(this.yScale.range())\n const xRangeStart = this.xScale.range()[0]\n const xRangeEnd = this.xScale.range()[1]\n\n const fontSizePx = getCSSVariableValueInPixels('var(--vis-scatter-point-label-text-font-size)', this.element)\n\n const extent = pointDataFlat.reduce((ext, d) => {\n const labelPosition = getValue(d, this.config.labelPosition, d._point.pointIndex)\n const labelBBox = getEstimatedLabelBBox(d, labelPosition, this.xScale, this.yScale, fontSizePx)\n const x = this.xScale(d._point.xValue)\n const y = this.yScale(d._point.yValue)\n const r = d._point.sizePx / 2\n\n ext.minX = Math.min(ext.minX, x - r, labelBBox.x)\n ext.maxX = Math.max(ext.maxX, x + r, labelBBox.x + labelBBox.width)\n ext.minY = Math.min(ext.minY, y - r, labelBBox.y)\n ext.maxY = Math.max(ext.maxY, y + r, labelBBox.y + labelBBox.height)\n return ext\n }, {\n minX: Number.POSITIVE_INFINITY,\n maxX: Number.NEGATIVE_INFINITY,\n minY: Number.POSITIVE_INFINITY,\n maxY: Number.NEGATIVE_INFINITY,\n })\n\n const coeff = 1.2 // Multiplier to take into account subsequent scale range changes and shape irregularities\n const top = extent.minY < yRangeStart ? coeff * (yRangeStart - extent.minY) : 0\n const bottom = extent.maxY > yRangeEnd ? coeff * (extent.maxY - yRangeEnd) : 0\n const left = extent.minX < xRangeStart ? coeff * (xRangeStart - extent.minX) : 0\n const right = extent.maxX > xRangeEnd ? coeff * (extent.maxX - xRangeEnd) : 0\n\n return { top, bottom, left, right }\n }\n\n _render (customDuration?: number): void {\n const { config } = this\n const duration = isNumber(customDuration) ? customDuration : config.duration\n\n // Groups\n const pointGroups = this.g\n .selectAll<SVGGElement, ScatterPoint<Datum>[]>(`.${s.pointGroup}`)\n .data(this._pointData)\n\n const pointGroupsEnter = pointGroups\n .enter()\n .append('g')\n .attr('class', s.pointGroup)\n\n const pointGroupsMerged = pointGroupsEnter.merge(pointGroups)\n smartTransition(pointGroupsMerged, duration)\n .style('opacity', 1)\n\n const pointGroupExit = pointGroups.exit().attr('class', s.pointGroupExit)\n smartTransition(pointGroupExit, duration).style('opacity', 0).remove()\n\n // Points\n const points = pointGroupsMerged\n .selectAll<SVGGElement, ScatterPoint<Datum>>(`.${s.point}`)\n .data(\n d => d,\n d => `${getString(d, config.id, d._point.pointIndex) ?? d._point.pointIndex}`\n )\n\n const pointsEnter = points.enter().append('g')\n .attr('class', s.point)\n createPoints(pointsEnter, this.xScale, this.yScale)\n\n this._points = pointsEnter.merge(points)\n updatePoints(this._points, config, this.xScale, this.yScale, duration)\n\n removePoints(points.exit<ScatterPoint<Datum>>(), this.xScale, this.yScale, duration)\n\n // Take care of overlapping labels\n this._resolveLabelOverlap()\n }\n\n private _resolveLabelOverlap (): void {\n if (!this.config.labelHideOverlapping) {\n const label = this._points.selectAll<SVGTextElement, ScatterPoint<Datum>>('text')\n label.attr('opacity', null)\n return\n }\n\n cancelAnimationFrame(this._collideLabelsAnimFrameId)\n this._collideLabelsAnimFrameId = requestAnimationFrame(() => {\n collideLabels(this._points, this.config, this.xScale, this.yScale)\n })\n }\n\n private _updateSizeScale (): void {\n const { config, datamodel } = this\n\n config.sizeScale\n .domain(getExtent(datamodel.data, config.size))\n .range(config.sizeRange ?? [0, 0])\n }\n\n private _getOnScreenData (): ScatterPoint<Datum>[][] {\n const { config, datamodel: { data } } = this\n\n const xDomain = this.xScale.domain().map(d => +d) // Convert Date to number\n const yDomain = this.yScale.domain().map(d => +d) // Convert Date to number\n const yAccessors = (isArray(config.y) ? config.y : [config.y]) as NumericAccessor<Datum>[]\n\n const maxSizeValue = max<number>(flatten(yAccessors.map((y, j) => data?.map(d => getNumber(d, config.size, j)))))\n const maxSizePx = config.sizeRange ? config.sizeScale(maxSizeValue) : maxSizeValue\n const maxSizeXDomain = (this.xScale.invert(maxSizePx) as number) - (this.xScale.invert(0) as number)\n const maxSizeYDomain = Math.abs((this.yScale.invert(maxSizePx) as number) - (this.yScale.invert(0) as number))\n\n return yAccessors.map((y, j) => {\n return data?.reduce<ScatterPoint<Datum>[]>((acc, d, i) => {\n const xValue = getNumber(d, config.x, i)\n const yValue = getNumber(d, y, j)\n const pointSize = getNumber(d, config.size, i)\n const pointSizeScaled = config.sizeRange ? config.sizeScale(pointSize) : pointSize\n const pointSizeXDomain = (this.xScale.invert(pointSizeScaled) as number) - (this.xScale.invert(0) as number)\n const pointSizeYDomain = Math.abs((this.yScale.invert(pointSizeScaled) as number) - (this.yScale.invert(0) as number))\n\n if (\n ((xValue - pointSizeXDomain / 2) >= (xDomain[0] - maxSizeXDomain / 2)) &&\n ((xValue + pointSizeXDomain / 2) <= (xDomain[1] + maxSizeXDomain / 2)) &&\n ((yValue - pointSizeYDomain / 2) >= (yDomain[0] - maxSizeYDomain / 2)) &&\n ((yValue + pointSizeYDomain / 2) <= (yDomain[1] + maxSizeYDomain / 2))\n ) {\n acc.push({\n ...d,\n _point: {\n xValue: xValue,\n yValue: yValue,\n sizePx: pointSizeScaled,\n color: getColor(d, config.color, j),\n strokeColor: getColor(d, config.strokeColor, j, true),\n strokeWidthPx: getNumber(d, config.strokeWidth, j),\n shape: getString(d, config.shape, j) as SymbolType,\n label: getString(d, config.label, j),\n labelColor: getValue(d, config.labelColor, j),\n cursor: getString(d, config.cursor, j),\n groupIndex: j,\n pointIndex: i,\n },\n })\n }\n\n return acc\n }, []) ?? []\n })\n }\n\n private _onPointMouseOver (d: ScatterPoint<Datum>, event: MouseEvent): void {\n const point = select(event.target as SVGGElement)\n const pointNode = point.node() as ScatterPointGroupNode | null\n if (pointNode) pointNode._forceShowLabel = true\n\n point.raise()\n this._resolveLabelOverlap()\n }\n\n private _onPointMouseOut (d: ScatterPoint<Datum>, event: MouseEvent): void {\n const pointNode = select(event.target as SVGGElement).node() as ScatterPointGroupNode | null\n if (pointNode) delete pointNode._forceShowLabel\n\n this._resolveLabelOverlap()\n }\n}\n"],"names":["s.pointGroup","pointGroupExit","s.pointGroupExit","s.point","s"],"mappings":"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"}
|
|
@@ -12,8 +12,9 @@ export declare class SingleContainer<Data> extends ContainerCore {
|
|
|
12
12
|
updateComponent(componentConfig: ComponentConfigInterface, preventRender?: boolean): void;
|
|
13
13
|
update(containerConfig: SingleContainerConfigInterface<Data>, componentConfig?: ComponentConfigInterface, data?: Data): void;
|
|
14
14
|
getFitWidthScale(): number;
|
|
15
|
-
|
|
15
|
+
protected _preRender(): void;
|
|
16
|
+
protected _render(duration?: number): void;
|
|
16
17
|
render(duration?: any): void;
|
|
17
|
-
_onResize(): void;
|
|
18
|
+
protected _onResize(): void;
|
|
18
19
|
destroy(): void;
|
|
19
20
|
}
|
|
@@ -32,7 +32,7 @@ class SingleContainer extends ContainerCore {
|
|
|
32
32
|
}
|
|
33
33
|
updateContainer(containerConfig, preventRender) {
|
|
34
34
|
super.updateContainer(containerConfig);
|
|
35
|
-
this.
|
|
35
|
+
this._removeAllChildren();
|
|
36
36
|
this.component = containerConfig.component;
|
|
37
37
|
if (containerConfig.sizing)
|
|
38
38
|
this.component.sizing = containerConfig.sizing;
|
|
@@ -68,10 +68,13 @@ class SingleContainer extends ContainerCore {
|
|
|
68
68
|
const componentWidth = extendedSizeComponent.getWidth() + config.margin.left + config.margin.right;
|
|
69
69
|
return this.width / componentWidth;
|
|
70
70
|
}
|
|
71
|
+
_preRender() {
|
|
72
|
+
super._preRender();
|
|
73
|
+
this.component.setSize(this.width, this.height, this.containerWidth, this.containerHeight);
|
|
74
|
+
}
|
|
71
75
|
_render(duration) {
|
|
72
76
|
const { config, component } = this;
|
|
73
77
|
super._render(duration);
|
|
74
|
-
component.setSize(this.width, this.height, this.containerWidth, this.containerHeight);
|
|
75
78
|
component.g.attr('transform', `translate(${config.margin.left},${config.margin.top})`);
|
|
76
79
|
component.render(duration);
|
|
77
80
|
if (config.tooltip)
|
|
@@ -109,6 +112,7 @@ class SingleContainer extends ContainerCore {
|
|
|
109
112
|
// Schedule the actual rendering in the next frame
|
|
110
113
|
cancelAnimationFrame(this._requestedAnimationFrame);
|
|
111
114
|
this._requestedAnimationFrame = requestAnimationFrame(() => {
|
|
115
|
+
this._preRender();
|
|
112
116
|
this._render(duration);
|
|
113
117
|
});
|
|
114
118
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/containers/single-container/index.ts"],"sourcesContent":["// Global CSS variables (side effects import)\nimport 'styles/index'\n\n// Core\nimport { ContainerCore } from 'core/container'\nimport { ComponentCore } from 'core/component'\nimport { ComponentConfigInterface } from 'core/component/config'\n\n// Utils\nimport { smartTransition } from 'utils/d3'\n\n// Types\nimport { Sizing, ExtendedSizeComponent } from 'types/component'\n\n// Config\nimport { SingleContainerConfig, SingleContainerConfigInterface } from './config'\n\nexport class SingleContainer<Data> extends ContainerCore {\n component: ComponentCore<Data>\n config: SingleContainerConfig<Data> = new SingleContainerConfig()\n\n constructor (element: HTMLElement, config?: SingleContainerConfigInterface<Data>, data?: Data) {\n super(element)\n\n if (config) {\n this.updateContainer(config, true)\n this.component = config.component\n }\n\n if (data) {\n this.setData(data, true)\n }\n\n // Render if component exists and has data\n if (this.component?.datamodel.data) this.render()\n }\n\n public setData (data: Data, preventRender?: boolean): void {\n const { config } = this\n\n if (this.component) this.component.setData(data)\n if (!preventRender) this.render()\n config.tooltip?.hide()\n }\n\n public updateContainer (containerConfig: SingleContainerConfigInterface<Data>, preventRender?: boolean): void {\n super.updateContainer(containerConfig)\n this.removeAllChildren()\n\n this.component = containerConfig.component\n if (containerConfig.sizing) this.component.sizing = containerConfig.sizing\n this.element.appendChild(this.component.element)\n\n const tooltip = containerConfig.tooltip\n if (tooltip) {\n if (!tooltip.hasContainer()) tooltip.setContainer(this._container)\n tooltip.setComponents([this.component])\n }\n\n if (!preventRender) this.render()\n }\n\n public updateComponent (componentConfig: ComponentConfigInterface, preventRender?: boolean): void {\n this.component.setConfig(componentConfig)\n if (!preventRender) this.render()\n }\n\n public update (\n containerConfig: SingleContainerConfigInterface<Data>,\n componentConfig?: ComponentConfigInterface,\n data?: Data\n ): void {\n if (containerConfig) this.updateContainer(containerConfig, true)\n if (componentConfig) this.updateComponent(componentConfig, true)\n if (data) this.setData(data, true)\n this.render()\n }\n\n public getFitWidthScale (): number {\n const { config, component } = this\n\n const extendedSizeComponent = component as ExtendedSizeComponent\n if (!extendedSizeComponent.getWidth) return 1\n\n const componentWidth = extendedSizeComponent.getWidth() + config.margin.left + config.margin.right\n return this.width / componentWidth\n }\n\n _render (duration?: number): void {\n const { config, component } = this\n super._render(duration)\n\n component.setSize(this.width, this.height, this.containerWidth, this.containerHeight)\n component.g.attr('transform', `translate(${config.margin.left},${config.margin.top})`)\n component.render(duration)\n\n if (config.tooltip) config.tooltip.update()\n }\n\n // Re-defining the `render()` function to handle different sizing techniques (`Sizing.Extend` and `Sizing.FitWidth`)\n // Not calling `super.render()` because we don't want it to interfere with setting the SVG size here.\n render (duration = this.config.duration): void {\n const { config, component } = this\n\n if (config.sizing === Sizing.Extend || config.sizing === Sizing.FitWidth) {\n const fitToWidth = config.sizing === Sizing.FitWidth\n const extendedSizeComponent = component as ExtendedSizeComponent\n\n const componentWidth = extendedSizeComponent.getWidth() + config.margin.left + config.margin.right\n const componentHeight = extendedSizeComponent.getHeight() + config.margin.top + config.margin.bottom\n const scale = fitToWidth ? this.getFitWidthScale() : 1\n\n const currentWidth = this.svg.attr('width')\n const currentHeight = this.svg.attr('height')\n const scaledWidth = componentWidth * scale\n const scaledHeight = componentHeight * scale\n const animated = currentWidth || currentHeight\n\n smartTransition(this.svg, animated ? duration : 0)\n .attr('width', scaledWidth)\n .attr('height', scaledHeight)\n .attr('viewBox', `${0} ${0} ${componentWidth} ${fitToWidth ? scaledHeight : componentHeight}`)\n .attr('preserveAspectRatio', 'xMinYMin')\n } else {\n this.svg\n .attr('width', this.config.width || this.containerWidth)\n .attr('height', this.config.height || this.containerHeight)\n }\n\n // Set up Resize Observer\n if (!this._resizeObserver) this._setUpResizeObserver()\n\n // Schedule the actual rendering in the next frame\n cancelAnimationFrame(this._requestedAnimationFrame)\n this._requestedAnimationFrame = requestAnimationFrame(() => {\n this._render(duration)\n })\n }\n\n _onResize (): void {\n const { config } = this\n super._onResize()\n config.tooltip?.hide()\n }\n\n public destroy (): void {\n const { component, config } = this\n super.destroy()\n\n component?.destroy()\n config.tooltip?.destroy()\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/containers/single-container/index.ts"],"sourcesContent":["// Global CSS variables (side effects import)\nimport 'styles/index'\n\n// Core\nimport { ContainerCore } from 'core/container'\nimport { ComponentCore } from 'core/component'\nimport { ComponentConfigInterface } from 'core/component/config'\n\n// Utils\nimport { smartTransition } from 'utils/d3'\n\n// Types\nimport { Sizing, ExtendedSizeComponent } from 'types/component'\n\n// Config\nimport { SingleContainerConfig, SingleContainerConfigInterface } from './config'\n\nexport class SingleContainer<Data> extends ContainerCore {\n component: ComponentCore<Data>\n config: SingleContainerConfig<Data> = new SingleContainerConfig()\n\n constructor (element: HTMLElement, config?: SingleContainerConfigInterface<Data>, data?: Data) {\n super(element)\n\n if (config) {\n this.updateContainer(config, true)\n this.component = config.component\n }\n\n if (data) {\n this.setData(data, true)\n }\n\n // Render if component exists and has data\n if (this.component?.datamodel.data) this.render()\n }\n\n public setData (data: Data, preventRender?: boolean): void {\n const { config } = this\n\n if (this.component) this.component.setData(data)\n if (!preventRender) this.render()\n config.tooltip?.hide()\n }\n\n public updateContainer (containerConfig: SingleContainerConfigInterface<Data>, preventRender?: boolean): void {\n super.updateContainer(containerConfig)\n this._removeAllChildren()\n\n this.component = containerConfig.component\n if (containerConfig.sizing) this.component.sizing = containerConfig.sizing\n this.element.appendChild(this.component.element)\n\n const tooltip = containerConfig.tooltip\n if (tooltip) {\n if (!tooltip.hasContainer()) tooltip.setContainer(this._container)\n tooltip.setComponents([this.component])\n }\n\n if (!preventRender) this.render()\n }\n\n public updateComponent (componentConfig: ComponentConfigInterface, preventRender?: boolean): void {\n this.component.setConfig(componentConfig)\n if (!preventRender) this.render()\n }\n\n public update (\n containerConfig: SingleContainerConfigInterface<Data>,\n componentConfig?: ComponentConfigInterface,\n data?: Data\n ): void {\n if (containerConfig) this.updateContainer(containerConfig, true)\n if (componentConfig) this.updateComponent(componentConfig, true)\n if (data) this.setData(data, true)\n this.render()\n }\n\n public getFitWidthScale (): number {\n const { config, component } = this\n\n const extendedSizeComponent = component as ExtendedSizeComponent\n if (!extendedSizeComponent.getWidth) return 1\n\n const componentWidth = extendedSizeComponent.getWidth() + config.margin.left + config.margin.right\n return this.width / componentWidth\n }\n\n protected _preRender (): void {\n super._preRender()\n this.component.setSize(this.width, this.height, this.containerWidth, this.containerHeight)\n }\n\n protected _render (duration?: number): void {\n const { config, component } = this\n super._render(duration)\n\n component.g.attr('transform', `translate(${config.margin.left},${config.margin.top})`)\n component.render(duration)\n\n if (config.tooltip) config.tooltip.update()\n }\n\n // Re-defining the `render()` function to handle different sizing techniques (`Sizing.Extend` and `Sizing.FitWidth`)\n // Not calling `super.render()` because we don't want it to interfere with setting the SVG size here.\n public render (duration = this.config.duration): void {\n const { config, component } = this\n\n if (config.sizing === Sizing.Extend || config.sizing === Sizing.FitWidth) {\n const fitToWidth = config.sizing === Sizing.FitWidth\n const extendedSizeComponent = component as ExtendedSizeComponent\n\n const componentWidth = extendedSizeComponent.getWidth() + config.margin.left + config.margin.right\n const componentHeight = extendedSizeComponent.getHeight() + config.margin.top + config.margin.bottom\n const scale = fitToWidth ? this.getFitWidthScale() : 1\n\n const currentWidth = this.svg.attr('width')\n const currentHeight = this.svg.attr('height')\n const scaledWidth = componentWidth * scale\n const scaledHeight = componentHeight * scale\n const animated = currentWidth || currentHeight\n\n smartTransition(this.svg, animated ? duration : 0)\n .attr('width', scaledWidth)\n .attr('height', scaledHeight)\n .attr('viewBox', `${0} ${0} ${componentWidth} ${fitToWidth ? scaledHeight : componentHeight}`)\n .attr('preserveAspectRatio', 'xMinYMin')\n } else {\n this.svg\n .attr('width', this.config.width || this.containerWidth)\n .attr('height', this.config.height || this.containerHeight)\n }\n\n // Set up Resize Observer\n if (!this._resizeObserver) this._setUpResizeObserver()\n\n // Schedule the actual rendering in the next frame\n cancelAnimationFrame(this._requestedAnimationFrame)\n this._requestedAnimationFrame = requestAnimationFrame(() => {\n this._preRender()\n this._render(duration)\n })\n }\n\n protected _onResize (): void {\n const { config } = this\n super._onResize()\n config.tooltip?.hide()\n }\n\n public destroy (): void {\n const { component, config } = this\n super.destroy()\n\n component?.destroy()\n config.tooltip?.destroy()\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -69,10 +69,12 @@ export interface XYContainerConfigInterface<Datum> extends ContainerConfigInterf
|
|
|
69
69
|
/** Crosshair component. Default: `undefined` */
|
|
70
70
|
crosshair?: Crosshair<Datum> | undefined;
|
|
71
71
|
/** Prevents the chart domain from being empty (when domain's min and max values are equal).
|
|
72
|
-
* That usually happens when all the data values are
|
|
73
|
-
* Setting to `true` will automatically extend the domain by `+1` when
|
|
74
|
-
*
|
|
75
|
-
|
|
72
|
+
* That usually happens when all the data values are equal or when there's no data.
|
|
73
|
+
* Setting to `true` will automatically extend the domain by `+1` when the domain is empty (domain start equals domain end).
|
|
74
|
+
* Setting to `null` will extend the empty domain, but only when there's no data.
|
|
75
|
+
* Setting to `false` will keep the domain as is.
|
|
76
|
+
* Default: `null` */
|
|
77
|
+
preventEmptyDomain?: boolean | null;
|
|
76
78
|
/** Sets the Y scale domain based on the current X scale domain (not the whole dataset). Default: `false` */
|
|
77
79
|
scaleByDomain?: boolean;
|
|
78
80
|
}
|
|
@@ -94,6 +96,6 @@ export declare class XYContainerConfig<Datum> extends ContainerConfig implements
|
|
|
94
96
|
yDomainMaxConstraint: any;
|
|
95
97
|
yRange: any;
|
|
96
98
|
yDirection: Direction;
|
|
97
|
-
preventEmptyDomain:
|
|
99
|
+
preventEmptyDomain: any;
|
|
98
100
|
scaleByDomain: boolean;
|
|
99
101
|
}
|
|
@@ -21,7 +21,7 @@ class XYContainerConfig extends ContainerConfig {
|
|
|
21
21
|
this.yDomainMaxConstraint = undefined;
|
|
22
22
|
this.yRange = undefined;
|
|
23
23
|
this.yDirection = Direction.North;
|
|
24
|
-
this.preventEmptyDomain =
|
|
24
|
+
this.preventEmptyDomain = null;
|
|
25
25
|
this.scaleByDomain = false;
|
|
26
26
|
}
|
|
27
27
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sources":["../../../src/containers/xy-container/config.ts"],"sourcesContent":["// Core\nimport { XYComponentCore } from 'core/xy-component'\nimport { ContainerConfig, ContainerConfigInterface } from 'core/container/config'\nimport { Tooltip } from 'components/tooltip'\n\n// Components\nimport { Axis } from 'components/axis'\nimport { Crosshair } from 'components/crosshair'\n\n// Types\nimport { ContinuousScale } from 'types/scale'\nimport { Direction } from 'types/direction'\n\nexport interface XYContainerConfigInterface<Datum> extends ContainerConfigInterface {\n /** An array of visualization components. Default: `[]` */\n components?: XYComponentCore<Datum>[];\n\n /** Scale for X dimension, e.g. Scale.scaleLinear().\n * If set, this value will override the components' xScale and they will have a single shared xScale instance.\n * By default the components have their own scale instances but their `domain` and `range` values are synchronized.\n * Default: `undefined` */\n xScale?: ContinuousScale;\n /** Scale domain (data extent) for X dimension. By default this value is calculated automatically based on data. */\n xDomain?: [number | undefined, number | undefined];\n /** Constraint the minimum value of the X scale domain. Useful when the data is plotted along the X axis.\n * For example, imagine that you have a chart with dynamic data that has negative values. When values are small\n * (let's say in the range of [-0.01, 0]), you might still want the chart to display some meaningful value range (e.g. [-1, 0]). That can\n * be achieved by setting `xDomainMinConstraint` to `[undefined, -1]`. In addition to that, if you want to cut off the\n * values that are too low (let's say lower than -100), you can set the constraint to `[-100, -1]`\n * Default: `undefined` */\n xDomainMinConstraint?: [number | undefined, number | undefined];\n /** Constraint the minimum value of the X scale domain. Useful when the data is plotted along the X axis.\n * For example, imagine that you have a chart with dynamic data. When values are small\n * (let's say < 0.01), you might still want the chart to display some meaningful value range (e.g. [0, 1]). That can\n * be achieved by setting `xDomainMaxConstraint` to `[1, undefined]`. In addition to that, if you want to cut off the\n * values that are too high (let's say higher than 100), you can set the constraint to `[1, 100]`\n * Default: `undefined` */\n xDomainMaxConstraint?: [number | undefined, number | undefined];\n /** Force set the X scale range (in the screen space). By default the range is calculated automatically based on the\n * chart's set up */\n xRange?: [number, number];\n\n /** Scale for Y dimension, e.g. Scale.scaleLinear().\n * If set, this value will override the components' yScale and they will have a single shared yScale instance.\n * By default the components have their own scale instances but their `domain` and `range` values are synchronized.\n * Default: `undefined` */\n yScale?: ContinuousScale;\n /** Scale domain (data extent) for Y dimension. By default this value is calculated automatically based on data. */\n yDomain?: [number | undefined, number | undefined];\n /** Constraint the minimum value of the Y scale domain.\n * For example, imagine that you have a chart with dynamic data that has negative values. When values are small\n * (let's say in the range of [-0.01, 0]), you might still want the chart to display some meaningful value range (e.g. [-1, 0]). That can\n * be achieved by setting `yDomainMinConstraint` to `[undefined, -1]`. In addition to that, if you want to cut off the\n * values that are too low (let's say lower than -100), you can set the constraint to `[-100, -1]`\n * Default: `undefined` */\n yDomainMinConstraint?: [number | undefined, number | undefined];\n /** Constraint the minimum value of the Y scale domain.\n * For example, imagine that you have a chart with dynamic data. When values are small\n * (let's say < 0.01), you might still want the chart to display some meaningful value range (e.g. [0, 1]). That can\n * be achieved by setting `yDomainMaxConstraint` to `[1, undefined]`. In addition to that, if you want to cut off the\n * values that are too high (let's say higher than 100), you can set the constraint to `[1, 100]`\n * Default: `undefined` */\n yDomainMaxConstraint?: [number | undefined, number | undefined];\n /** Force set the Y scale range (in the screen space). By default the range is calculated automatically based on the\n * chart's set up */\n yRange?: [number, number];\n /** Y Axis direction. Default: `Direction.North` */\n yDirection?: Direction.South | Direction.North | string;\n\n /** X Axis component instance. Default: `undefined` */\n xAxis?: Axis<Datum>;\n /** Y Axis component instance. Default: `undefined` */\n yAxis?: Axis<Datum>;\n /** Enables automatic calculation of chart margins based on the size of the axes. Default: `true` */\n autoMargin?: boolean;\n /** Tooltip component. Default: `undefined` */\n tooltip?: Tooltip | undefined;\n /** Crosshair component. Default: `undefined` */\n crosshair?: Crosshair<Datum> | undefined;\n /** Prevents the chart domain from being empty (when domain's min and max values are equal).\n * That usually happens when all the data values are
|
|
1
|
+
{"version":3,"file":"config.js","sources":["../../../src/containers/xy-container/config.ts"],"sourcesContent":["// Core\nimport { XYComponentCore } from 'core/xy-component'\nimport { ContainerConfig, ContainerConfigInterface } from 'core/container/config'\nimport { Tooltip } from 'components/tooltip'\n\n// Components\nimport { Axis } from 'components/axis'\nimport { Crosshair } from 'components/crosshair'\n\n// Types\nimport { ContinuousScale } from 'types/scale'\nimport { Direction } from 'types/direction'\n\nexport interface XYContainerConfigInterface<Datum> extends ContainerConfigInterface {\n /** An array of visualization components. Default: `[]` */\n components?: XYComponentCore<Datum>[];\n\n /** Scale for X dimension, e.g. Scale.scaleLinear().\n * If set, this value will override the components' xScale and they will have a single shared xScale instance.\n * By default the components have their own scale instances but their `domain` and `range` values are synchronized.\n * Default: `undefined` */\n xScale?: ContinuousScale;\n /** Scale domain (data extent) for X dimension. By default this value is calculated automatically based on data. */\n xDomain?: [number | undefined, number | undefined];\n /** Constraint the minimum value of the X scale domain. Useful when the data is plotted along the X axis.\n * For example, imagine that you have a chart with dynamic data that has negative values. When values are small\n * (let's say in the range of [-0.01, 0]), you might still want the chart to display some meaningful value range (e.g. [-1, 0]). That can\n * be achieved by setting `xDomainMinConstraint` to `[undefined, -1]`. In addition to that, if you want to cut off the\n * values that are too low (let's say lower than -100), you can set the constraint to `[-100, -1]`\n * Default: `undefined` */\n xDomainMinConstraint?: [number | undefined, number | undefined];\n /** Constraint the minimum value of the X scale domain. Useful when the data is plotted along the X axis.\n * For example, imagine that you have a chart with dynamic data. When values are small\n * (let's say < 0.01), you might still want the chart to display some meaningful value range (e.g. [0, 1]). That can\n * be achieved by setting `xDomainMaxConstraint` to `[1, undefined]`. In addition to that, if you want to cut off the\n * values that are too high (let's say higher than 100), you can set the constraint to `[1, 100]`\n * Default: `undefined` */\n xDomainMaxConstraint?: [number | undefined, number | undefined];\n /** Force set the X scale range (in the screen space). By default the range is calculated automatically based on the\n * chart's set up */\n xRange?: [number, number];\n\n /** Scale for Y dimension, e.g. Scale.scaleLinear().\n * If set, this value will override the components' yScale and they will have a single shared yScale instance.\n * By default the components have their own scale instances but their `domain` and `range` values are synchronized.\n * Default: `undefined` */\n yScale?: ContinuousScale;\n /** Scale domain (data extent) for Y dimension. By default this value is calculated automatically based on data. */\n yDomain?: [number | undefined, number | undefined];\n /** Constraint the minimum value of the Y scale domain.\n * For example, imagine that you have a chart with dynamic data that has negative values. When values are small\n * (let's say in the range of [-0.01, 0]), you might still want the chart to display some meaningful value range (e.g. [-1, 0]). That can\n * be achieved by setting `yDomainMinConstraint` to `[undefined, -1]`. In addition to that, if you want to cut off the\n * values that are too low (let's say lower than -100), you can set the constraint to `[-100, -1]`\n * Default: `undefined` */\n yDomainMinConstraint?: [number | undefined, number | undefined];\n /** Constraint the minimum value of the Y scale domain.\n * For example, imagine that you have a chart with dynamic data. When values are small\n * (let's say < 0.01), you might still want the chart to display some meaningful value range (e.g. [0, 1]). That can\n * be achieved by setting `yDomainMaxConstraint` to `[1, undefined]`. In addition to that, if you want to cut off the\n * values that are too high (let's say higher than 100), you can set the constraint to `[1, 100]`\n * Default: `undefined` */\n yDomainMaxConstraint?: [number | undefined, number | undefined];\n /** Force set the Y scale range (in the screen space). By default the range is calculated automatically based on the\n * chart's set up */\n yRange?: [number, number];\n /** Y Axis direction. Default: `Direction.North` */\n yDirection?: Direction.South | Direction.North | string;\n\n /** X Axis component instance. Default: `undefined` */\n xAxis?: Axis<Datum>;\n /** Y Axis component instance. Default: `undefined` */\n yAxis?: Axis<Datum>;\n /** Enables automatic calculation of chart margins based on the size of the axes. Default: `true` */\n autoMargin?: boolean;\n /** Tooltip component. Default: `undefined` */\n tooltip?: Tooltip | undefined;\n /** Crosshair component. Default: `undefined` */\n crosshair?: Crosshair<Datum> | undefined;\n /** Prevents the chart domain from being empty (when domain's min and max values are equal).\n * That usually happens when all the data values are equal or when there's no data.\n * Setting to `true` will automatically extend the domain by `+1` when the domain is empty (domain start equals domain end).\n * Setting to `null` will extend the empty domain, but only when there's no data.\n * Setting to `false` will keep the domain as is.\n * Default: `null` */\n preventEmptyDomain?: boolean | null;\n /** Sets the Y scale domain based on the current X scale domain (not the whole dataset). Default: `false` */\n scaleByDomain?: boolean;\n}\n\nexport class XYContainerConfig<Datum> extends ContainerConfig implements XYContainerConfigInterface<Datum> {\n components = []\n tooltip: Tooltip = undefined\n crosshair: Crosshair<Datum> = undefined\n xAxis: Axis<Datum> = undefined\n yAxis: Axis<Datum> = undefined\n autoMargin = true\n\n xScale = undefined\n xDomain = undefined\n xDomainMinConstraint = undefined\n xDomainMaxConstraint = undefined\n xRange = undefined\n\n yScale = undefined\n yDomain = undefined\n yDomainMinConstraint = undefined\n yDomainMaxConstraint = undefined\n yRange = undefined\n yDirection = Direction.North\n\n preventEmptyDomain = null\n scaleByDomain = false\n}\n"],"names":[],"mappings":";;;AA0FM,MAAO,iBAAyB,SAAQ,eAAe,CAAA;AAA7D,IAAA,WAAA,GAAA;;QACE,IAAU,CAAA,UAAA,GAAG,EAAE,CAAA;QACf,IAAO,CAAA,OAAA,GAAY,SAAS,CAAA;QAC5B,IAAS,CAAA,SAAA,GAAqB,SAAS,CAAA;QACvC,IAAK,CAAA,KAAA,GAAgB,SAAS,CAAA;QAC9B,IAAK,CAAA,KAAA,GAAgB,SAAS,CAAA;QAC9B,IAAU,CAAA,UAAA,GAAG,IAAI,CAAA;QAEjB,IAAM,CAAA,MAAA,GAAG,SAAS,CAAA;QAClB,IAAO,CAAA,OAAA,GAAG,SAAS,CAAA;QACnB,IAAoB,CAAA,oBAAA,GAAG,SAAS,CAAA;QAChC,IAAoB,CAAA,oBAAA,GAAG,SAAS,CAAA;QAChC,IAAM,CAAA,MAAA,GAAG,SAAS,CAAA;QAElB,IAAM,CAAA,MAAA,GAAG,SAAS,CAAA;QAClB,IAAO,CAAA,OAAA,GAAG,SAAS,CAAA;QACnB,IAAoB,CAAA,oBAAA,GAAG,SAAS,CAAA;QAChC,IAAoB,CAAA,oBAAA,GAAG,SAAS,CAAA;QAChC,IAAM,CAAA,MAAA,GAAG,SAAS,CAAA;AAClB,QAAA,IAAA,CAAA,UAAU,GAAG,SAAS,CAAC,KAAK,CAAA;QAE5B,IAAkB,CAAA,kBAAA,GAAG,IAAI,CAAA;QACzB,IAAa,CAAA,aAAA,GAAG,KAAK,CAAA;KACtB;AAAA;;;;"}
|
|
@@ -22,13 +22,14 @@ export declare class XYContainer<Datum> extends ContainerCore {
|
|
|
22
22
|
updateContainer(containerConfig: XYContainerConfigInterface<Datum>, preventRender?: boolean): void;
|
|
23
23
|
updateComponents(componentConfigs: XYConfigInterface<Datum>[], preventRender?: boolean): void;
|
|
24
24
|
update(containerConfig: XYContainerConfigInterface<Datum>, componentConfigs?: XYComponentConfigInterface<Datum>[], data?: Datum[]): void;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
25
|
+
protected _preRender(): void;
|
|
26
|
+
protected _render(customDuration?: number): void;
|
|
27
|
+
private _updateScales;
|
|
28
|
+
private _setScales;
|
|
29
|
+
private _updateScalesDomain;
|
|
30
|
+
private _updateScalesRange;
|
|
31
|
+
private _renderAxes;
|
|
32
|
+
private _setAutoMargin;
|
|
32
33
|
private _getMargin;
|
|
33
34
|
destroy(): void;
|
|
34
35
|
}
|
|
@@ -84,7 +84,7 @@ class XYContainer extends ContainerCore {
|
|
|
84
84
|
}
|
|
85
85
|
updateContainer(containerConfig, preventRender) {
|
|
86
86
|
super.updateContainer(containerConfig);
|
|
87
|
-
this.
|
|
87
|
+
this._removeAllChildren();
|
|
88
88
|
// If there were any new components added we need to pass them data
|
|
89
89
|
this.setData(this.datamodel.data, true);
|
|
90
90
|
// Set up the axes
|
|
@@ -130,7 +130,7 @@ class XYContainer extends ContainerCore {
|
|
|
130
130
|
c.setConfig(componentConfigs[i]);
|
|
131
131
|
}
|
|
132
132
|
});
|
|
133
|
-
this.
|
|
133
|
+
this._updateScales(...this.components, config.xAxis, config.yAxis, config.crosshair);
|
|
134
134
|
if (!preventRender)
|
|
135
135
|
this.render();
|
|
136
136
|
}
|
|
@@ -143,18 +143,22 @@ class XYContainer extends ContainerCore {
|
|
|
143
143
|
this.updateComponents(componentConfigs, true);
|
|
144
144
|
this.render();
|
|
145
145
|
}
|
|
146
|
-
|
|
147
|
-
var _a, _b, _c;
|
|
146
|
+
_preRender() {
|
|
148
147
|
const { config } = this;
|
|
149
|
-
super.
|
|
148
|
+
super._preRender();
|
|
150
149
|
// Calculate extra margin required to fit the axes
|
|
151
150
|
if (config.autoMargin) {
|
|
152
151
|
this._setAutoMargin();
|
|
153
152
|
}
|
|
153
|
+
// Update Scales of all the components at once to calculate required paddings and sync them
|
|
154
|
+
this._updateScales(...this.components, config.xAxis, config.yAxis, config.crosshair);
|
|
155
|
+
}
|
|
156
|
+
_render(customDuration) {
|
|
157
|
+
var _a, _b, _c;
|
|
158
|
+
const { config } = this;
|
|
159
|
+
super._render();
|
|
154
160
|
// Get chart total margin after auto margin calculations
|
|
155
161
|
const margin = this._getMargin();
|
|
156
|
-
// Update Scales of all the components at once to calculate required paddings and sync them
|
|
157
|
-
this.updateScales(...this.components, config.xAxis, config.yAxis, config.crosshair);
|
|
158
162
|
// Render components
|
|
159
163
|
for (const c of this.components) {
|
|
160
164
|
c.g.attr('transform', `translate(${margin.left},${margin.top})`)
|
|
@@ -194,7 +198,7 @@ class XYContainer extends ContainerCore {
|
|
|
194
198
|
}
|
|
195
199
|
this._firstRender = false;
|
|
196
200
|
}
|
|
197
|
-
|
|
201
|
+
_updateScales(...components) {
|
|
198
202
|
const c = clean(components || this.components);
|
|
199
203
|
this._setScales(...c);
|
|
200
204
|
this._updateScalesDomain(...c);
|
|
@@ -214,12 +218,11 @@ class XYContainer extends ContainerCore {
|
|
|
214
218
|
const { config } = this;
|
|
215
219
|
if (!components)
|
|
216
220
|
return;
|
|
221
|
+
const componentsWithDomain = components.filter(c => !c.config.excludeFromDomainCalculation);
|
|
217
222
|
// Loop over all the dimensions
|
|
218
223
|
Object.values(ScaleDimension).forEach((dimension) => {
|
|
219
224
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
220
|
-
const [min, max] = extent(merge(
|
|
221
|
-
.filter(c => !c.config.excludeFromDomainCalculation)
|
|
222
|
-
.map(c => c.getDataExtent(dimension, config.scaleByDomain)))); // Components with undefined dimension accessors will return [undefined, undefined] but d3.extent will take care of that
|
|
225
|
+
const [min, max] = extent(merge(componentsWithDomain.map(c => c.getDataExtent(dimension, config.scaleByDomain)))); // Components with undefined dimension accessors will return [undefined, undefined] but d3.extent will take care of that
|
|
223
226
|
const configuredDomain = dimension === ScaleDimension.Y ? config.yDomain : config.xDomain;
|
|
224
227
|
const configuredDomainMinConstraint = dimension === ScaleDimension.Y ? config.yDomainMinConstraint : config.xDomainMinConstraint;
|
|
225
228
|
const configuredDomainMaxConstraint = dimension === ScaleDimension.Y ? config.yDomainMaxConstraint : config.xDomainMaxConstraint;
|
|
@@ -229,8 +232,12 @@ class XYContainer extends ContainerCore {
|
|
|
229
232
|
clamp(domainMin, (_e = configuredDomainMinConstraint === null || configuredDomainMinConstraint === void 0 ? void 0 : configuredDomainMinConstraint[0]) !== null && _e !== void 0 ? _e : Number.NEGATIVE_INFINITY, (_f = configuredDomainMinConstraint === null || configuredDomainMinConstraint === void 0 ? void 0 : configuredDomainMinConstraint[1]) !== null && _f !== void 0 ? _f : Number.POSITIVE_INFINITY),
|
|
230
233
|
clamp(domainMax, (_g = configuredDomainMaxConstraint === null || configuredDomainMaxConstraint === void 0 ? void 0 : configuredDomainMaxConstraint[0]) !== null && _g !== void 0 ? _g : Number.NEGATIVE_INFINITY, (_h = configuredDomainMaxConstraint === null || configuredDomainMaxConstraint === void 0 ? void 0 : configuredDomainMaxConstraint[1]) !== null && _h !== void 0 ? _h : Number.POSITIVE_INFINITY),
|
|
231
234
|
];
|
|
232
|
-
|
|
233
|
-
|
|
235
|
+
// Extend the domain if there is no data provided or preventEmptyDomain was explicitly set to `true`
|
|
236
|
+
if (domain[0] === domain[1]) {
|
|
237
|
+
const hasDataProvided = componentsWithDomain.some(c => { var _a; return ((_a = c.datamodel.data) === null || _a === void 0 ? void 0 : _a.length) > 0; });
|
|
238
|
+
if (config.preventEmptyDomain || (config.preventEmptyDomain === null && !hasDataProvided)) {
|
|
239
|
+
domain[1] = domain[0] + 1;
|
|
240
|
+
}
|
|
234
241
|
}
|
|
235
242
|
components.forEach(c => c.setScaleDomain(dimension, domain));
|
|
236
243
|
});
|