@unovis/ts 1.6.5 → 1.6.6-beta.1
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/area/index.js +1 -3
- package/components/area/index.js.map +1 -1
- package/components/axis/config.d.ts +10 -7
- package/components/axis/config.js +1 -1
- package/components/axis/config.js.map +1 -1
- package/components/axis/index.d.ts +1 -0
- package/components/axis/index.js +44 -53
- package/components/axis/index.js.map +1 -1
- package/components/axis/style.d.ts +2 -38
- package/components/axis/style.js +28 -24
- package/components/axis/style.js.map +1 -1
- package/components/brush/config.d.ts +3 -0
- package/components/brush/config.js +1 -1
- package/components/brush/config.js.map +1 -1
- package/components/brush/index.d.ts +1 -0
- package/components/brush/index.js +7 -3
- package/components/brush/index.js.map +1 -1
- package/components/crosshair/config.d.ts +2 -0
- package/components/crosshair/config.js +1 -1
- package/components/crosshair/config.js.map +1 -1
- package/components/crosshair/index.d.ts +2 -0
- package/components/crosshair/index.js +8 -1
- package/components/crosshair/index.js.map +1 -1
- package/components/graph/index.js +2 -0
- package/components/graph/index.js.map +1 -1
- package/components/sankey/config.d.ts +2 -0
- package/components/sankey/config.js +1 -1
- package/components/sankey/config.js.map +1 -1
- package/components/sankey/index.d.ts +2 -2
- package/components/sankey/index.js +12 -5
- package/components/sankey/index.js.map +1 -1
- package/components/sankey/types.d.ts +4 -0
- package/components/sankey/types.js +7 -2
- package/components/sankey/types.js.map +1 -1
- package/components/scatter/index.d.ts +4 -0
- package/components/scatter/index.js +14 -0
- package/components/scatter/index.js.map +1 -1
- package/components/stacked-bar/index.d.ts +4 -1
- package/components/stacked-bar/index.js +17 -6
- package/components/stacked-bar/index.js.map +1 -1
- package/components/timeline/config.d.ts +7 -1
- package/components/timeline/config.js +2 -2
- package/components/timeline/config.js.map +1 -1
- package/components/timeline/index.d.ts +2 -2
- package/components/timeline/index.js +63 -32
- package/components/timeline/index.js.map +1 -1
- package/components/timeline/style.d.ts +6 -1
- package/components/timeline/style.js +40 -46
- package/components/timeline/style.js.map +1 -1
- package/components/topojson-map/index.d.ts +2 -2
- package/components/topojson-map/index.js +24 -5
- package/components/topojson-map/index.js.map +1 -1
- package/core/component/index.d.ts +4 -1
- package/core/component/index.js +6 -6
- package/core/component/index.js.map +1 -1
- package/index.js +1 -1
- package/package.json +6 -5
- package/types/misc.js +2 -0
- package/types/misc.js.map +1 -0
- package/types/style.d.ts +1 -0
- package/types.d.ts +1 -0
- package/types.js +2 -1
- package/types.js.map +1 -1
- package/utils/text.js +6 -2
- package/utils/text.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/components/stacked-bar/index.ts"],"sourcesContent":["import { min, max } from 'd3-array'\n\n// Core\nimport { XYComponentCore } from 'core/xy-component'\n\n// Utils\nimport { isNumber, isArray, isEmpty, clamp, getStackedExtent, getString, getNumber, getStackedData, getExtent } from 'utils/data'\nimport { roundedRectPath } from 'utils/path'\nimport { smartTransition } from 'utils/d3'\nimport { getColor } from 'utils/color'\n\n// Types\nimport { ContinuousScale } from 'types/scale'\nimport { NumericAccessor } from 'types/accessor'\nimport { Spacing } from 'types/spacing'\nimport { Orientation } from 'types/position'\n\n// Local Types\nimport { StackedBarDataRecord } from './types'\n\n// Config\nimport { StackedBarDefaultConfig, StackedBarConfigInterface } from './config'\n\n// Styles\nimport * as s from './style'\n\nexport class StackedBar<Datum> extends XYComponentCore<Datum, StackedBarConfigInterface<Datum>> {\n static selectors = s\n protected _defaultConfig = StackedBarDefaultConfig as StackedBarConfigInterface<Datum>\n public config: StackedBarConfigInterface<Datum> = this._defaultConfig\n\n getAccessors = (): NumericAccessor<Datum>[] => (isArray(this.config.y) ? this.config.y : [this.config.y])\n stacked = true\n events = {}\n private _prevNegative: boolean[] | undefined // To help guessing the bar direction when an accessor was set to null or 0\n private _barData: Datum[] = []\n\n constructor (config?: StackedBarConfigInterface<Datum>) {\n super()\n if (config) this.setConfig(config)\n }\n\n get bleed (): Spacing {\n this._barData = this._getVisibleData()\n if (this._barData.length === 0) return { top: 0, bottom: 0, left: 0, right: 0 }\n\n // By default, horizontal orientation is \"flipped\", i.e. the `yDirection` of `XYContainer` is set to `Direction.North`\n const isHorizontalAndFlipped = !this.isVertical() && (this.dataScale.range()[0] > this.dataScale.range()[1])\n const dataDomain = this.dataScale.domain()\n const halfGroupWidth = this._getBarWidth() / 2\n\n const dataScaleValues = this._barData.map((d, i) => getNumber(d, this.config.x, i))\n const firstDataValue = min(dataScaleValues)\n const lastDataValue = max(dataScaleValues)\n const firstValuePx = this.dataScale(firstDataValue)\n const lastValuePx = this.dataScale(lastDataValue)\n\n const dataDomainRequiredStart = this.dataScale.invert(firstValuePx + (isHorizontalAndFlipped ? halfGroupWidth : -halfGroupWidth))\n const dataDomainRequiredEnd = this.dataScale.invert(lastValuePx + (isHorizontalAndFlipped ? -halfGroupWidth : halfGroupWidth))\n const bleedPxStart = dataDomainRequiredStart <= dataDomain[0] ? this.dataScale(dataDomain[0]) - this.dataScale(dataDomainRequiredStart) : 0\n const bleedPxEnd = dataDomainRequiredEnd > dataDomain[1] ? this.dataScale(dataDomainRequiredEnd) - this.dataScale(dataDomain[1]) : 0\n\n return {\n top: this.isVertical() ? 0 : (isHorizontalAndFlipped ? -bleedPxEnd : bleedPxStart),\n bottom: this.isVertical() ? 0 : (isHorizontalAndFlipped ? -bleedPxStart : bleedPxEnd),\n left: this.isVertical() ? bleedPxStart : 0,\n right: this.isVertical() ? bleedPxEnd : 0,\n }\n }\n\n private get dataScale (): ContinuousScale {\n return this.isVertical() ? this.xScale : this.yScale\n }\n\n private get valueScale (): ContinuousScale {\n return this.isVertical() ? this.yScale : this.xScale\n }\n\n private isVertical (): boolean {\n return this.config.orientation === Orientation.Vertical\n }\n\n _render (customDuration?: number): void {\n const { config } = this\n const duration = isNumber(customDuration) ? customDuration : config.duration\n\n const yAccessors = this.getAccessors()\n const stacked = getStackedData(this._barData, 0, yAccessors, this._prevNegative)\n this._prevNegative = stacked.map(s => !!s.isMostlyNegative)\n\n const barGroups = this.g\n .selectAll<SVGGElement, Datum>(`.${s.barGroup}`)\n .data(this._barData, (d, i) => `${getString(d, config.id, i) ?? i}`)\n\n const getBarGroupsTransform = (d: Datum, i: number): string => {\n const v = this.dataScale(getNumber(d, config.x, i))\n const x = this.isVertical() ? v : 0\n const y = this.isVertical() ? 0 : v\n return `translate(${x},${y})`\n }\n\n const barGroupsEnter = barGroups.enter().append('g')\n .attr('class', s.barGroup)\n .attr('transform', getBarGroupsTransform)\n .style('opacity', 1)\n\n const barGroupsMerged = barGroupsEnter.merge(barGroups)\n smartTransition(barGroupsMerged, duration)\n .attr('transform', getBarGroupsTransform)\n .style('opacity', 1)\n\n const barGroupExit = barGroups.exit()\n .attr('class', s.barGroupExit)\n\n smartTransition(barGroupExit, duration)\n .style('opacity', 0)\n .remove()\n\n // Animate bars from exiting groups going down\n smartTransition(barGroupExit.selectAll(`.${s.bar}`), duration)\n .attr('transform', this.isVertical()\n ? `translate(0,${this._height / 3})`\n : `translate(${this._width / 6},0)`\n )\n\n // Render Bars\n const bars = barGroupsMerged\n .selectAll<SVGPathElement, StackedBarDataRecord<Datum>>(`.${s.bar}`)\n .data(\n (d, j) => {\n type StackedBarRenderDatum = {\n datum: Datum;\n index: number;\n stacked: [number, number];\n stackIndex: number;\n isEnding: boolean;\n }\n\n const groupData = stacked\n .map((s, i) => ({\n datum: d,\n index: j,\n stacked: s[j],\n stackIndex: i,\n }))\n .filter(d => d.stacked[0] !== d.stacked[1]) as StackedBarRenderDatum[] // Skip zero-height bars\n\n // Populate `isEnding`\n // Ending bar if the next stack is not the same as the current one\n groupData.forEach((d, i) => {\n d.isEnding = (i === groupData.length - 1) ||\n ((i <= groupData.length - 1) && groupData[i + 1].stacked[0] !== d.stacked[1])\n })\n return groupData\n },\n d => d.stackIndex // Key function for proper transitions\n )\n\n const barsEnter = bars.enter().append('path')\n .attr('class', s.bar)\n .attr('d', d => this._getBarPath(d, true))\n .style('fill', d => getColor(d.datum, config.color, d.stackIndex))\n\n const barsMerged = barsEnter.merge(bars)\n\n smartTransition(barsMerged, duration)\n .attr('d', d => this._getBarPath(d))\n .style('fill', d => getColor(d.datum, config.color, d.stackIndex))\n .style('cursor', d => getString(d.datum, config.cursor, d.stackIndex))\n\n smartTransition(bars.exit(), duration)\n .style('opacity', 0)\n .remove()\n }\n\n _getBarWidth (): number {\n const { config, datamodel: { data } } = this\n if (isEmpty(data)) return 0\n if (config.barWidth) return min([config.barWidth, config.barMaxWidth])\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const isOrdinal = this.dataScale.bandwidth\n const domain = (this.dataScale.domain ? this.dataScale.domain() : []) as number[]\n const domainLength = isOrdinal ? domain.length : domain[1] - domain[0]\n\n // If the dataStep property is provided the amount of data elements is calculates as domainLength / dataStep\n // otherwise we get the number of data elements within the domain range\n // Or if the scale is ordinal we use data.length\n let dataSize = (1 + domainLength / config.dataStep) ||\n (!isOrdinal && data.filter((d, i) => {\n const value = getNumber(d, config.x, i)\n return (value >= domain[0]) && (value <= domain[1])\n }).length) ||\n data.length\n\n // We increase the dataSize by 1 to take into account possible additional domain space\n if (!isOrdinal && dataSize >= 2) dataSize += 1\n\n const c = dataSize < 2 ? 1 : 1 - config.barPadding\n const barWidth = c * (this.isVertical() ? this._width : this._height) / dataSize\n\n return min([barWidth, config.barMaxWidth])\n }\n\n _getVisibleData (): Datum[] {\n const { config, datamodel: { data } } = this\n\n const groupWidth = this._getBarWidth()\n const halfGroupWidthPx = data.length < 2 ? 0 : groupWidth / 2\n\n const scale = this.dataScale\n const halfGroupWidth = Math.abs((scale.invert(halfGroupWidthPx) as number) - (scale.invert(0) as number))\n const filtered = data?.filter((d, i) => {\n const v = getNumber(d, config.x, i)\n const domain: number[] | Date[] = scale.domain()\n const domainMin = +domain[0]\n const domainMax = +domain[1]\n return (v >= (domainMin - halfGroupWidth)) && (v <= (domainMax + halfGroupWidth))\n })\n\n return filtered\n }\n\n _getBarPath (d: StackedBarDataRecord<Datum>, isEntering = false): string {\n const { config } = this\n const yAccessors = this.getAccessors()\n const barWidth = this._getBarWidth()\n\n const isNegative = d.stacked[1] < 0\n const isEnding = d.isEnding // The most top bar or, if the value is negative, the most bottom bar\n const value = getNumber(d.datum, yAccessors[d.stackIndex], d.index)\n const height = isEntering ? 0 : Math.abs(this.valueScale(d.stacked[0]) - this.valueScale(d.stacked[1]))\n const h = !isEntering && config.barMinHeight1Px && (height < 1) && isFinite(value) && (value !== config.barMinHeightZeroValue) ? 1 : height\n const y = isEntering\n ? this.valueScale(0)\n : this.valueScale(isNegative ? d.stacked[0] : d.stacked[1]) - (height < 1 && config.barMinHeight1Px ? 1 : 0)\n\n const x = -barWidth / 2\n const width = barWidth\n\n const cornerRadius = config.roundedCorners\n ? isNumber(config.roundedCorners) ? +config.roundedCorners : width / 2\n : 0\n const cornerRadiusClamped = clamp(cornerRadius, 0, Math.min(height, width) / 2)\n const isNorthDirected = this.yScale.range()[0] > this.yScale.range()[1]\n\n return roundedRectPath({\n x: this.isVertical() ? x : y - h,\n y: this.isVertical() ? y + (isNorthDirected ? 0 : -h) : x,\n w: this.isVertical() ? width : h,\n h: this.isVertical() ? h : width,\n tl: isEnding && (this.isVertical()\n ? (!isNegative && isNorthDirected) || (isNegative && !isNorthDirected)\n : isNegative\n ),\n tr: isEnding && (this.isVertical()\n ? (!isNegative && isNorthDirected) || (isNegative && !isNorthDirected)\n : !isNegative\n ),\n br: isEnding && (this.isVertical()\n ? (isNegative && isNorthDirected) || (!isNegative && !isNorthDirected)\n : !isNegative\n ),\n bl: isEnding && (this.isVertical()\n ? (isNegative && isNorthDirected) || (!isNegative && !isNorthDirected)\n : isNegative\n ),\n r: cornerRadiusClamped,\n })\n }\n\n // After performance optimizations in https://github.com/f5/unovis/pull/708\n // there's a breaking change in the event data structure.\n // This method is used to map the event data to the original data structure.\n // Todo: This can be removed in Unovis 2.0, but the migration guide should contain a note about it.\n protected _mapEventDatum (d: StackedBarDataRecord<Datum>): Datum {\n const eventDatum = {\n ...d,\n ...d.datum,\n }\n\n return eventDatum\n }\n\n getValueScaleExtent (scaleByVisibleData: boolean): number[] {\n const { datamodel } = this\n const yAccessors = this.getAccessors()\n\n const data = scaleByVisibleData ? this._getVisibleData() : datamodel.data\n return getStackedExtent(data, ...yAccessors)\n }\n\n getDataScaleExtent (): number[] {\n const { config, datamodel } = this\n return getExtent(datamodel.data, config.x)\n }\n\n getYDataExtent (scaleByVisibleData: boolean): number[] {\n return this.isVertical() ? this.getValueScaleExtent(scaleByVisibleData) : this.getDataScaleExtent()\n }\n\n getXDataExtent (): number[] {\n return this.isVertical() ? this.getDataScaleExtent() : this.getValueScaleExtent(false)\n }\n}\n"],"names":["s.barGroup","barGroupExit","s.barGroupExit","s.bar","s"],"mappings":";;;;;;;;;;;AA0BM,MAAO,UAAkB,SAAQ,eAAwD,CAAA;AAW7F,IAAA,WAAA,CAAa,MAAyC,EAAA;AACpD,QAAA,KAAK,EAAE,CAAA;QAVC,IAAc,CAAA,cAAA,GAAG,uBAA2D,CAAA;AAC/E,QAAA,IAAA,CAAA,MAAM,GAAqC,IAAI,CAAC,cAAc,CAAA;AAErE,QAAA,IAAA,CAAA,YAAY,GAAG,OAAiC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;QACzG,IAAO,CAAA,OAAA,GAAG,IAAI,CAAA;QACd,IAAM,CAAA,MAAA,GAAG,EAAE,CAAA;QAEH,IAAQ,CAAA,QAAA,GAAY,EAAE,CAAA;AAI5B,QAAA,IAAI,MAAM;AAAE,YAAA,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;KACnC;AAED,IAAA,IAAI,KAAK,GAAA;AACP,QAAA,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,eAAe,EAAE,CAAA;AACtC,QAAA,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;AAAE,YAAA,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAA;;AAG/E,QAAA,MAAM,sBAAsB,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;QAC5G,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAA;QAC1C,MAAM,cAAc,GAAG,IAAI,CAAC,YAAY,EAAE,GAAG,CAAC,CAAA;AAE9C,QAAA,MAAM,eAAe,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;AACnF,QAAA,MAAM,cAAc,GAAG,GAAG,CAAC,eAAe,CAAC,CAAA;AAC3C,QAAA,MAAM,aAAa,GAAG,GAAG,CAAC,eAAe,CAAC,CAAA;QAC1C,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAAA;QACnD,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAA;QAEjD,MAAM,uBAAuB,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,YAAY,IAAI,sBAAsB,GAAG,cAAc,GAAG,CAAC,cAAc,CAAC,CAAC,CAAA;QACjI,MAAM,qBAAqB,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,IAAI,sBAAsB,GAAG,CAAC,cAAc,GAAG,cAAc,CAAC,CAAC,CAAA;AAC9H,QAAA,MAAM,YAAY,GAAG,uBAAuB,IAAI,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAA;AAC3I,QAAA,MAAM,UAAU,GAAG,qBAAqB,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,qBAAqB,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QAEpI,OAAO;YACL,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,IAAI,sBAAsB,GAAG,CAAC,UAAU,GAAG,YAAY,CAAC;YAClF,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,IAAI,sBAAsB,GAAG,CAAC,YAAY,GAAG,UAAU,CAAC;AACrF,YAAA,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,GAAG,YAAY,GAAG,CAAC;AAC1C,YAAA,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,GAAG,UAAU,GAAG,CAAC;SAC1C,CAAA;KACF;AAED,IAAA,IAAY,SAAS,GAAA;AACnB,QAAA,OAAO,IAAI,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;KACrD;AAED,IAAA,IAAY,UAAU,GAAA;AACpB,QAAA,OAAO,IAAI,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;KACrD;IAEO,UAAU,GAAA;QAChB,OAAO,IAAI,CAAC,MAAM,CAAC,WAAW,KAAK,WAAW,CAAC,QAAQ,CAAA;KACxD;AAED,IAAA,OAAO,CAAE,cAAuB,EAAA;AAC9B,QAAA,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;AACvB,QAAA,MAAM,QAAQ,GAAG,QAAQ,CAAC,cAAc,CAAC,GAAG,cAAc,GAAG,MAAM,CAAC,QAAQ,CAAA;AAE5E,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,CAAA;AACtC,QAAA,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,aAAa,CAAC,CAAA;AAChF,QAAA,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAA;AAE3D,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC;AACrB,aAAA,SAAS,CAAqB,CAAI,CAAA,EAAAA,QAAU,EAAE,CAAC;AAC/C,aAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,KAAI,EAAA,IAAA,EAAA,CAAA,CAAC,OAAA,CAAG,EAAA,CAAA,EAAA,GAAA,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA,GAAI,CAAC,CAAA,CAAE,CAAA,EAAA,CAAC,CAAA;AAEtE,QAAA,MAAM,qBAAqB,GAAG,CAAC,CAAQ,EAAE,CAAS,KAAY;AAC5D,YAAA,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;AACnD,YAAA,MAAM,CAAC,GAAG,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,GAAG,CAAC,CAAA;AACnC,YAAA,MAAM,CAAC,GAAG,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,GAAG,CAAC,CAAA;AACnC,YAAA,OAAO,CAAa,UAAA,EAAA,CAAC,CAAI,CAAA,EAAA,CAAC,GAAG,CAAA;AAC/B,SAAC,CAAA;QAED,MAAM,cAAc,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC;AACjD,aAAA,IAAI,CAAC,OAAO,EAAEA,QAAU,CAAC;AACzB,aAAA,IAAI,CAAC,WAAW,EAAE,qBAAqB,CAAC;AACxC,aAAA,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAA;QAEtB,MAAM,eAAe,GAAG,cAAc,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;AACvD,QAAA,eAAe,CAAC,eAAe,EAAE,QAAQ,CAAC;AACvC,aAAA,IAAI,CAAC,WAAW,EAAE,qBAAqB,CAAC;AACxC,aAAA,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAA;AAEtB,QAAA,MAAMC,cAAY,GAAG,SAAS,CAAC,IAAI,EAAE;AAClC,aAAA,IAAI,CAAC,OAAO,EAAEC,YAAc,CAAC,CAAA;AAEhC,QAAA,eAAe,CAACD,cAAY,EAAE,QAAQ,CAAC;AACpC,aAAA,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;AACnB,aAAA,MAAM,EAAE,CAAA;;AAGX,QAAA,eAAe,CAACA,cAAY,CAAC,SAAS,CAAC,CAAA,CAAA,EAAIE,GAAK,CAAA,CAAE,CAAC,EAAE,QAAQ,CAAC;AAC3D,aAAA,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,UAAU,EAAE;AAClC,cAAE,CAAe,YAAA,EAAA,IAAI,CAAC,OAAO,GAAG,CAAC,CAAG,CAAA,CAAA;cAClC,aAAa,IAAI,CAAC,MAAM,GAAG,CAAC,CAAK,GAAA,CAAA,CACpC,CAAA;;QAGH,MAAM,IAAI,GAAG,eAAe;AACzB,aAAA,SAAS,CAA8C,CAAI,CAAA,EAAAA,GAAK,EAAE,CAAC;AACnE,aAAA,IAAI,CACH,CAAC,CAAC,EAAE,CAAC,KAAI;YASP,MAAM,SAAS,GAAG,OAAO;iBACtB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM;AACd,gBAAA,KAAK,EAAE,CAAC;AACR,gBAAA,KAAK,EAAE,CAAC;AACR,gBAAA,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;AACb,gBAAA,UAAU,EAAE,CAAC;AACd,aAAA,CAAC,CAAC;iBACF,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAA4B,CAAA;;;YAIxE,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,KAAI;gBACzB,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,KAAK,SAAS,CAAC,MAAM,GAAG,CAAC;AACpC,qBAAC,CAAC,CAAC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,KAAK,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA;AACnF,aAAC,CAAC,CAAA;AACF,YAAA,OAAO,SAAS,CAAA;SACjB,EACD,CAAC,IAAI,CAAC,CAAC,UAAU;SAClB,CAAA;QAEH,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC;AAC1C,aAAA,IAAI,CAAC,OAAO,EAAEA,GAAK,CAAC;AACpB,aAAA,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;aACzC,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAA;QAEpE,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;AAExC,QAAA,eAAe,CAAC,UAAU,EAAE,QAAQ,CAAC;AAClC,aAAA,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;aACnC,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC;aACjE,KAAK,CAAC,QAAQ,EAAE,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAA;AAExE,QAAA,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC;AACnC,aAAA,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;AACnB,aAAA,MAAM,EAAE,CAAA;KACZ;IAED,YAAY,GAAA;QACV,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,EAAE,GAAG,IAAI,CAAA;QAC5C,IAAI,OAAO,CAAC,IAAI,CAAC;AAAE,YAAA,OAAO,CAAC,CAAA;QAC3B,IAAI,MAAM,CAAC,QAAQ;AAAE,YAAA,OAAO,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAA;;;AAItE,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAA;QAC1C,MAAM,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,GAAG,EAAE,CAAa,CAAA;QACjF,MAAM,YAAY,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;;;;QAKtE,IAAI,QAAQ,GAAG,CAAC,CAAC,GAAG,YAAY,GAAG,MAAM,CAAC,QAAQ;AAC9C,aAAC,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAI;AAClC,gBAAA,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AACvC,gBAAA,OAAO,CAAC,KAAK,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;aACpD,CAAC,CAAC,MAAM,CAAC;YACV,IAAI,CAAC,MAAM,CAAA;;AAGf,QAAA,IAAI,CAAC,SAAS,IAAI,QAAQ,IAAI,CAAC;YAAE,QAAQ,IAAI,CAAC,CAAA;AAE9C,QAAA,MAAM,CAAC,GAAG,QAAQ,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,UAAU,CAAA;QAClD,MAAM,QAAQ,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAA;QAEhF,OAAO,GAAG,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAA;KAC3C;IAED,eAAe,GAAA;QACb,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,EAAE,GAAG,IAAI,CAAA;AAE5C,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,CAAA;AACtC,QAAA,MAAM,gBAAgB,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,GAAG,UAAU,GAAG,CAAC,CAAA;AAE7D,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAA;QAC5B,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAE,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAY,GAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAY,CAAC,CAAA;AACzG,QAAA,MAAM,QAAQ,GAAG,IAAI,KAAA,IAAA,IAAJ,IAAI,KAAJ,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,IAAI,CAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAI;AACrC,YAAA,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AACnC,YAAA,MAAM,MAAM,GAAsB,KAAK,CAAC,MAAM,EAAE,CAAA;AAChD,YAAA,MAAM,SAAS,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;AAC5B,YAAA,MAAM,SAAS,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;AAC5B,YAAA,OAAO,CAAC,CAAC,KAAK,SAAS,GAAG,cAAc,CAAC,MAAM,CAAC,KAAK,SAAS,GAAG,cAAc,CAAC,CAAC,CAAA;AACnF,SAAC,CAAC,CAAA;AAEF,QAAA,OAAO,QAAQ,CAAA;KAChB;AAED,IAAA,WAAW,CAAE,CAA8B,EAAE,UAAU,GAAG,KAAK,EAAA;AAC7D,QAAA,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;AACvB,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,CAAA;AACtC,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE,CAAA;QAEpC,MAAM,UAAU,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;AACnC,QAAA,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAA;AAC3B,QAAA,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAA;AACnE,QAAA,MAAM,MAAM,GAAG,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AACvG,QAAA,MAAM,CAAC,GAAG,CAAC,UAAU,IAAI,MAAM,CAAC,eAAe,KAAK,MAAM,GAAG,CAAC,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC,KAAK,KAAK,KAAK,MAAM,CAAC,qBAAqB,CAAC,GAAG,CAAC,GAAG,MAAM,CAAA;QAC3I,MAAM,CAAC,GAAG,UAAU;AAClB,cAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;AACpB,cAAE,IAAI,CAAC,UAAU,CAAC,UAAU,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,eAAe,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;AAE9G,QAAA,MAAM,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAA;QACvB,MAAM,KAAK,GAAG,QAAQ,CAAA;AAEtB,QAAA,MAAM,YAAY,GAAG,MAAM,CAAC,cAAc;AACxC,cAAE,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,GAAG,KAAK,GAAG,CAAC;cACpE,CAAC,CAAA;AACL,QAAA,MAAM,mBAAmB,GAAG,KAAK,CAAC,YAAY,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;QAC/E,MAAM,eAAe,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAA;AAEvE,QAAA,OAAO,eAAe,CAAC;AACrB,YAAA,CAAC,EAAE,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC;YAChC,CAAC,EAAE,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,IAAI,eAAe,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;AACzD,YAAA,CAAC,EAAE,IAAI,CAAC,UAAU,EAAE,GAAG,KAAK,GAAG,CAAC;AAChC,YAAA,CAAC,EAAE,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,GAAG,KAAK;AAChC,YAAA,EAAE,EAAE,QAAQ,KAAK,IAAI,CAAC,UAAU,EAAE;AAChC,kBAAE,CAAC,CAAC,UAAU,IAAI,eAAe,MAAM,UAAU,IAAI,CAAC,eAAe,CAAC;kBACpE,UAAU,CACb;AACD,YAAA,EAAE,EAAE,QAAQ,KAAK,IAAI,CAAC,UAAU,EAAE;AAChC,kBAAE,CAAC,CAAC,UAAU,IAAI,eAAe,MAAM,UAAU,IAAI,CAAC,eAAe,CAAC;kBACpE,CAAC,UAAU,CACd;AACD,YAAA,EAAE,EAAE,QAAQ,KAAK,IAAI,CAAC,UAAU,EAAE;AAChC,kBAAE,CAAC,UAAU,IAAI,eAAe,MAAM,CAAC,UAAU,IAAI,CAAC,eAAe,CAAC;kBACpE,CAAC,UAAU,CACd;AACD,YAAA,EAAE,EAAE,QAAQ,KAAK,IAAI,CAAC,UAAU,EAAE;AAChC,kBAAE,CAAC,UAAU,IAAI,eAAe,MAAM,CAAC,UAAU,IAAI,CAAC,eAAe,CAAC;kBACpE,UAAU,CACb;AACD,YAAA,CAAC,EAAE,mBAAmB;AACvB,SAAA,CAAC,CAAA;KACH;;;;;AAMS,IAAA,cAAc,CAAE,CAA8B,EAAA;QACtD,MAAM,UAAU,mCACX,CAAC,CAAA,EACD,CAAC,CAAC,KAAK,CACX,CAAA;AAED,QAAA,OAAO,UAAU,CAAA;KAClB;AAED,IAAA,mBAAmB,CAAE,kBAA2B,EAAA;AAC9C,QAAA,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAA;AAC1B,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,CAAA;AAEtC,QAAA,MAAM,IAAI,GAAG,kBAAkB,GAAG,IAAI,CAAC,eAAe,EAAE,GAAG,SAAS,CAAC,IAAI,CAAA;AACzE,QAAA,OAAO,gBAAgB,CAAC,IAAI,EAAE,GAAG,UAAU,CAAC,CAAA;KAC7C;IAED,kBAAkB,GAAA;AAChB,QAAA,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAA;QAClC,OAAO,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;KAC3C;AAED,IAAA,cAAc,CAAE,kBAA2B,EAAA;QACzC,OAAO,IAAI,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,mBAAmB,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAA;KACpG;IAED,cAAc,GAAA;QACZ,OAAO,IAAI,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,kBAAkB,EAAE,GAAG,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAA;KACvF;;AArRM,UAAS,CAAA,SAAA,GAAGC,KAAC;;;;"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/components/stacked-bar/index.ts"],"sourcesContent":["import { min, max } from 'd3-array'\n\n// Core\nimport { XYComponentCore } from 'core/xy-component'\n\n// Utils\nimport { isNumber, isArray, isEmpty, clamp, getStackedExtent, getString, getNumber, getStackedData, getExtent } from 'utils/data'\nimport { roundedRectPath } from 'utils/path'\nimport { smartTransition } from 'utils/d3'\nimport { getColor } from 'utils/color'\n\n// Types\nimport { ContinuousScale } from 'types/scale'\nimport { NumericAccessor } from 'types/accessor'\nimport { Spacing } from 'types/spacing'\nimport { Orientation } from 'types/position'\n\n// Local Types\nimport { StackedBarDataRecord } from './types'\n\n// Config\nimport { StackedBarDefaultConfig, StackedBarConfigInterface } from './config'\n\n// Styles\nimport * as s from './style'\n\nexport class StackedBar<Datum> extends XYComponentCore<Datum, StackedBarConfigInterface<Datum>> {\n static selectors = s\n protected _defaultConfig = StackedBarDefaultConfig as StackedBarConfigInterface<Datum>\n public config: StackedBarConfigInterface<Datum> = this._defaultConfig\n\n getAccessors = (): NumericAccessor<Datum>[] => (isArray(this.config.y) ? this.config.y : [this.config.y])\n stacked = true\n events = {}\n private _prevNegative: boolean[] | undefined // To help guessing the bar direction when an accessor was set to null or 0\n private _barData: Datum[] = []\n\n constructor (config?: StackedBarConfigInterface<Datum>) {\n super()\n if (config) this.setConfig(config)\n }\n\n get bleed (): Spacing {\n this._barData = this._getVisibleData()\n if (this._barData.length === 0) return { top: 0, bottom: 0, left: 0, right: 0 }\n\n // By default, horizontal orientation is \"flipped\", i.e. the `yDirection` of `XYContainer` is set to `Direction.North`\n const isHorizontalAndFlipped = !this.isVertical() && (this.dataScale.range()[0] > this.dataScale.range()[1])\n const dataDomain = this.dataScale.domain()\n const halfGroupWidth = this._getBarWidth() / 2\n\n const dataScaleValues = this._barData.map((d, i) => getNumber(d, this.config.x, i))\n const firstDataValue = min(dataScaleValues)\n const lastDataValue = max(dataScaleValues)\n const firstValuePx = this.dataScale(firstDataValue)\n const lastValuePx = this.dataScale(lastDataValue)\n\n const dataDomainRequiredStart = this.dataScale.invert(firstValuePx + (isHorizontalAndFlipped ? halfGroupWidth : -halfGroupWidth))\n const dataDomainRequiredEnd = this.dataScale.invert(lastValuePx + (isHorizontalAndFlipped ? -halfGroupWidth : halfGroupWidth))\n const bleedPxStart = dataDomainRequiredStart <= dataDomain[0] ? this.dataScale(dataDomain[0]) - this.dataScale(dataDomainRequiredStart) : 0\n const bleedPxEnd = dataDomainRequiredEnd > dataDomain[1] ? this.dataScale(dataDomainRequiredEnd) - this.dataScale(dataDomain[1]) : 0\n\n return {\n top: this.isVertical() ? 0 : (isHorizontalAndFlipped ? -bleedPxEnd : bleedPxStart),\n bottom: this.isVertical() ? 0 : (isHorizontalAndFlipped ? -bleedPxStart : bleedPxEnd),\n left: this.isVertical() ? bleedPxStart : 0,\n right: this.isVertical() ? bleedPxEnd : 0,\n }\n }\n\n private get dataScale (): ContinuousScale {\n return this.isVertical() ? this.xScale : this.yScale\n }\n\n private get valueScale (): ContinuousScale {\n return this.isVertical() ? this.yScale : this.xScale\n }\n\n private isVertical (): boolean {\n return this.config.orientation === Orientation.Vertical\n }\n\n _render (customDuration?: number): void {\n const { config } = this\n const duration = isNumber(customDuration) ? customDuration : config.duration\n\n const yAccessors = this.getAccessors()\n const stacked = getStackedData(this._barData, 0, yAccessors, this._prevNegative)\n this._prevNegative = stacked.map(s => !!s.isMostlyNegative)\n\n const barGroups = this.g\n .selectAll<SVGGElement, Datum>(`.${s.barGroup}`)\n .data(this._barData, (d, i) => `${getString(d, config.id, i) ?? i}`)\n\n const getBarGroupsTransform = (d: Datum, i: number): string => {\n const v = this.dataScale(getNumber(d, config.x, i))\n const x = this.isVertical() ? v : 0\n const y = this.isVertical() ? 0 : v\n return `translate(${x},${y})`\n }\n\n const barGroupsEnter = barGroups.enter().append('g')\n .attr('class', s.barGroup)\n .attr('transform', getBarGroupsTransform)\n .style('opacity', 1)\n\n const barGroupsMerged = barGroupsEnter.merge(barGroups)\n smartTransition(barGroupsMerged, duration)\n .attr('transform', getBarGroupsTransform)\n .style('opacity', 1)\n\n const barGroupExit = barGroups.exit()\n .attr('class', s.barGroupExit)\n\n smartTransition(barGroupExit, duration)\n .style('opacity', 0)\n .remove()\n // `transition.remove()` only fires on `end`; if the transition is interrupted by a re-render,\n // the node would linger in the DOM with opacity < 1 and could be picked up by the next data join.\n .on('interrupt', function () { this.remove() })\n\n // Animate bars from exiting groups going down\n smartTransition(barGroupExit.selectAll(`.${s.bar}`), duration)\n .attr('transform', this.isVertical()\n ? `translate(0,${this._height / 3})`\n : `translate(${this._width / 6},0)`\n )\n\n // Render Bars\n const bars = barGroupsMerged\n .selectAll<SVGPathElement, StackedBarDataRecord<Datum>>(`.${s.bar}`)\n .data(\n (d, j) => {\n type StackedBarRenderDatum = {\n datum: Datum;\n index: number;\n stacked: [number, number];\n stackIndex: number;\n isEnding: boolean;\n }\n\n const groupData = stacked\n .map((s, i) => ({\n datum: d,\n index: j,\n stacked: s[j],\n stackIndex: i,\n }))\n .filter(d => d.stacked[0] !== d.stacked[1]) as StackedBarRenderDatum[] // Skip zero-height bars\n\n // Populate `isEnding`\n // Ending bar if the next stack is not the same as the current one\n groupData.forEach((d, i) => {\n d.isEnding = (i === groupData.length - 1) ||\n ((i <= groupData.length - 1) && groupData[i + 1].stacked[0] !== d.stacked[1])\n })\n return groupData\n },\n d => d.stackIndex // Key function for proper transitions\n )\n\n const barsEnter = bars.enter().append('path')\n .attr('class', s.bar)\n .attr('d', d => this._getBarPath(d, true))\n .style('fill', d => getColor(d.datum, config.color, d.stackIndex))\n\n const barsMerged = barsEnter.merge(bars)\n\n smartTransition(barsMerged, duration)\n .attr('d', d => this._getBarPath(d))\n .style('fill', d => getColor(d.datum, config.color, d.stackIndex))\n .style('cursor', d => getString(d.datum, config.cursor, d.stackIndex))\n\n smartTransition(bars.exit(), duration)\n .style('opacity', 0)\n .remove()\n // `transition.remove()` only fires on `end`; if the transition is interrupted by a re-render,\n // the node would linger in the DOM with opacity < 1 and could be picked up by the next data join.\n .on('interrupt', function () { this.remove() })\n }\n\n _getBarWidth (): number {\n const { config, datamodel: { data } } = this\n if (isEmpty(data)) return 0\n if (config.barWidth) return min([config.barWidth, config.barMaxWidth])\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const isOrdinal = this.dataScale.bandwidth\n const domain = (this.dataScale.domain ? this.dataScale.domain() : []) as number[]\n const domainLength = isOrdinal ? domain.length : domain[1] - domain[0]\n\n // If the dataStep property is provided the amount of data elements is calculates as domainLength / dataStep\n // otherwise we get the number of data elements within the domain range\n // Or if the scale is ordinal we use data.length\n let dataSize = (1 + domainLength / config.dataStep) ||\n (!isOrdinal && data.filter((d, i) => {\n const value = getNumber(d, config.x, i)\n return (value >= domain[0]) && (value <= domain[1])\n }).length) ||\n data.length\n\n // We increase the dataSize by 1 to take into account possible additional domain space\n if (!isOrdinal && dataSize >= 2) dataSize += 1\n\n const c = dataSize < 2 ? 1 : 1 - config.barPadding\n const barWidth = c * (this.isVertical() ? this._width : this._height) / dataSize\n\n return min([barWidth, config.barMaxWidth])\n }\n\n _getVisibleData (): Datum[] {\n const { config, datamodel: { data } } = this\n\n const groupWidth = this._getBarWidth()\n const halfGroupWidthPx = data.length < 2 ? 0 : groupWidth / 2\n\n const scale = this.dataScale\n const halfGroupWidth = Math.abs((scale.invert(halfGroupWidthPx) as number) - (scale.invert(0) as number))\n const filtered = data?.filter((d, i) => {\n const v = getNumber(d, config.x, i)\n const domain: number[] | Date[] = scale.domain()\n const domainMin = +domain[0]\n const domainMax = +domain[1]\n return (v >= (domainMin - halfGroupWidth)) && (v <= (domainMax + halfGroupWidth))\n })\n\n return filtered\n }\n\n _getBarPath (d: StackedBarDataRecord<Datum>, isEntering = false): string {\n const { config } = this\n const yAccessors = this.getAccessors()\n const barWidth = this._getBarWidth()\n\n const isNegative = d.stacked[1] < 0\n const isEnding = d.isEnding // The most top bar or, if the value is negative, the most bottom bar\n const value = getNumber(d.datum, yAccessors[d.stackIndex], d.index)\n const height = isEntering ? 0 : Math.abs(this.valueScale(d.stacked[0]) - this.valueScale(d.stacked[1]))\n const h = !isEntering && config.barMinHeight1Px && (height < 1) && isFinite(value) && (value !== config.barMinHeightZeroValue) ? 1 : height\n const y = isEntering\n ? this.valueScale(0)\n : this.valueScale(isNegative ? d.stacked[0] : d.stacked[1]) - (height < 1 && config.barMinHeight1Px ? 1 : 0)\n\n const x = -barWidth / 2\n const width = barWidth\n\n const cornerRadius = config.roundedCorners\n ? isNumber(config.roundedCorners) ? +config.roundedCorners : width / 2\n : 0\n const cornerRadiusClamped = clamp(cornerRadius, 0, Math.min(height, width) / 2)\n const isNorthDirected = this.yScale.range()[0] > this.yScale.range()[1]\n\n return roundedRectPath({\n x: this.isVertical() ? x : y - h,\n y: this.isVertical() ? y + (isNorthDirected ? 0 : -h) : x,\n w: this.isVertical() ? width : h,\n h: this.isVertical() ? h : width,\n tl: isEnding && (this.isVertical()\n ? (!isNegative && isNorthDirected) || (isNegative && !isNorthDirected)\n : isNegative\n ),\n tr: isEnding && (this.isVertical()\n ? (!isNegative && isNorthDirected) || (isNegative && !isNorthDirected)\n : !isNegative\n ),\n br: isEnding && (this.isVertical()\n ? (isNegative && isNorthDirected) || (!isNegative && !isNorthDirected)\n : !isNegative\n ),\n bl: isEnding && (this.isVertical()\n ? (isNegative && isNorthDirected) || (!isNegative && !isNorthDirected)\n : isNegative\n ),\n r: cornerRadiusClamped,\n })\n }\n\n // After performance optimizations in https://github.com/f5/unovis/pull/708\n // there's a breaking change in the event data structure: the d3 datum bound\n // to each bar is now a `StackedBarDataRecord` wrapper, and the DOM-derived\n // index no longer matches the original row index (zero-height segments are\n // filtered out, and bars from all groups share the same selection).\n // This method maps both back to the pre-#708 contract.\n // Todo: This can be removed in Unovis 2.0, but the migration guide should contain a note about it.\n protected _mapEventDatum (d: StackedBarDataRecord<Datum>): { datum: Datum; index: number } {\n return {\n datum: { ...d, ...d.datum },\n index: d.index,\n }\n }\n\n getValueScaleExtent (scaleByVisibleData: boolean): number[] {\n const { datamodel } = this\n const yAccessors = this.getAccessors()\n\n const data = scaleByVisibleData ? this._getVisibleData() : datamodel.data\n return getStackedExtent(data, ...yAccessors)\n }\n\n getDataScaleExtent (): number[] {\n const { config, datamodel } = this\n return getExtent(datamodel.data, config.x)\n }\n\n getYDataExtent (scaleByVisibleData: boolean): number[] {\n return this.isVertical() ? this.getValueScaleExtent(scaleByVisibleData) : this.getDataScaleExtent()\n }\n\n getXDataExtent (): number[] {\n return this.isVertical() ? this.getDataScaleExtent() : this.getValueScaleExtent(false)\n }\n}\n"],"names":["s.barGroup","barGroupExit","s.barGroupExit","s.bar","s"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { XYComponentConfigInterface } from "../../core/xy-component/config";
|
|
2
2
|
import { WithOptional } from "../../types/misc";
|
|
3
3
|
import { ColorAccessor, NumericAccessor, StringAccessor, GenericAccessor } from "../../types/accessor";
|
|
4
|
-
import { TextAlign } from "../../types/text";
|
|
4
|
+
import { TextAlign, TrimMode } from "../../types/text";
|
|
5
5
|
import { Arrangement } from "../../types/position";
|
|
6
6
|
import type { TimelineArrow, TimelineLineRenderState, TimelineRowIcon, TimelineRowLabel } from './types';
|
|
7
7
|
export interface TimelineConfigInterface<Datum> extends WithOptional<XYComponentConfigInterface<Datum>, 'y'> {
|
|
@@ -74,6 +74,12 @@ export interface TimelineConfigInterface<Datum> extends WithOptional<XYComponent
|
|
|
74
74
|
rowMaxLabelWidth?: number;
|
|
75
75
|
/** Text alignment for labels: `TextAlign.Left`, `TextAlign.Center` or `TextAlign.Right`. Default: `TextAlign.Right` */
|
|
76
76
|
rowLabelTextAlign?: TextAlign | `${TextAlign}`;
|
|
77
|
+
/** Row label trim mode when width is limited: `TrimMode.Start`, `TrimMode.Middle` or `TrimMode.End`. Default: `TrimMode.Middle` */
|
|
78
|
+
rowLabelTrimMode?: TrimMode | `${TrimMode}`;
|
|
79
|
+
/** Row label margin in pixels. Can be a single number or a `[left, right]` tuple. Default: `[0, 5]` */
|
|
80
|
+
rowLabelMargin?: number | [number, number];
|
|
81
|
+
/** When component height is larger than the height of all rows, render rows to fill empty space */
|
|
82
|
+
rowFillEmptySpace?: boolean;
|
|
77
83
|
arrows?: TimelineArrow[];
|
|
78
84
|
/** Control the animation by specify the initial position for new lines as [x, y]. Default: `undefined` */
|
|
79
85
|
animationLineEnterPosition?: [
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { XYComponentDefaultConfig } from '../../core/xy-component/config.js';
|
|
2
|
-
import { TextAlign } from '../../types/text.js';
|
|
2
|
+
import { TextAlign, TrimMode } from '../../types/text.js';
|
|
3
3
|
import { Arrangement } from '../../types/position.js';
|
|
4
4
|
|
|
5
5
|
const TimelineDefaultConfig = Object.assign(Object.assign({}, XYComponentDefaultConfig), { id: undefined,
|
|
@@ -8,7 +8,7 @@ const TimelineDefaultConfig = Object.assign(Object.assign({}, XYComponentDefault
|
|
|
8
8
|
// Rows
|
|
9
9
|
rowHeight: 22, alternatingRowColors: true,
|
|
10
10
|
// Row Labels
|
|
11
|
-
showLabels: false, labelWidth: undefined, maxLabelWidth: 120, showRowLabels: undefined, rowLabelFormatter: undefined, rowIcon: undefined, rowLabelStyle: undefined, rowLabelWidth: undefined, rowMaxLabelWidth: undefined, rowLabelTextAlign: TextAlign.Right,
|
|
11
|
+
showLabels: false, labelWidth: undefined, maxLabelWidth: 120, showRowLabels: undefined, rowLabelFormatter: undefined, rowIcon: undefined, rowLabelStyle: undefined, rowLabelWidth: undefined, rowMaxLabelWidth: undefined, rowLabelTextAlign: TextAlign.Right, rowLabelTrimMode: TrimMode.Middle, rowLabelMargin: [0, 6], rowFillEmptySpace: true,
|
|
12
12
|
// Arrows
|
|
13
13
|
arrows: undefined,
|
|
14
14
|
// Animation
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sources":["../../../src/components/timeline/config.ts"],"sourcesContent":["import { XYComponentConfigInterface, XYComponentDefaultConfig } from 'core/xy-component/config'\n\n// Types\nimport { WithOptional } from 'types/misc'\nimport { ColorAccessor, NumericAccessor, StringAccessor, GenericAccessor } from 'types/accessor'\nimport { TextAlign } from 'types/text'\nimport { Arrangement } from 'types/position'\n\n// Local Types\nimport type { TimelineArrow, TimelineLineRenderState, TimelineRowIcon, TimelineRowLabel } from './types'\n\nexport interface TimelineConfigInterface<Datum> extends WithOptional<XYComponentConfigInterface<Datum>, 'y'> {\n // Items (Lines)\n /** @deprecated This property has been renamed to `key` */\n type?: StringAccessor<Datum>;\n /** @deprecated This property has been renamed to `lineDuration` */\n length?: NumericAccessor<Datum>;\n /** @deprecated This property has been renamed to `lineCursor` */\n cursor?: StringAccessor<Datum>;\n /** Timeline item row accessor function. Records with the `lineRow` will be plotted in one row. Default: `undefined` */\n lineRow?: StringAccessor<Datum>;\n /** Timeline item duration accessor function. Default: `undefined`. Falls back to the deprecated `length` property */\n lineDuration?: NumericAccessor<Datum>;\n /** Timeline item color accessor function. Default: `d => d.color` */\n color?: ColorAccessor<Datum>;\n /** Width of the timeline items. Default: `8` */\n lineWidth?: NumericAccessor<Datum>;\n /** Display rounded ends for timeline items. Default: `true` */\n lineCap?: boolean;\n /** Provide a href to an SVG defined in container's `svgDefs` to display an icon at the start of the line. Default: undefined */\n lineStartIcon?: StringAccessor<Datum>;\n /** Line start icon color accessor function. Default: `undefined` */\n lineStartIconColor?: StringAccessor<Datum>;\n /** Line start icon size accessor function. Default: `undefined` */\n lineStartIconSize?: NumericAccessor<Datum>;\n /** Line start icon arrangement configuration. Controls how the icon is positioned relative to the line.\n * Accepts values from the Arrangement enum: `Arrangement.Start`, `Arrangement.Middle`, `Arrangement.End` or a string equivalent.\n * Default: `Arrangement.Inside` */\n lineStartIconArrangement?: GenericAccessor<Arrangement | `${Arrangement}`, Datum>;\n /** Provide a href to an SVG defined in container's `svgDefs` to display an icon at the end of the line. Default: undefined */\n lineEndIcon?: StringAccessor<Datum>;\n /** Line end icon color accessor function. Default: `undefined` */\n lineEndIconColor?: StringAccessor<Datum>;\n /** Line end icon size accessor function. Default: `undefined` */\n lineEndIconSize?: NumericAccessor<Datum>;\n /** Line end icon arrangement configuration. Controls how the icon is positioned relative to the line.\n * Accepts values from the Arrangement enum: `Arrangement.Start`, `Arrangement.Middle`, `Arrangement.End` or a string equivalent.\n * Default: `Arrangement.Inside` */\n lineEndIconArrangement?: GenericAccessor<Arrangement | `${Arrangement}`, Datum>;\n /** Configurable Timeline item cursor when hovering over. Default: `undefined` */\n lineCursor?: StringAccessor<Datum>;\n /** Sets the minimum line length to 1 pixel for better visibility of small values.\n * When `lineCap` is set to `true`, the segment will be rendered as a circle.\n * Default: `false` */\n showEmptySegments?: boolean;\n /** Center small segments when `showEmptySegments` and `lineCap` are set to `true`.\n * Default: `true` */\n showEmptySegmentsCorrectPosition?: boolean;\n\n /** Timeline row height. Default: `22` */\n rowHeight?: number;\n /** Alternating row colors. Default: `true` */\n alternatingRowColors?: boolean;\n\n // Row Labels\n /** @deprecated This property has been renamed to `showRowLabels */\n showLabels?: boolean;\n /** @deprecated This property has been renamed to `rowLabelWidth */\n labelWidth?: number;\n /** @deprecated This property has been renamed to `rowMaxLabelWidth */\n maxLabelWidth?: number;\n\n /** Show row labels when set to `true`. Default: `false`. Falls back to deprecated `showLabels` */\n showRowLabels?: boolean;\n /** Row label style as an object with the `{ [property-name]: value }` format. Default: `undefined` */\n rowLabelStyle?: GenericAccessor<Record<string, string>, TimelineRowLabel<Datum>>;\n /** Row label formatter function. Default: `undefined` */\n rowLabelFormatter?: (key: string, items: Datum[], i: number) => string;\n /** Provide an icon href to be displayed before the row label. Default: `undefined` */\n rowIcon?: (key: string, items: Datum[], i: number) => TimelineRowIcon | undefined;\n /** Fixed label width in pixels. Labels longer than the specified value will be trimmed. Default: `undefined`. Falls back to deprecated `labelWidth`. */\n rowLabelWidth?: number;\n /** Maximum label width in pixels. Labels longer than the specified value will be trimmed. Default: `undefined`. Falls back to deprecated `maxLabelWidth`. */\n rowMaxLabelWidth?: number;\n /** Text alignment for labels: `TextAlign.Left`, `TextAlign.Center` or `TextAlign.Right`. Default: `TextAlign.Right` */\n rowLabelTextAlign?: TextAlign | `${TextAlign}`;\n\n // Arrows\n arrows?: TimelineArrow[];\n\n // Animation\n /** Control the animation by specify the initial position for new lines as [x, y]. Default: `undefined` */\n animationLineEnterPosition?:\n [number | undefined | null, number | undefined | null] |\n ((d: Datum & TimelineLineRenderState, i: number, data: (Datum & TimelineLineRenderState)[]) => [number | undefined, number | undefined]) |\n undefined;\n /** Control the animation by specify the destination position for exiting lines as [x, y]. Default: `undefined` */\n animationLineExitPosition?: [number | undefined | null, number | undefined | null] |\n ((d: Datum & TimelineLineRenderState, i: number, data: (Datum & TimelineLineRenderState)[]) => [number | undefined, number | undefined]) |\n undefined;\n\n // Callbacks\n /** Scrolling callback function: `(scrollTop: number) => void`. Default: `undefined` */\n onScroll?: (scrollTop: number) => void;\n}\n\nexport const TimelineDefaultConfig: TimelineConfigInterface<unknown> = {\n ...XYComponentDefaultConfig,\n id: undefined,\n\n // Items (Lines)\n cursor: undefined, // Deprecated (see above)\n type: (d: unknown): string => (d as { type: string }).type, // Deprecated (see above)\n length: (d: unknown): number => (d as { length: number }).length, // Deprecated (see above)\n color: (d: unknown): string => (d as { color: string }).color,\n lineRow: undefined,\n lineDuration: undefined,\n lineWidth: 8,\n lineCap: false,\n lineCursor: undefined,\n showEmptySegments: false,\n showEmptySegmentsCorrectPosition: true,\n lineStartIcon: undefined,\n lineStartIconColor: undefined,\n lineStartIconSize: undefined,\n lineStartIconArrangement: Arrangement.Inside,\n lineEndIcon: undefined,\n lineEndIconColor: undefined,\n lineEndIconSize: undefined,\n lineEndIconArrangement: Arrangement.Inside,\n\n // Rows\n rowHeight: 22,\n alternatingRowColors: true,\n\n // Row Labels\n showLabels: false, // Deprecated (see above)\n labelWidth: undefined, // Deprecated (see above)\n maxLabelWidth: 120, // Deprecated (see above)\n\n showRowLabels: undefined,\n rowLabelFormatter: undefined,\n rowIcon: undefined,\n rowLabelStyle: undefined,\n rowLabelWidth: undefined,\n rowMaxLabelWidth: undefined,\n rowLabelTextAlign: TextAlign.Right,\n\n // Arrows\n arrows: undefined,\n\n // Animation\n animationLineEnterPosition: undefined,\n\n // Callbacks\n onScroll: undefined,\n}\n"],"names":[],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"config.js","sources":["../../../src/components/timeline/config.ts"],"sourcesContent":["import { XYComponentConfigInterface, XYComponentDefaultConfig } from 'core/xy-component/config'\n\n// Types\nimport { WithOptional } from 'types/misc'\nimport { ColorAccessor, NumericAccessor, StringAccessor, GenericAccessor } from 'types/accessor'\nimport { TextAlign, TrimMode } from 'types/text'\nimport { Arrangement } from 'types/position'\n\n// Local Types\nimport type { TimelineArrow, TimelineLineRenderState, TimelineRowIcon, TimelineRowLabel } from './types'\n\nexport interface TimelineConfigInterface<Datum> extends WithOptional<XYComponentConfigInterface<Datum>, 'y'> {\n // Items (Lines)\n /** @deprecated This property has been renamed to `key` */\n type?: StringAccessor<Datum>;\n /** @deprecated This property has been renamed to `lineDuration` */\n length?: NumericAccessor<Datum>;\n /** @deprecated This property has been renamed to `lineCursor` */\n cursor?: StringAccessor<Datum>;\n /** Timeline item row accessor function. Records with the `lineRow` will be plotted in one row. Default: `undefined` */\n lineRow?: StringAccessor<Datum>;\n /** Timeline item duration accessor function. Default: `undefined`. Falls back to the deprecated `length` property */\n lineDuration?: NumericAccessor<Datum>;\n /** Timeline item color accessor function. Default: `d => d.color` */\n color?: ColorAccessor<Datum>;\n /** Width of the timeline items. Default: `8` */\n lineWidth?: NumericAccessor<Datum>;\n /** Display rounded ends for timeline items. Default: `true` */\n lineCap?: boolean;\n /** Provide a href to an SVG defined in container's `svgDefs` to display an icon at the start of the line. Default: undefined */\n lineStartIcon?: StringAccessor<Datum>;\n /** Line start icon color accessor function. Default: `undefined` */\n lineStartIconColor?: StringAccessor<Datum>;\n /** Line start icon size accessor function. Default: `undefined` */\n lineStartIconSize?: NumericAccessor<Datum>;\n /** Line start icon arrangement configuration. Controls how the icon is positioned relative to the line.\n * Accepts values from the Arrangement enum: `Arrangement.Start`, `Arrangement.Middle`, `Arrangement.End` or a string equivalent.\n * Default: `Arrangement.Inside` */\n lineStartIconArrangement?: GenericAccessor<Arrangement | `${Arrangement}`, Datum>;\n /** Provide a href to an SVG defined in container's `svgDefs` to display an icon at the end of the line. Default: undefined */\n lineEndIcon?: StringAccessor<Datum>;\n /** Line end icon color accessor function. Default: `undefined` */\n lineEndIconColor?: StringAccessor<Datum>;\n /** Line end icon size accessor function. Default: `undefined` */\n lineEndIconSize?: NumericAccessor<Datum>;\n /** Line end icon arrangement configuration. Controls how the icon is positioned relative to the line.\n * Accepts values from the Arrangement enum: `Arrangement.Start`, `Arrangement.Middle`, `Arrangement.End` or a string equivalent.\n * Default: `Arrangement.Inside` */\n lineEndIconArrangement?: GenericAccessor<Arrangement | `${Arrangement}`, Datum>;\n /** Configurable Timeline item cursor when hovering over. Default: `undefined` */\n lineCursor?: StringAccessor<Datum>;\n /** Sets the minimum line length to 1 pixel for better visibility of small values.\n * When `lineCap` is set to `true`, the segment will be rendered as a circle.\n * Default: `false` */\n showEmptySegments?: boolean;\n /** Center small segments when `showEmptySegments` and `lineCap` are set to `true`.\n * Default: `true` */\n showEmptySegmentsCorrectPosition?: boolean;\n\n /** Timeline row height. Default: `22` */\n rowHeight?: number;\n /** Alternating row colors. Default: `true` */\n alternatingRowColors?: boolean;\n\n // Row Labels\n /** @deprecated This property has been renamed to `showRowLabels */\n showLabels?: boolean;\n /** @deprecated This property has been renamed to `rowLabelWidth */\n labelWidth?: number;\n /** @deprecated This property has been renamed to `rowMaxLabelWidth */\n maxLabelWidth?: number;\n\n /** Show row labels when set to `true`. Default: `false`. Falls back to deprecated `showLabels` */\n showRowLabels?: boolean;\n /** Row label style as an object with the `{ [property-name]: value }` format. Default: `undefined` */\n rowLabelStyle?: GenericAccessor<Record<string, string>, TimelineRowLabel<Datum>>;\n /** Row label formatter function. Default: `undefined` */\n rowLabelFormatter?: (key: string, items: Datum[], i: number) => string;\n /** Provide an icon href to be displayed before the row label. Default: `undefined` */\n rowIcon?: (key: string, items: Datum[], i: number) => TimelineRowIcon | undefined;\n /** Fixed label width in pixels. Labels longer than the specified value will be trimmed. Default: `undefined`. Falls back to deprecated `labelWidth`. */\n rowLabelWidth?: number;\n /** Maximum label width in pixels. Labels longer than the specified value will be trimmed. Default: `undefined`. Falls back to deprecated `maxLabelWidth`. */\n rowMaxLabelWidth?: number;\n /** Text alignment for labels: `TextAlign.Left`, `TextAlign.Center` or `TextAlign.Right`. Default: `TextAlign.Right` */\n rowLabelTextAlign?: TextAlign | `${TextAlign}`;\n /** Row label trim mode when width is limited: `TrimMode.Start`, `TrimMode.Middle` or `TrimMode.End`. Default: `TrimMode.Middle` */\n rowLabelTrimMode?: TrimMode | `${TrimMode}`;\n /** Row label margin in pixels. Can be a single number or a `[left, right]` tuple. Default: `[0, 5]` */\n rowLabelMargin?: number | [number, number];\n /** When component height is larger than the height of all rows, render rows to fill empty space */\n rowFillEmptySpace?: boolean;\n\n // Arrows\n arrows?: TimelineArrow[];\n\n // Animation\n /** Control the animation by specify the initial position for new lines as [x, y]. Default: `undefined` */\n animationLineEnterPosition?:\n [number | undefined | null, number | undefined | null] |\n ((d: Datum & TimelineLineRenderState, i: number, data: (Datum & TimelineLineRenderState)[]) => [number | undefined, number | undefined]) |\n undefined;\n /** Control the animation by specify the destination position for exiting lines as [x, y]. Default: `undefined` */\n animationLineExitPosition?: [number | undefined | null, number | undefined | null] |\n ((d: Datum & TimelineLineRenderState, i: number, data: (Datum & TimelineLineRenderState)[]) => [number | undefined, number | undefined]) |\n undefined;\n\n // Callbacks\n /** Scrolling callback function: `(scrollTop: number) => void`. Default: `undefined` */\n onScroll?: (scrollTop: number) => void;\n}\n\nexport const TimelineDefaultConfig: TimelineConfigInterface<unknown> = {\n ...XYComponentDefaultConfig,\n id: undefined,\n\n // Items (Lines)\n cursor: undefined, // Deprecated (see above)\n type: (d: unknown): string => (d as { type: string }).type, // Deprecated (see above)\n length: (d: unknown): number => (d as { length: number }).length, // Deprecated (see above)\n color: (d: unknown): string => (d as { color: string }).color,\n lineRow: undefined,\n lineDuration: undefined,\n lineWidth: 8,\n lineCap: false,\n lineCursor: undefined,\n showEmptySegments: false,\n showEmptySegmentsCorrectPosition: true,\n lineStartIcon: undefined,\n lineStartIconColor: undefined,\n lineStartIconSize: undefined,\n lineStartIconArrangement: Arrangement.Inside,\n lineEndIcon: undefined,\n lineEndIconColor: undefined,\n lineEndIconSize: undefined,\n lineEndIconArrangement: Arrangement.Inside,\n\n // Rows\n rowHeight: 22,\n alternatingRowColors: true,\n\n // Row Labels\n showLabels: false, // Deprecated (see above)\n labelWidth: undefined, // Deprecated (see above)\n maxLabelWidth: 120, // Deprecated (see above)\n\n showRowLabels: undefined,\n rowLabelFormatter: undefined,\n rowIcon: undefined,\n rowLabelStyle: undefined,\n rowLabelWidth: undefined,\n rowMaxLabelWidth: undefined,\n rowLabelTextAlign: TextAlign.Right,\n rowLabelTrimMode: TrimMode.Middle,\n rowLabelMargin: [0, 6],\n rowFillEmptySpace: true,\n\n // Arrows\n arrows: undefined,\n\n // Animation\n animationLineEnterPosition: undefined,\n\n // Callbacks\n onScroll: undefined,\n}\n"],"names":[],"mappings":";;;;MAgHa,qBAAqB,GAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,EAAA,EAC7B,wBAAwB,CAC3B,EAAA,EAAA,EAAE,EAAE,SAAS;;IAGb,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,CAAC,CAAU,KAAc,CAAsB,CAAC,IAAI,EAC1D,MAAM,EAAE,CAAC,CAAU,KAAc,CAAwB,CAAC,MAAM,EAChE,KAAK,EAAE,CAAC,CAAU,KAAc,CAAuB,CAAC,KAAK,EAC7D,OAAO,EAAE,SAAS,EAClB,YAAY,EAAE,SAAS,EACvB,SAAS,EAAE,CAAC,EACZ,OAAO,EAAE,KAAK,EACd,UAAU,EAAE,SAAS,EACrB,iBAAiB,EAAE,KAAK,EACxB,gCAAgC,EAAE,IAAI,EACtC,aAAa,EAAE,SAAS,EACxB,kBAAkB,EAAE,SAAS,EAC7B,iBAAiB,EAAE,SAAS,EAC5B,wBAAwB,EAAE,WAAW,CAAC,MAAM,EAC5C,WAAW,EAAE,SAAS,EACtB,gBAAgB,EAAE,SAAS,EAC3B,eAAe,EAAE,SAAS,EAC1B,sBAAsB,EAAE,WAAW,CAAC,MAAM;;AAG1C,IAAA,SAAS,EAAE,EAAE,EACb,oBAAoB,EAAE,IAAI;;IAG1B,UAAU,EAAE,KAAK,EACjB,UAAU,EAAE,SAAS,EACrB,aAAa,EAAE,GAAG,EAElB,aAAa,EAAE,SAAS,EACxB,iBAAiB,EAAE,SAAS,EAC5B,OAAO,EAAE,SAAS,EAClB,aAAa,EAAE,SAAS,EACxB,aAAa,EAAE,SAAS,EACxB,gBAAgB,EAAE,SAAS,EAC3B,iBAAiB,EAAE,SAAS,CAAC,KAAK,EAClC,gBAAgB,EAAE,QAAQ,CAAC,MAAM,EACjC,cAAc,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EACtB,iBAAiB,EAAE,IAAI;;AAGvB,IAAA,MAAM,EAAE,SAAS;;AAGjB,IAAA,0BAA0B,EAAE,SAAS;;IAGrC,QAAQ,EAAE,SAAS,EAAA;;;;"}
|
|
@@ -25,9 +25,8 @@ export declare class Timeline<Datum> extends XYComponentCore<Datum, TimelineConf
|
|
|
25
25
|
private _scrollBarMargin;
|
|
26
26
|
private _maxScroll;
|
|
27
27
|
private _scrollbarHeight;
|
|
28
|
-
private _labelMargin;
|
|
29
28
|
private _labelWidth;
|
|
30
|
-
private
|
|
29
|
+
private _lineIconBleed;
|
|
31
30
|
private _lineBleed;
|
|
32
31
|
/** We define a dedicated clipping path for this component because it needs to behave
|
|
33
32
|
* differently than the regular XYContainer's clipPath */
|
|
@@ -38,6 +37,7 @@ export declare class Timeline<Datum> extends XYComponentCore<Datum, TimelineConf
|
|
|
38
37
|
setData(data: Datum[]): void;
|
|
39
38
|
get bleed(): Spacing;
|
|
40
39
|
_render(customDuration?: number): void;
|
|
40
|
+
private _getRowLabelMargin;
|
|
41
41
|
private _getLineLength;
|
|
42
42
|
private _getLineWidth;
|
|
43
43
|
private _getLineDuration;
|
|
@@ -12,7 +12,7 @@ import { guid } from '../../utils/misc.js';
|
|
|
12
12
|
import '../../types.js';
|
|
13
13
|
import { TimelineDefaultConfig } from './config.js';
|
|
14
14
|
import * as style from './style.js';
|
|
15
|
-
import { background, rows, arrows, lines, labels, rowIcons, scrollbar, scrollbarBackground, scrollbarHandle, label, rowIcon, row, rowOdd, lineGroup, line, lineStartIcon, lineEndIcon, arrow } from './style.js';
|
|
15
|
+
import { background, rows, arrows, lines, labels, rowIcons, scrollbar, scrollbarBackground, scrollbarHandle, label, rowIcon, labelBackground, row, rowOdd, lineGroup, line, lineStartIcon, lineEndIcon, arrow } from './style.js';
|
|
16
16
|
import { TIMELINE_DEFAULT_ARROW_HEAD_LENGTH, TIMELINE_DEFAULT_ARROW_HEAD_WIDTH, TIMELINE_DEFAULT_ARROW_MARGIN } from './constants.js';
|
|
17
17
|
import { getIconBleed } from './utils.js';
|
|
18
18
|
import { TextAlign } from '../../types/text.js';
|
|
@@ -30,6 +30,9 @@ class Timeline extends XYComponentCore {
|
|
|
30
30
|
[Timeline.selectors.label]: {
|
|
31
31
|
wheel: this._onMouseWheel.bind(this),
|
|
32
32
|
},
|
|
33
|
+
[Timeline.selectors.labelBackground]: {
|
|
34
|
+
wheel: this._onMouseWheel.bind(this),
|
|
35
|
+
},
|
|
33
36
|
[Timeline.selectors.rows]: {
|
|
34
37
|
wheel: this._onMouseWheel.bind(this),
|
|
35
38
|
},
|
|
@@ -42,9 +45,8 @@ class Timeline extends XYComponentCore {
|
|
|
42
45
|
this._scrollBarMargin = 5;
|
|
43
46
|
this._maxScroll = 0;
|
|
44
47
|
this._scrollbarHeight = 0;
|
|
45
|
-
this._labelMargin = 5;
|
|
46
48
|
this._labelWidth = 0; // Will be overridden in `get bleed ()`
|
|
47
|
-
this.
|
|
49
|
+
this._lineIconBleed = [0, 0];
|
|
48
50
|
this._lineBleed = [0, 0];
|
|
49
51
|
/** We define a dedicated clipping path for this component because it needs to behave
|
|
50
52
|
* differently than the regular XYContainer's clipPath */
|
|
@@ -84,26 +86,29 @@ class Timeline extends XYComponentCore {
|
|
|
84
86
|
super.setData(data);
|
|
85
87
|
}
|
|
86
88
|
get bleed() {
|
|
87
|
-
var _a, _b, _c
|
|
89
|
+
var _a, _b, _c;
|
|
88
90
|
const { config, datamodel: { data } } = this;
|
|
89
91
|
const rowLabels = this._getRowLabels(data);
|
|
90
92
|
const rowHeight = config.rowHeight || (this._height / (rowLabels.length || 1));
|
|
91
|
-
const
|
|
92
|
-
const
|
|
93
|
+
const hasRowIcons = rowLabels.some(l => l.iconHref);
|
|
94
|
+
const maxRowIconSize = max(rowLabels.map(l => l.iconSize || 0));
|
|
93
95
|
// We calculate the longest label width to set the bleed values accordingly
|
|
94
96
|
if ((_a = config.showRowLabels) !== null && _a !== void 0 ? _a : config.showLabels) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
+
const [marginLeft, marginRight] = this._getRowLabelMargin();
|
|
98
|
+
if ((_b = config.rowLabelWidth) !== null && _b !== void 0 ? _b : config.labelWidth) {
|
|
99
|
+
this._labelWidth = ((_c = config.rowLabelWidth) !== null && _c !== void 0 ? _c : config.labelWidth) + marginLeft + marginRight;
|
|
100
|
+
}
|
|
97
101
|
else {
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
.
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
const
|
|
106
|
-
|
|
102
|
+
const labels = rowLabels.map(l => {
|
|
103
|
+
var _a;
|
|
104
|
+
return this._labelsGroup.append('text')
|
|
105
|
+
.attr('class', label)
|
|
106
|
+
.text(l.formattedLabel || '')
|
|
107
|
+
.call(trimSVGText, (_a = config.rowMaxLabelWidth) !== null && _a !== void 0 ? _a : config.maxLabelWidth, config.rowLabelTrimMode);
|
|
108
|
+
});
|
|
109
|
+
const labelWidth = max(labels.map(l => l.node().getBBox().width)) || 0;
|
|
110
|
+
labels.forEach(l => l.remove());
|
|
111
|
+
this._labelWidth = labelWidth ? labelWidth + marginLeft + marginRight : 0;
|
|
107
112
|
}
|
|
108
113
|
}
|
|
109
114
|
// There can be multiple start / end items with the same timestamp, so we need to find the shortest one
|
|
@@ -136,23 +141,23 @@ class Timeline extends XYComponentCore {
|
|
|
136
141
|
}
|
|
137
142
|
this._lineBleed = lineBleed;
|
|
138
143
|
// Icon bleed
|
|
139
|
-
const
|
|
144
|
+
const lineIconBleed = [0, 0];
|
|
140
145
|
if (config.lineStartIcon) {
|
|
141
|
-
|
|
146
|
+
lineIconBleed[0] = max(data, (d, i) => getIconBleed(d, i, config.lineStartIcon, config.lineStartIconSize, config.lineStartIconArrangement, rowHeight)) || 0;
|
|
142
147
|
}
|
|
143
148
|
if (config.lineEndIcon) {
|
|
144
|
-
|
|
149
|
+
lineIconBleed[1] = max(data, (d, i) => getIconBleed(d, i, config.lineEndIcon, config.lineEndIconSize, config.lineEndIconArrangement, rowHeight)) || 0;
|
|
145
150
|
}
|
|
146
|
-
this.
|
|
151
|
+
this._lineIconBleed = lineIconBleed;
|
|
147
152
|
return {
|
|
148
153
|
top: 0,
|
|
149
154
|
bottom: 0,
|
|
150
|
-
left: this._labelWidth +
|
|
151
|
-
right: this._scrollBarWidth + this._scrollBarMargin +
|
|
155
|
+
left: this._labelWidth + lineIconBleed[0] + (hasRowIcons ? maxRowIconSize : 0) + lineBleed[0],
|
|
156
|
+
right: this._scrollBarWidth + this._scrollBarMargin + lineIconBleed[1] + lineBleed[1],
|
|
152
157
|
};
|
|
153
158
|
}
|
|
154
159
|
_render(customDuration) {
|
|
155
|
-
var _a;
|
|
160
|
+
var _a, _b, _c;
|
|
156
161
|
super._render(customDuration);
|
|
157
162
|
const { config, datamodel: { data } } = this;
|
|
158
163
|
const duration = isNumber(customDuration) ? customDuration : config.duration;
|
|
@@ -181,6 +186,7 @@ class Timeline extends XYComponentCore {
|
|
|
181
186
|
.attr('width', l => l.iconSize)
|
|
182
187
|
.attr('height', l => l.iconSize)
|
|
183
188
|
.attr('y', l => yStart + (yOrdinalScale(l.label) + 0.5) * rowHeight - l.iconSize / 2)
|
|
189
|
+
.style('color', l => l.iconColor)
|
|
184
190
|
.style('opacity', 0);
|
|
185
191
|
smartTransition(rowIconsEnter.merge(rowIcons), duration)
|
|
186
192
|
.attr('href', l => l.iconHref)
|
|
@@ -196,11 +202,28 @@ class Timeline extends XYComponentCore {
|
|
|
196
202
|
// Labels
|
|
197
203
|
const labels = this._labelsGroup.selectAll(`.${label}`)
|
|
198
204
|
.data(((_a = config.showRowLabels) !== null && _a !== void 0 ? _a : config.showLabels) ? rowLabels : [], l => l === null || l === void 0 ? void 0 : l.label);
|
|
205
|
+
const [labelMarginLeft, labelMarginRight] = this._getRowLabelMargin();
|
|
199
206
|
const labelOffset = config.rowLabelTextAlign === TextAlign.Center ? this._labelWidth / 2
|
|
200
|
-
: config.rowLabelTextAlign === TextAlign.Left ? this._labelWidth
|
|
201
|
-
:
|
|
202
|
-
const xStart = xRange[0] - this.
|
|
207
|
+
: config.rowLabelTextAlign === TextAlign.Left ? this._labelWidth - labelMarginLeft
|
|
208
|
+
: labelMarginRight;
|
|
209
|
+
const xStart = xRange[0] - this._lineBleed[0] - this._lineIconBleed[0];
|
|
203
210
|
const labelXStart = xStart - labelOffset;
|
|
211
|
+
// Invisible background rects covering the full label column width for pointer events
|
|
212
|
+
const labelBackgrounds = this._labelsGroup
|
|
213
|
+
.selectAll(`.${labelBackground}`)
|
|
214
|
+
.data(((_b = config.showRowLabels) !== null && _b !== void 0 ? _b : config.showLabels) ? rowLabels : [], l => l === null || l === void 0 ? void 0 : l.label);
|
|
215
|
+
const labelBackgroundsEnter = labelBackgrounds.enter().append('rect')
|
|
216
|
+
.attr('class', labelBackground)
|
|
217
|
+
.attr('x', xStart - this._labelWidth)
|
|
218
|
+
.attr('y', l => yStart + yOrdinalScale(l.label) * rowHeight)
|
|
219
|
+
.attr('width', this._labelWidth)
|
|
220
|
+
.attr('height', rowHeight);
|
|
221
|
+
labelBackgroundsEnter.merge(labelBackgrounds)
|
|
222
|
+
.attr('x', xStart - this._labelWidth)
|
|
223
|
+
.attr('y', l => yStart + yOrdinalScale(l.label) * rowHeight)
|
|
224
|
+
.attr('width', this._labelWidth)
|
|
225
|
+
.attr('height', rowHeight);
|
|
226
|
+
labelBackgrounds.exit().remove();
|
|
204
227
|
const labelsEnter = labels.enter().append('text')
|
|
205
228
|
.attr('class', label)
|
|
206
229
|
.attr('x', labelXStart)
|
|
@@ -211,7 +234,8 @@ class Timeline extends XYComponentCore {
|
|
|
211
234
|
.each((label, i, els) => {
|
|
212
235
|
var _a, _b;
|
|
213
236
|
const labelSelection = select(els[i]);
|
|
214
|
-
|
|
237
|
+
const maxLabelWidth = ((_a = config.rowLabelWidth) !== null && _a !== void 0 ? _a : config.labelWidth) || ((_b = config.rowMaxLabelWidth) !== null && _b !== void 0 ? _b : config.maxLabelWidth);
|
|
238
|
+
trimSVGText(labelSelection, maxLabelWidth, config.rowLabelTrimMode);
|
|
215
239
|
// Apply custom label style if it has been provided
|
|
216
240
|
const customStyle = getValue(label, config.rowLabelStyle);
|
|
217
241
|
if (!isPlainObject(customStyle))
|
|
@@ -229,8 +253,8 @@ class Timeline extends XYComponentCore {
|
|
|
229
253
|
.style('opacity', 0)
|
|
230
254
|
.remove();
|
|
231
255
|
// Row background rects
|
|
232
|
-
const timelineWidth = xRange[1] - xRange[0] + this.
|
|
233
|
-
const numRows = Math.max(Math.floor(yHeight / rowHeight), numRowLabels);
|
|
256
|
+
const timelineWidth = xRange[1] - xRange[0] + this._lineIconBleed[0] + this._lineIconBleed[1] + this._lineBleed[0] + this._lineBleed[1];
|
|
257
|
+
const numRows = config.rowFillEmptySpace ? Math.max(Math.floor(yHeight / rowHeight), numRowLabels) : numRowLabels;
|
|
234
258
|
const recordTypes = Array(numRows).fill(null).map((_, i) => rowLabels[i]);
|
|
235
259
|
const rects = this._rowsGroup.selectAll(`.${row}`)
|
|
236
260
|
.data(recordTypes);
|
|
@@ -360,12 +384,19 @@ class Timeline extends XYComponentCore {
|
|
|
360
384
|
.attr('ry', this._scrollBarWidth / 2);
|
|
361
385
|
this._updateScrollPosition(0);
|
|
362
386
|
// Clip path
|
|
387
|
+
// Arrowheads can get cut off when they are too close to the edges, so we extend the clip path to account for them.
|
|
388
|
+
// TODO: In rare scenarios this can have unwanted side effects, so we might need to create a dedicated clip path for arrows.
|
|
389
|
+
const maxArrowHeadWidth = (_c = max(arrowsData !== null && arrowsData !== void 0 ? arrowsData : [], a => { var _a; return (_a = a.arrowHeadWidth) !== null && _a !== void 0 ? _a : TIMELINE_DEFAULT_ARROW_HEAD_WIDTH; })) !== null && _c !== void 0 ? _c : 0;
|
|
363
390
|
const clipPathRect = this._clipPath.select('rect');
|
|
364
391
|
smartTransition(clipPathRect, clipPathRect.attr('width') ? duration : 0)
|
|
365
|
-
.attr('x', xStart)
|
|
366
|
-
.attr('width', timelineWidth)
|
|
392
|
+
.attr('x', xStart - maxArrowHeadWidth / 2)
|
|
393
|
+
.attr('width', timelineWidth + maxArrowHeadWidth)
|
|
367
394
|
.attr('height', this._height);
|
|
368
395
|
}
|
|
396
|
+
_getRowLabelMargin() {
|
|
397
|
+
const m = this.config.rowLabelMargin;
|
|
398
|
+
return Array.isArray(m) ? m : [m, m];
|
|
399
|
+
}
|
|
369
400
|
_getLineLength(d, i) {
|
|
370
401
|
var _a, _b;
|
|
371
402
|
const { config, xScale } = this;
|