@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.
Files changed (65) hide show
  1. package/components/area/index.js +1 -3
  2. package/components/area/index.js.map +1 -1
  3. package/components/axis/config.d.ts +10 -7
  4. package/components/axis/config.js +1 -1
  5. package/components/axis/config.js.map +1 -1
  6. package/components/axis/index.d.ts +1 -0
  7. package/components/axis/index.js +44 -53
  8. package/components/axis/index.js.map +1 -1
  9. package/components/axis/style.d.ts +2 -38
  10. package/components/axis/style.js +28 -24
  11. package/components/axis/style.js.map +1 -1
  12. package/components/brush/config.d.ts +3 -0
  13. package/components/brush/config.js +1 -1
  14. package/components/brush/config.js.map +1 -1
  15. package/components/brush/index.d.ts +1 -0
  16. package/components/brush/index.js +7 -3
  17. package/components/brush/index.js.map +1 -1
  18. package/components/crosshair/config.d.ts +2 -0
  19. package/components/crosshair/config.js +1 -1
  20. package/components/crosshair/config.js.map +1 -1
  21. package/components/crosshair/index.d.ts +2 -0
  22. package/components/crosshair/index.js +8 -1
  23. package/components/crosshair/index.js.map +1 -1
  24. package/components/graph/index.js +2 -0
  25. package/components/graph/index.js.map +1 -1
  26. package/components/sankey/config.d.ts +2 -0
  27. package/components/sankey/config.js +1 -1
  28. package/components/sankey/config.js.map +1 -1
  29. package/components/sankey/index.d.ts +2 -2
  30. package/components/sankey/index.js +12 -5
  31. package/components/sankey/index.js.map +1 -1
  32. package/components/sankey/types.d.ts +4 -0
  33. package/components/sankey/types.js +7 -2
  34. package/components/sankey/types.js.map +1 -1
  35. package/components/scatter/index.d.ts +4 -0
  36. package/components/scatter/index.js +14 -0
  37. package/components/scatter/index.js.map +1 -1
  38. package/components/stacked-bar/index.d.ts +4 -1
  39. package/components/stacked-bar/index.js +17 -6
  40. package/components/stacked-bar/index.js.map +1 -1
  41. package/components/timeline/config.d.ts +7 -1
  42. package/components/timeline/config.js +2 -2
  43. package/components/timeline/config.js.map +1 -1
  44. package/components/timeline/index.d.ts +2 -2
  45. package/components/timeline/index.js +63 -32
  46. package/components/timeline/index.js.map +1 -1
  47. package/components/timeline/style.d.ts +6 -1
  48. package/components/timeline/style.js +40 -46
  49. package/components/timeline/style.js.map +1 -1
  50. package/components/topojson-map/index.d.ts +2 -2
  51. package/components/topojson-map/index.js +24 -5
  52. package/components/topojson-map/index.js.map +1 -1
  53. package/core/component/index.d.ts +4 -1
  54. package/core/component/index.js +6 -6
  55. package/core/component/index.js.map +1 -1
  56. package/index.js +1 -1
  57. package/package.json +6 -5
  58. package/types/misc.js +2 -0
  59. package/types/misc.js.map +1 -0
  60. package/types/style.d.ts +1 -0
  61. package/types.d.ts +1 -0
  62. package/types.js +2 -1
  63. package/types.js.map +1 -1
  64. package/utils/text.js +6 -2
  65. 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":"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"}
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":";;;;MA0Ga,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;;AAG1B,IAAA,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;;AAGlC,IAAA,MAAM,EAAE,SAAS;;AAGjB,IAAA,0BAA0B,EAAE,SAAS;;IAGrC,QAAQ,EAAE,SAAS,EAAA;;;;"}
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 _rowIconBleed;
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._rowIconBleed = [0, 0];
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, _d;
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 hasIcons = rowLabels.some(l => l.iconHref);
92
- const maxIconSize = max(rowLabels.map(l => l.iconSize || 0));
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
- if ((_b = config.rowLabelWidth) !== null && _b !== void 0 ? _b : config.labelWidth)
96
- this._labelWidth = ((_c = config.rowLabelWidth) !== null && _c !== void 0 ? _c : config.labelWidth) + this._labelMargin;
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 longestLabel = rowLabels.reduce((longestLabel, l) => longestLabel.formattedLabel.length > l.formattedLabel.length ? longestLabel : l, rowLabels[0]);
99
- const label$1 = this._labelsGroup.append('text')
100
- .attr('class', label)
101
- .text((longestLabel === null || longestLabel === void 0 ? void 0 : longestLabel.formattedLabel) || '')
102
- .call(trimSVGText, (_d = config.rowMaxLabelWidth) !== null && _d !== void 0 ? _d : config.maxLabelWidth);
103
- const labelWidth = label$1.node().getBBox().width;
104
- label$1.remove();
105
- const tolerance = 1.15; // Some characters are wider than others so we add a little of extra space to take that into account
106
- this._labelWidth = labelWidth ? tolerance * labelWidth + this._labelMargin : 0;
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 iconBleed = [0, 0];
144
+ const lineIconBleed = [0, 0];
140
145
  if (config.lineStartIcon) {
141
- iconBleed[0] = max(data, (d, i) => getIconBleed(d, i, config.lineStartIcon, config.lineStartIconSize, config.lineStartIconArrangement, rowHeight)) || 0;
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
- iconBleed[1] = max(data, (d, i) => getIconBleed(d, i, config.lineEndIcon, config.lineEndIconSize, config.lineEndIconArrangement, rowHeight)) || 0;
149
+ lineIconBleed[1] = max(data, (d, i) => getIconBleed(d, i, config.lineEndIcon, config.lineEndIconSize, config.lineEndIconArrangement, rowHeight)) || 0;
145
150
  }
146
- this._rowIconBleed = iconBleed;
151
+ this._lineIconBleed = lineIconBleed;
147
152
  return {
148
153
  top: 0,
149
154
  bottom: 0,
150
- left: this._labelWidth + iconBleed[0] + (hasIcons ? maxIconSize : 0) + lineBleed[0],
151
- right: this._scrollBarWidth + this._scrollBarMargin + iconBleed[1] + lineBleed[1],
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
- : this._labelMargin;
202
- const xStart = xRange[0] - this._rowIconBleed[0] - this._lineBleed[0];
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
- trimSVGText(labelSelection, ((_a = config.rowLabelWidth) !== null && _a !== void 0 ? _a : config.labelWidth) || ((_b = config.rowMaxLabelWidth) !== null && _b !== void 0 ? _b : config.maxLabelWidth));
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._rowIconBleed[0] + this._rowIconBleed[1] + this._lineBleed[0] + this._lineBleed[1];
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;