@unovis/ts 1.5.1-exf.10 → 1.5.1-exf.11

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/components/axis/index.ts"],"sourcesContent":["import { select, Selection } from 'd3-selection'\nimport { interrupt } from 'd3-transition'\nimport { Axis as D3Axis, axisBottom, axisLeft, axisRight, axisTop } from 'd3-axis'\n\n// Core\nimport { XYComponentCore } from 'core/xy-component'\n\n// Types\nimport { Position } from 'types/position'\nimport { ContinuousScale } from 'types/scale'\nimport { Spacing } from 'types/spacing'\nimport { FitMode, TextAlign, TrimMode, UnovisText, UnovisTextOptions, VerticalAlign } from 'types/text'\n\n// Utils\nimport { smartTransition } from 'utils/d3'\nimport { renderTextToSvgTextElement, trimSVGText } from 'utils/text'\nimport { isEqual } from 'utils/data'\nimport { rectIntersect } from 'utils/misc'\n\n// Local Types\nimport { AxisType } from './types'\n\n// Config\nimport { AxisDefaultConfig, AxisConfigInterface } from './config'\n\n// Styles\nimport * as s from './style'\n\nexport class Axis<Datum> extends XYComponentCore<Datum, AxisConfigInterface<Datum>> {\n static selectors = s\n protected _defaultConfig: AxisConfigInterface<Datum> = AxisDefaultConfig\n public config: AxisConfigInterface<Datum> = this._defaultConfig\n private axisGroup: Selection<SVGGElement, unknown, SVGGElement, unknown>\n private gridGroup: Selection<SVGGElement, unknown, SVGGElement, unknown>\n\n private _axisRawBBox: DOMRect\n private _axisSizeBBox: SVGRect\n private _requiredMargin: Spacing\n private _defaultNumTicks = 3\n private _collideTickLabelsAnimFrameId: ReturnType<typeof requestAnimationFrame>\n\n protected events = {}\n\n constructor (config?: AxisConfigInterface<Datum>) {\n super()\n if (config) this.setConfig(config)\n this.axisGroup = this.g.append('g')\n this.gridGroup = this.g.append('g')\n .attr('class', s.grid)\n }\n\n /** Renders axis to an invisible grouped to calculate automatic chart margins */\n public preRender (): void {\n const { config } = this\n const axisRenderHelperGroup = this.g.append('g').attr('opacity', 0)\n\n this._renderAxis(axisRenderHelperGroup, 0)\n\n // Store axis raw BBox (without the label) for further label positioning (see _renderAxisLabel)\n this._axisRawBBox = axisRenderHelperGroup.node().getBBox()\n\n // Align tick text\n if (config.tickTextAlign) this._alignTickLabels()\n\n // Render label and store total axis size and required margins\n this._renderAxisLabel(axisRenderHelperGroup)\n this._axisSizeBBox = this._getAxisSize(axisRenderHelperGroup)\n this._requiredMargin = this._getRequiredMargin(this._axisSizeBBox)\n\n axisRenderHelperGroup.remove()\n }\n\n public getPosition (): Position {\n const { config: { type, position } } = this\n return (position ?? ((type === AxisType.X) ? Position.Bottom : Position.Left)) as Position\n }\n\n private _getAxisSize (selection: Selection<SVGGElement, unknown, SVGGElement, undefined>): SVGRect {\n const bBox = selection.node().getBBox()\n return bBox\n }\n\n private _getRequiredMargin (axisSize = this._axisSizeBBox): Spacing {\n const { config: { type, position } } = this\n\n switch (type) {\n case AxisType.X: {\n const tolerancePx = 1\n const xEnd = this._axisSizeBBox.x + this._axisSizeBBox.width\n\n const left = this._axisSizeBBox.x < 0 ? Math.abs(this._axisSizeBBox.x) : 0\n const right = (xEnd - this._width) > tolerancePx ? xEnd - this._width : 0\n\n switch (position) {\n case Position.Top: return { top: axisSize.height, left, right }\n case Position.Bottom: default: return { bottom: axisSize.height, left, right }\n }\n }\n case AxisType.Y: {\n const bleedY = axisSize.height > this._height ? (axisSize.height - this._height) / 2 : 0\n const top = bleedY\n const bottom = bleedY\n\n switch (position) {\n case Position.Right: return { right: axisSize.width, top, bottom }\n case Position.Left: default: return { left: axisSize.width, top, bottom }\n }\n }\n }\n }\n\n getRequiredMargin (): Spacing {\n return this._requiredMargin\n }\n\n /** Calculates axis transform:translate offset based on passed container margins */\n getOffset (containerMargin: Spacing): {left: number; top: number} {\n const { config: { type, position } } = this\n\n switch (type) {\n case AxisType.X:\n switch (position) {\n case Position.Top: return { top: containerMargin.top, left: containerMargin.left }\n case Position.Bottom: default: return { top: containerMargin.top + this._height, left: containerMargin.left }\n }\n case AxisType.Y:\n switch (position) {\n case Position.Right: return { top: containerMargin.top, left: containerMargin.left + this._width }\n case Position.Left: default: return { top: containerMargin.top, left: containerMargin.left }\n }\n }\n }\n\n public _render (duration = this.config.duration, selection = this.axisGroup): void {\n const { config } = this\n\n this._renderAxis(selection, duration)\n this._renderAxisLabel(selection)\n\n if (config.gridLine) {\n const gridGen = this._buildGrid().tickFormat(() => '')\n gridGen.tickValues(this._getConfiguredTickValues())\n // Interrupting all active transitions first to prevent them from being stuck.\n // Somehow we see it happening in Angular apps.\n this.gridGroup.selectAll('*').interrupt()\n smartTransition(this.gridGroup, duration).call(gridGen).style('opacity', 1)\n } else {\n smartTransition(this.gridGroup, duration).style('opacity', 0)\n }\n\n if (config.tickTextAlign) this._alignTickLabels()\n\n this._resolveTickLabelOverlap(selection)\n }\n\n private _buildAxis (): D3Axis<any> {\n const { config: { type, position, tickPadding } } = this\n\n const ticks = this._getNumTicks()\n switch (type) {\n case AxisType.X:\n switch (position) {\n case Position.Top: return axisTop(this.xScale).ticks(ticks).tickPadding(tickPadding)\n case Position.Bottom: default: return axisBottom(this.xScale).ticks(ticks).tickPadding(tickPadding)\n }\n case AxisType.Y:\n switch (position) {\n case Position.Right: return axisRight(this.yScale).ticks(ticks).tickPadding(tickPadding)\n case Position.Left: default: return axisLeft(this.yScale).ticks(ticks).tickPadding(tickPadding)\n }\n }\n }\n\n private _buildGrid (): D3Axis<any> {\n const { config: { type, position } } = this\n\n const ticks = this._getNumTicks()\n switch (type) {\n case AxisType.X:\n switch (position) {\n case Position.Top: return axisTop(this.xScale).ticks(ticks * 2).tickSize(-this._height).tickSizeOuter(0)\n case Position.Bottom: default: return axisBottom(this.xScale).ticks(ticks * 2).tickSize(-this._height).tickSizeOuter(0)\n }\n case AxisType.Y:\n switch (position) {\n case Position.Right: return axisRight(this.yScale).ticks(ticks * 2).tickSize(-this._width).tickSizeOuter(0)\n case Position.Left: default: return axisLeft(this.yScale).ticks(ticks * 2).tickSize(-this._width).tickSizeOuter(0)\n }\n }\n }\n\n private _renderAxis (selection = this.axisGroup, duration = this.config.duration): void {\n const { config } = this\n\n const axisGen = this._buildAxis()\n const tickValues: (number[] | Date[]) = this._getConfiguredTickValues() || axisGen.scale<ContinuousScale>().ticks(this._getNumTicks())\n axisGen.tickValues(tickValues)\n\n // Interrupting all active transitions first to prevent them from being stuck.\n // Somehow we see it happening in Angular apps.\n selection.selectAll('*').interrupt()\n smartTransition(selection, duration).call(axisGen)\n\n const ticks = selection.selectAll<SVGGElement, number | Date>('g.tick')\n\n ticks\n .classed(s.tick, true)\n .style('font-size', config.tickTextFontSize)\n\n // Selecting the <text> elements of the ticks to apply formatting. By default, this selection\n // will include exiting elements, so we're filtering them out.\n const tickText = selection.selectAll<SVGTextElement, number | Date>('g.tick > text')\n .filter(tickValue => tickValues.some((t: number | Date) => isEqual(tickValue, t))) // We use isEqual to compare Dates\n .classed(s.tickLabel, true)\n .classed(s.tickLabelHideable, Boolean(config.tickTextHideOverlapping))\n .style('fill', config.tickTextColor) as Selection<SVGTextElement, number, SVGGElement, unknown> | Selection<SVGTextElement, Date, SVGGElement, unknown>\n\n\n // We interrupt the transition on tick's <text> to make it 'wrappable'\n tickText.nodes().forEach(node => interrupt(node))\n\n tickText.each((value: number | Date, i: number, elements: ArrayLike<SVGTextElement>) => {\n let text = config.tickFormat?.(value, i, tickValues) ?? `${value}`\n const textElement = elements[i] as SVGTextElement\n const textMaxWidth = config.tickTextWidth || (config.type === AxisType.X ? this._containerWidth / (ticks.size() + 1) : this._containerWidth / 5)\n const styleDeclaration = getComputedStyle(textElement)\n const fontSize = Number.parseFloat(styleDeclaration.fontSize)\n const fontFamily = styleDeclaration.fontFamily\n const textOptions: UnovisTextOptions = {\n verticalAlign: config.type === AxisType.X ? VerticalAlign.Top : VerticalAlign.Middle,\n width: textMaxWidth,\n textRotationAngle: config.tickTextAngle,\n separator: config.tickTextSeparator,\n wordBreak: config.tickTextForceWordBreak,\n }\n\n if (config.tickTextFitMode === FitMode.Trim) {\n const textElementSelection = select<SVGTextElement, string>(textElement).text(text)\n trimSVGText(textElementSelection, textMaxWidth, config.tickTextTrimType as TrimMode, true, fontSize, 0.58)\n text = select<SVGTextElement, string>(textElement).text()\n }\n\n const textBlock: UnovisText = { text, fontFamily, fontSize }\n renderTextToSvgTextElement(textElement, textBlock, textOptions)\n })\n\n selection\n .classed(s.axis, true)\n .classed(s.hideTickLine, !config.tickLine)\n .classed(s.hideDomain, !config.domainLine)\n\n if (config.fullSize) {\n const path = this._getFullDomainPath(0)\n smartTransition(selection.select('.domain'), duration).attr('d', path)\n }\n }\n\n private _resolveTickLabelOverlap (selection = this.axisGroup): void {\n const { config } = this\n const tickTextSelection = selection.selectAll<SVGTextElement, number | Date>('g.tick > text')\n\n if (!config.tickTextHideOverlapping) {\n tickTextSelection.style('opacity', null)\n return\n }\n\n cancelAnimationFrame(this._collideTickLabelsAnimFrameId)\n // Colliding labels in the next frame to prevent forced reflow\n this._collideTickLabelsAnimFrameId = requestAnimationFrame(() => {\n this._collideTickLabels(tickTextSelection)\n })\n }\n\n private _collideTickLabels (selection: Selection<SVGTextElement, number | Date, SVGGElement, unknown>): void {\n type SVGOverlappingTextElement = SVGTextElement & {\n _visible: boolean;\n }\n\n // Reset visibility of all labels\n selection.each((d, i, elements) => {\n const node = elements[i] as SVGOverlappingTextElement\n node._visible = true\n })\n\n // We do three iterations because not all overlapping labels can be resolved in the first iteration\n const numIterations = 3\n for (let i = 0; i < numIterations; i += 1) {\n // Run collision detection and set labels visibility\n selection.each((d, i, elements) => {\n const label1 = elements[i] as SVGOverlappingTextElement\n const isLabel1Visible = label1._visible\n if (!isLabel1Visible) return\n\n // Calculate bounding rect of point's label\n const label1BoundingRect = label1.getBoundingClientRect()\n\n for (let j = i + 1; j < elements.length; j += 1) {\n if (i === j) continue\n const label2 = elements[j] as SVGOverlappingTextElement\n const isLabel2Visible = label2._visible\n if (isLabel2Visible) {\n const label2BoundingRect = label2.getBoundingClientRect()\n const intersect = rectIntersect(label1BoundingRect, label2BoundingRect, -5)\n if (intersect) {\n label2._visible = false\n break\n }\n }\n }\n })\n }\n\n // Hide the overlapping labels\n selection.each((d, i, elements) => {\n const label = elements[i] as SVGOverlappingTextElement\n select(label).style('opacity', label._visible ? 1 : 0)\n })\n }\n\n private _getNumTicks (): number {\n const { config: { type, numTicks } } = this\n\n if (numTicks) return numTicks\n\n if (type === AxisType.X) {\n const xRange = this.xScale.range() as [number, number]\n const width = xRange[1] - xRange[0]\n return Math.floor(width / 175)\n }\n\n if (type === AxisType.Y) {\n const yRange = this.yScale.range() as [number, number]\n const height = Math.abs(yRange[0] - yRange[1])\n return Math.pow(height, 0.85) / 25\n }\n\n return this._defaultNumTicks\n }\n\n private _getConfiguredTickValues (): number[] | null {\n const { config } = this\n const scale = config.type === AxisType.X ? this.xScale : this.yScale\n const scaleDomain = scale?.domain() as [number, number]\n\n if (config.tickValues) {\n return config.tickValues.filter(v => (v >= scaleDomain[0]) && (v <= scaleDomain[1]))\n }\n\n if (config.minMaxTicksOnly || (config.type === AxisType.X && this._width < config.minMaxTicksOnlyWhenWidthIsLess)) {\n return scaleDomain as number[]\n }\n\n return null\n }\n\n private _getFullDomainPath (tickSize = 0): string {\n const { config: { type } } = this\n switch (type) {\n case AxisType.X: return `M0.5, ${tickSize} V0.5 H${this._width + 0.5} V${tickSize}`\n case AxisType.Y: return `M${-tickSize}, ${this._height + 0.5} H0.5 V0.5 H${-tickSize}`\n }\n }\n\n private _renderAxisLabel (selection = this.axisGroup): void {\n const { type, label, labelMargin, labelFontSize } = this.config\n\n // Remove the old label first to calculate the axis size properly\n selection.selectAll(`.${s.label}`).remove()\n\n // Calculate label position and rotation\n const axisPosition = this.getPosition()\n // We always use this.axisRenderHelperGroup to calculate the size of the axis because\n // this.axisGroup will give us incorrect values due to animation\n const { width: axisWidth, height: axisHeight } = this._axisRawBBox ?? selection.node().getBBox()\n\n const offsetX = type === AxisType.X ? this._width / 2 : (-1) ** (+(axisPosition === Position.Left)) * axisWidth\n const offsetY = type === AxisType.X ? (-1) ** (+(axisPosition === Position.Top)) * axisHeight : this._height / 2\n\n const marginX = type === AxisType.X ? 0 : (-1) ** (+(axisPosition === Position.Left)) * labelMargin\n const marginY = type === AxisType.X ? (-1) ** (+(axisPosition === Position.Top)) * labelMargin : 0\n\n const rotation = type === AxisType.Y ? -90 : 0\n // Append new label\n selection\n .append('text')\n .attr('class', s.label)\n .text(label)\n .attr('dy', `${this._getLabelDY()}em`)\n .attr('transform', `translate(${offsetX + marginX},${offsetY + marginY}) rotate(${rotation})`)\n .style('font-size', labelFontSize)\n .style('fill', this.config.labelColor)\n }\n\n private _getLabelDY (): number {\n const { type, position } = this.config\n switch (type) {\n case AxisType.X:\n switch (position) {\n case Position.Top: return 0\n case Position.Bottom: default: return 0.75\n }\n case AxisType.Y:\n switch (position) {\n case Position.Right: return 0.75\n case Position.Left: default: return -0.25\n }\n }\n }\n\n private _alignTickLabels (): void {\n const { config: { type, tickTextAlign, tickTextAngle, position } } = this\n const tickText = this.g.selectAll('g.tick > text')\n\n const textAnchor = this._getTickTextAnchor(tickTextAlign as TextAlign)\n const translateX = type === AxisType.X\n ? 0\n : this._getYTickTextTranslate(tickTextAlign as TextAlign, position as Position)\n\n const translateValue = tickTextAngle ? `translate(${translateX},0) rotate(${tickTextAngle})` : `translate(${translateX},0)`\n tickText\n .attr('transform', translateValue)\n .attr('text-anchor', textAnchor)\n }\n\n private _getTickTextAnchor (textAlign: TextAlign): string {\n switch (textAlign) {\n case TextAlign.Left: return 'start'\n case TextAlign.Right: return 'end'\n case TextAlign.Center: return 'middle'\n default: return null\n }\n }\n\n private _getYTickTextTranslate (textAlign: TextAlign, axisPosition: Position = Position.Left): number {\n const defaultTickTextSpacingPx = 9 // Default in D3\n const width = this._axisRawBBox.width - defaultTickTextSpacingPx\n\n switch (textAlign) {\n case TextAlign.Left: return axisPosition === Position.Left ? width * -1 : 0\n case TextAlign.Right: return axisPosition === Position.Left ? 0 : width\n case TextAlign.Center: return axisPosition === Position.Left ? width * (-0.5) : width * 0.5\n default: return 0\n }\n }\n}\n"],"names":["_Axis","XYComponentCore","config","AxisDefaultConfig","s.grid","axisRenderHelperGroup","type","position","AxisType","Position","selection","axisSize","xEnd","left","right","bleedY","top","bottom","containerMargin","duration","gridGen","smartTransition","tickPadding","ticks","axisTop","axisBottom","axisRight","axisLeft","axisGen","tickValues","s.tick","tickText","tickValue","t","isEqual","s.tickLabel","s.tickLabelHideable","node","interrupt","value","i","elements","text","_a","textElement","textMaxWidth","styleDeclaration","fontSize","fontFamily","textOptions","VerticalAlign","FitMode","textElementSelection","select","trimSVGText","renderTextToSvgTextElement","s.axis","s.hideTickLine","s.hideDomain","path","tickTextSelection","d","numIterations","label1","label1BoundingRect","j","label2","label2BoundingRect","rectIntersect","label","numTicks","xRange","width","yRange","height","scale","scaleDomain","v","tickSize","labelMargin","labelFontSize","s.label","axisPosition","axisWidth","axisHeight","offsetX","offsetY","marginX","marginY","rotation","tickTextAlign","tickTextAngle","textAnchor","translateX","translateValue","textAlign","TextAlign","s","Axis"],"mappings":";;;;;;;;;;;;;;AA4BO,MAAMA,IAAN,MAAMA,UAAoBC,EAAmD;AAAA,EAelF,YAAaC,GAAqC;AAC1C,UAAA,GAdR,KAAU,iBAA6CC,GACvD,KAAO,SAAqC,KAAK,gBAOjD,KAAQ,mBAAmB,GAG3B,KAAU,SAAS,CAAC,GAIdD,KAAa,KAAA,UAAUA,CAAM,GACjC,KAAK,YAAY,KAAK,EAAE,OAAO,GAAG,GAC7B,KAAA,YAAY,KAAK,EAAE,OAAO,GAAG,EAC/B,KAAK,SAASE,CAAM;AAAA,EAAA;AAAA;AAAA,EAIlB,YAAmB;AAClB,UAAA,EAAE,QAAAF,MAAW,MACbG,IAAwB,KAAK,EAAE,OAAO,GAAG,EAAE,KAAK,WAAW,CAAC;AAE7D,SAAA,YAAYA,GAAuB,CAAC,GAGzC,KAAK,eAAeA,EAAsB,KAAK,EAAE,QAAQ,GAGrDH,EAAO,iBAAe,KAAK,iBAAiB,GAGhD,KAAK,iBAAiBG,CAAqB,GACtC,KAAA,gBAAgB,KAAK,aAAaA,CAAqB,GAC5D,KAAK,kBAAkB,KAAK,mBAAmB,KAAK,aAAa,GAEjEA,EAAsB,OAAO;AAAA,EAAA;AAAA,EAGxB,cAAyB;AAC9B,UAAM,EAAE,QAAQ,EAAE,MAAAC,GAAM,UAAAC,EAAA,EAAe,IAAA;AACvC,WAAQA,MAAcD,MAASE,EAAS,IAAKC,EAAS,SAASA,EAAS;AAAA,EAAA;AAAA,EAGlE,aAAcC,GAA6E;AAE1F,WADMA,EAAU,KAAK,EAAE,QAAQ;AAAA,EAC/B;AAAA,EAGD,mBAAoBC,IAAW,KAAK,eAAwB;AAClE,UAAM,EAAE,QAAQ,EAAE,MAAAL,GAAM,UAAAC,EAAA,EAAe,IAAA;AAEvC,YAAQD,GAAM;AAAA,MACZ,KAAKE,EAAS,GAAG;AAEf,cAAMI,IAAO,KAAK,cAAc,IAAI,KAAK,cAAc,OAEjDC,IAAO,KAAK,cAAc,IAAI,IAAI,KAAK,IAAI,KAAK,cAAc,CAAC,IAAI,GACnEC,IAASF,IAAO,KAAK,SAAU,IAAcA,IAAO,KAAK,SAAS;AAExE,gBAAQL,GAAU;AAAA,UAChB,KAAKE,EAAS;AAAK,mBAAO,EAAE,KAAKE,EAAS,QAAQ,MAAAE,GAAM,OAAAC,EAAM;AAAA,UAC9D,KAAKL,EAAS;AAAA,UAAQ;AAAS,mBAAO,EAAE,QAAQE,EAAS,QAAQ,MAAAE,GAAM,OAAAC,EAAM;AAAA,QAAA;AAAA,MAC/E;AAAA,MAEF,KAAKN,EAAS,GAAG;AACT,cAAAO,IAASJ,EAAS,SAAS,KAAK,WAAWA,EAAS,SAAS,KAAK,WAAW,IAAI,GACjFK,IAAMD,GACNE,IAASF;AAEf,gBAAQR,GAAU;AAAA,UAChB,KAAKE,EAAS;AAAO,mBAAO,EAAE,OAAOE,EAAS,OAAO,KAAAK,GAAK,QAAAC,EAAO;AAAA,UACjE,KAAKR,EAAS;AAAA,UAAM;AAAS,mBAAO,EAAE,MAAME,EAAS,OAAO,KAAAK,GAAK,QAAAC,EAAO;AAAA,QAAA;AAAA,MAC1E;AAAA,IACF;AAAA,EACF;AAAA,EAGF,oBAA8B;AAC5B,WAAO,KAAK;AAAA,EAAA;AAAA;AAAA,EAId,UAAWC,GAAuD;AAChE,UAAM,EAAE,QAAQ,EAAE,MAAAZ,GAAM,UAAAC,EAAA,EAAe,IAAA;AAEvC,YAAQD,GAAM;AAAA,MACZ,KAAKE,EAAS;AACZ,gBAAQD,GAAU;AAAA,UAChB,KAAKE,EAAS;AAAK,mBAAO,EAAE,KAAKS,EAAgB,KAAK,MAAMA,EAAgB,KAAK;AAAA,UACjF,KAAKT,EAAS;AAAA,UAAQ;AAAgB,mBAAA,EAAE,KAAKS,EAAgB,MAAM,KAAK,SAAS,MAAMA,EAAgB,KAAK;AAAA,QAAA;AAAA,MAEhH,KAAKV,EAAS;AACZ,gBAAQD,GAAU;AAAA,UAChB,KAAKE,EAAS;AAAc,mBAAA,EAAE,KAAKS,EAAgB,KAAK,MAAMA,EAAgB,OAAO,KAAK,OAAO;AAAA,UACjG,KAAKT,EAAS;AAAA,UAAM;AAAS,mBAAO,EAAE,KAAKS,EAAgB,KAAK,MAAMA,EAAgB,KAAK;AAAA,QAAA;AAAA,IAC7F;AAAA,EACJ;AAAA,EAGK,QAASC,IAAW,KAAK,OAAO,UAAUT,IAAY,KAAK,WAAiB;AAC3E,UAAA,EAAE,QAAAR,MAAW;AAKnB,QAHK,KAAA,YAAYQ,GAAWS,CAAQ,GACpC,KAAK,iBAAiBT,CAAS,GAE3BR,EAAO,UAAU;AACnB,YAAMkB,IAAU,KAAK,WAAa,EAAA,WAAW,MAAM,EAAE;AAC7C,MAAAA,EAAA,WAAW,KAAK,0BAA0B,GAGlD,KAAK,UAAU,UAAU,GAAG,EAAE,UAAU,GACxBC,EAAA,KAAK,WAAWF,CAAQ,EAAE,KAAKC,CAAO,EAAE,MAAM,WAAW,CAAC;AAAA,IAAA;AAE1E,MAAAC,EAAgB,KAAK,WAAWF,CAAQ,EAAE,MAAM,WAAW,CAAC;AAG1D,IAAAjB,EAAO,iBAAe,KAAK,iBAAiB,GAEhD,KAAK,yBAAyBQ,CAAS;AAAA,EAAA;AAAA,EAGjC,aAA2B;AACjC,UAAM,EAAE,QAAQ,EAAE,MAAAJ,GAAM,UAAAC,GAAU,aAAAe,QAAkB,MAE9CC,IAAQ,KAAK,aAAa;AAChC,YAAQjB,GAAM;AAAA,MACZ,KAAKE,EAAS;AACZ,gBAAQD,GAAU;AAAA,UAChB,KAAKE,EAAS;AAAY,mBAAAe,EAAQ,KAAK,MAAM,EAAE,MAAMD,CAAK,EAAE,YAAYD,CAAW;AAAA,UACnF,KAAKb,EAAS;AAAA,UAAQ;AAAgB,mBAAAgB,EAAW,KAAK,MAAM,EAAE,MAAMF,CAAK,EAAE,YAAYD,CAAW;AAAA,QAAA;AAAA,MAEtG,KAAKd,EAAS;AACZ,gBAAQD,GAAU;AAAA,UAChB,KAAKE,EAAS;AAAc,mBAAAiB,EAAU,KAAK,MAAM,EAAE,MAAMH,CAAK,EAAE,YAAYD,CAAW;AAAA,UACvF,KAAKb,EAAS;AAAA,UAAM;AAAgB,mBAAAkB,EAAS,KAAK,MAAM,EAAE,MAAMJ,CAAK,EAAE,YAAYD,CAAW;AAAA,QAAA;AAAA,IAChG;AAAA,EACJ;AAAA,EAGM,aAA2B;AACjC,UAAM,EAAE,QAAQ,EAAE,MAAAhB,GAAM,UAAAC,EAAA,EAAe,IAAA,MAEjCgB,IAAQ,KAAK,aAAa;AAChC,YAAQjB,GAAM;AAAA,MACZ,KAAKE,EAAS;AACZ,gBAAQD,GAAU;AAAA,UAChB,KAAKE,EAAS;AAAK,mBAAOe,EAAQ,KAAK,MAAM,EAAE,MAAMD,IAAQ,CAAC,EAAE,SAAS,CAAC,KAAK,OAAO,EAAE,cAAc,CAAC;AAAA,UACvG,KAAKd,EAAS;AAAA,UAAQ;AAAS,mBAAOgB,EAAW,KAAK,MAAM,EAAE,MAAMF,IAAQ,CAAC,EAAE,SAAS,CAAC,KAAK,OAAO,EAAE,cAAc,CAAC;AAAA,QAAA;AAAA,MAE1H,KAAKf,EAAS;AACZ,gBAAQD,GAAU;AAAA,UAChB,KAAKE,EAAS;AAAO,mBAAOiB,EAAU,KAAK,MAAM,EAAE,MAAMH,IAAQ,CAAC,EAAE,SAAS,CAAC,KAAK,MAAM,EAAE,cAAc,CAAC;AAAA,UAC1G,KAAKd,EAAS;AAAA,UAAM;AAAS,mBAAOkB,EAAS,KAAK,MAAM,EAAE,MAAMJ,IAAQ,CAAC,EAAE,SAAS,CAAC,KAAK,MAAM,EAAE,cAAc,CAAC;AAAA,QAAA;AAAA,IACnH;AAAA,EACJ;AAAA,EAGM,YAAab,IAAY,KAAK,WAAWS,IAAW,KAAK,OAAO,UAAgB;AAChF,UAAA,EAAE,QAAAjB,MAAW,MAEb0B,IAAU,KAAK,WAAW,GAC1BC,IAAkC,KAAK,8BAA8BD,EAAQ,QAAyB,MAAM,KAAK,cAAc;AACrI,IAAAA,EAAQ,WAAWC,CAAU,GAInBnB,EAAA,UAAU,GAAG,EAAE,UAAU,GACnCW,EAAgBX,GAAWS,CAAQ,EAAE,KAAKS,CAAO;AAE3C,UAAAL,IAAQb,EAAU,UAAsC,QAAQ;AAGnE,IAAAa,EAAA,QAAQO,GAAQ,EAAI,EACpB,MAAM,aAAa5B,EAAO,gBAAgB;AAI7C,UAAM6B,IAAWrB,EAAU,UAAyC,eAAe,EAChF,OAAO,CAAAsB,MAAaH,EAAW,KAAK,CAACI,MAAqBC,EAAQF,GAAWC,CAAC,CAAC,CAAC,EAChF,QAAQE,GAAa,EAAI,EACzB,QAAQC,GAAqB,EAAQlC,EAAO,uBAAwB,EACpE,MAAM,QAAQA,EAAO,aAAa;AAoCrC,QAhCA6B,EAAS,QAAQ,QAAQ,CAAQM,MAAAC,EAAUD,CAAI,CAAC,GAEhDN,EAAS,KAAK,CAACQ,GAAsBC,GAAWC,MAAwC;;AAClF,UAAAC,MAAOC,IAAAzC,EAAO,eAAP,gBAAAyC,EAAA,KAAAzC,GAAoBqC,GAAOC,GAAGX,OAAe,GAAGU,CAAK;AAC1D,YAAAK,IAAcH,EAASD,CAAC,GACxBK,IAAe3C,EAAO,kBAAkBA,EAAO,SAASM,EAAS,IAAI,KAAK,mBAAmBe,EAAM,SAAS,KAAK,KAAK,kBAAkB,IACxIuB,IAAmB,iBAAiBF,CAAW,GAC/CG,IAAW,OAAO,WAAWD,EAAiB,QAAQ,GACtDE,IAAaF,EAAiB,YAC9BG,IAAiC;AAAA,QACrC,eAAe/C,EAAO,SAASM,EAAS,IAAI0C,EAAc,MAAMA,EAAc;AAAA,QAC9E,OAAOL;AAAA,QACP,mBAAmB3C,EAAO;AAAA,QAC1B,WAAWA,EAAO;AAAA,QAClB,WAAWA,EAAO;AAAA,MACpB;AAEI,UAAAA,EAAO,oBAAoBiD,EAAQ,MAAM;AAC3C,cAAMC,IAAuBC,EAA+BT,CAAW,EAAE,KAAKF,CAAI;AAClF,QAAAY,EAAYF,GAAsBP,GAAc3C,EAAO,kBAA8B,IAAM6C,GAAU,IAAI,GAClGL,IAAAW,EAA+BT,CAAW,EAAE,KAAK;AAAA,MAAA;AAI/B,MAAAW,EAAAX,GADG,EAAE,MAAAF,GAAM,YAAAM,GAAY,UAAAD,EAAS,GACRE,CAAW;AAAA,IAAA,CAC/D,GAEDvC,EACG,QAAQ8C,GAAQ,EAAI,EACpB,QAAQC,GAAgB,CAACvD,EAAO,QAAQ,EACxC,QAAQwD,GAAc,CAACxD,EAAO,UAAU,GAEvCA,EAAO,UAAU;AACb,YAAAyD,IAAO,KAAK,mBAAmB,CAAC;AACtB,MAAAtC,EAAAX,EAAU,OAAO,SAAS,GAAGS,CAAQ,EAAE,KAAK,KAAKwC,CAAI;AAAA,IAAA;AAAA,EACvE;AAAA,EAGM,yBAA0BjD,IAAY,KAAK,WAAiB;AAC5D,UAAA,EAAE,QAAAR,MAAW,MACb0D,IAAoBlD,EAAU,UAAyC,eAAe;AAExF,QAAA,CAACR,EAAO,yBAAyB;AACjB,MAAA0D,EAAA,MAAM,WAAW,IAAI;AACvC;AAAA,IAAA;AAGF,yBAAqB,KAAK,6BAA6B,GAElD,KAAA,gCAAgC,sBAAsB,MAAM;AAC/D,WAAK,mBAAmBA,CAAiB;AAAA,IAAA,CAC1C;AAAA,EAAA;AAAA,EAGK,mBAAoBlD,GAAiF;AAM3G,IAAAA,EAAU,KAAK,CAACmD,GAAGrB,GAAGC,MAAa;AAC3B,YAAAJ,IAAOI,EAASD,CAAC;AACvB,MAAAH,EAAK,WAAW;AAAA,IAAA,CACjB;AAGD,UAAMyB,IAAgB;AACtB,aAAStB,IAAI,GAAGA,IAAIsB,GAAetB,KAAK;AAEtC,MAAA9B,EAAU,KAAK,CAACmD,GAAGrB,GAAGC,MAAa;AAC3B,cAAAsB,IAAStB,EAASD,CAAC;AAEzB,YAAI,CADoBuB,EAAO,SACT;AAGhB,cAAAC,IAAqBD,EAAO,sBAAsB;AAExD,iBAASE,IAAIzB,IAAI,GAAGyB,IAAIxB,EAAS,QAAQwB,KAAK,GAAG;AAC/C,cAAIzB,MAAMyB,EAAG;AACP,gBAAAC,IAASzB,EAASwB,CAAC;AAEzB,cADwBC,EAAO,UACV;AACb,kBAAAC,IAAqBD,EAAO,sBAAsB;AAExD,gBADkBE,EAAcJ,GAAoBG,GAAoB,EAAE,GAC3D;AACb,cAAAD,EAAO,WAAW;AAClB;AAAA,YAAA;AAAA,UACF;AAAA,QACF;AAAA,MACF,CACD;AAIH,IAAAxD,EAAU,KAAK,CAACmD,GAAGrB,GAAGC,MAAa;AAC3B,YAAA4B,IAAQ5B,EAASD,CAAC;AACxB,MAAAa,EAAOgB,CAAK,EAAE,MAAM,WAAWA,EAAM,WAAW,IAAI,CAAC;AAAA,IAAA,CACtD;AAAA,EAAA;AAAA,EAGK,eAAwB;AAC9B,UAAM,EAAE,QAAQ,EAAE,MAAA/D,GAAM,UAAAgE,EAAA,EAAe,IAAA;AAEvC,QAAIA,EAAiB,QAAAA;AAEjB,QAAAhE,MAASE,EAAS,GAAG;AACjB,YAAA+D,IAAS,KAAK,OAAO,MAAM,GAC3BC,IAAQD,EAAO,CAAC,IAAIA,EAAO,CAAC;AAC3B,aAAA,KAAK,MAAMC,IAAQ,GAAG;AAAA,IAAA;AAG3B,QAAAlE,MAASE,EAAS,GAAG;AACjB,YAAAiE,IAAS,KAAK,OAAO,MAAM,GAC3BC,IAAS,KAAK,IAAID,EAAO,CAAC,IAAIA,EAAO,CAAC,CAAC;AAC7C,aAAO,KAAK,IAAIC,GAAQ,IAAI,IAAI;AAAA,IAAA;AAGlC,WAAO,KAAK;AAAA,EAAA;AAAA,EAGN,2BAA6C;AAC7C,UAAA,EAAE,QAAAxE,MAAW,MACbyE,IAAQzE,EAAO,SAASM,EAAS,IAAI,KAAK,SAAS,KAAK,QACxDoE,IAAcD,KAAA,gBAAAA,EAAO;AAE3B,WAAIzE,EAAO,aACFA,EAAO,WAAW,OAAO,CAAM2E,MAAAA,KAAKD,EAAY,CAAC,KAAOC,KAAKD,EAAY,CAAC,CAAE,IAGjF1E,EAAO,mBAAoBA,EAAO,SAASM,EAAS,KAAK,KAAK,SAASN,EAAO,iCACzE0E,IAGF;AAAA,EAAA;AAAA,EAGD,mBAAoBE,IAAW,GAAW;AAChD,UAAM,EAAE,QAAQ,EAAE,MAAAxE,EAAA,EAAW,IAAA;AAC7B,YAAQA,GAAM;AAAA,MACZ,KAAKE,EAAS;AAAG,eAAO,SAASsE,CAAQ,UAAU,KAAK,SAAS,GAAG,KAAKA,CAAQ;AAAA,MACjF,KAAKtE,EAAS;AAAU,eAAA,IAAI,CAACsE,CAAQ,KAAK,KAAK,UAAU,GAAG,eAAe,CAACA,CAAQ;AAAA,IAAA;AAAA,EACtF;AAAA,EAGM,iBAAkBpE,IAAY,KAAK,WAAiB;AAC1D,UAAM,EAAE,MAAAJ,GAAM,OAAA+D,GAAO,aAAAU,GAAa,eAAAC,EAAA,IAAkB,KAAK;AAGzD,IAAAtE,EAAU,UAAU,IAAIuE,CAAO,EAAE,EAAE,OAAO;AAGpC,UAAAC,IAAe,KAAK,YAAY,GAGhC,EAAE,OAAOC,GAAW,QAAQC,EAAA,IAAe,KAAK,gBAAgB1E,EAAU,KAAK,EAAE,QAAQ,GAEzF2E,IAAU/E,MAASE,EAAS,IAAI,KAAK,SAAS,IAAa,QAAA,EAAE0E,MAAiBzE,EAAS,QAAS0E,GAChGG,IAAUhF,MAASE,EAAS,IAAK,QAAQ,EAAE0E,MAAiBzE,EAAS,OAAQ2E,IAAa,KAAK,UAAU,GAEzGG,IAAUjF,MAASE,EAAS,IAAI,IAAa,QAAA,EAAE0E,MAAiBzE,EAAS,QAASsE,GAClFS,IAAUlF,MAASE,EAAS,YAAa,EAAE0E,MAAiBzE,EAAS,OAAQsE,IAAc,GAE3FU,IAAWnF,MAASE,EAAS,IAAI,MAAM;AAE7C,IAAAE,EACG,OAAO,MAAM,EACb,KAAK,SAASuE,CAAO,EACrB,KAAKZ,CAAK,EACV,KAAK,MAAM,GAAG,KAAK,YAAA,CAAa,IAAI,EACpC,KAAK,aAAa,aAAagB,IAAUE,CAAO,IAAID,IAAUE,CAAO,YAAYC,CAAQ,GAAG,EAC5F,MAAM,aAAaT,CAAa,EAChC,MAAM,QAAQ,KAAK,OAAO,UAAU;AAAA,EAAA;AAAA,EAGjC,cAAuB;AAC7B,UAAM,EAAE,MAAA1E,GAAM,UAAAC,EAAS,IAAI,KAAK;AAChC,YAAQD,GAAM;AAAA,MACZ,KAAKE,EAAS;AACZ,gBAAQD,GAAU;AAAA,UAChB,KAAKE,EAAS;AAAY,mBAAA;AAAA,UAC1B,KAAKA,EAAS;AAAA,UAAQ;AAAgB,mBAAA;AAAA,QAAA;AAAA,MAE1C,KAAKD,EAAS;AACZ,gBAAQD,GAAU;AAAA,UAChB,KAAKE,EAAS;AAAc,mBAAA;AAAA,UAC5B,KAAKA,EAAS;AAAA,UAAM;AAAgB,mBAAA;AAAA,QAAA;AAAA,IACtC;AAAA,EACJ;AAAA,EAGM,mBAA0B;AAC1B,UAAA,EAAE,QAAQ,EAAE,MAAAH,GAAM,eAAAoF,GAAe,eAAAC,GAAe,UAAApF,QAAe,MAC/DwB,IAAW,KAAK,EAAE,UAAU,eAAe,GAE3C6D,IAAa,KAAK,mBAAmBF,CAA0B,GAC/DG,IAAavF,MAASE,EAAS,IACjC,IACA,KAAK,uBAAuBkF,GAA4BnF,CAAoB,GAE1EuF,IAAiBH,IAAgB,aAAaE,CAAU,cAAcF,CAAa,MAAM,aAAaE,CAAU;AACtH,IAAA9D,EACG,KAAK,aAAa+D,CAAc,EAChC,KAAK,eAAeF,CAAU;AAAA,EAAA;AAAA,EAG3B,mBAAoBG,GAA8B;AACxD,YAAQA,GAAW;AAAA,MACjB,KAAKC,EAAU;AAAa,eAAA;AAAA,MAC5B,KAAKA,EAAU;AAAc,eAAA;AAAA,MAC7B,KAAKA,EAAU;AAAe,eAAA;AAAA,MAC9B;AAAgB,eAAA;AAAA,IAAA;AAAA,EAClB;AAAA,EAGM,uBAAwBD,GAAsBb,IAAyBzE,EAAS,MAAc;AAE9F,UAAA+D,IAAQ,KAAK,aAAa,QAAQ;AAExC,YAAQuB,GAAW;AAAA,MACjB,KAAKC,EAAU;AAAM,eAAOd,MAAiBzE,EAAS,OAAO+D,IAAQ,KAAK;AAAA,MAC1E,KAAKwB,EAAU;AAAc,eAAAd,MAAiBzE,EAAS,OAAO,IAAI+D;AAAA,MAClE,KAAKwB,EAAU;AAAQ,eAAOd,MAAiBzE,EAAS,OAAO+D,IAAS,OAAQA,IAAQ;AAAA,MACxF;AAAgB,eAAA;AAAA,IAAA;AAAA,EAClB;AAEJ;AA/ZExE,EAAO,YAAYiG;AADd,IAAMC,IAANlG;"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/components/axis/index.ts"],"sourcesContent":["import { select, Selection } from 'd3-selection'\nimport { interrupt } from 'd3-transition'\nimport { Axis as D3Axis, axisBottom, axisLeft, axisRight, axisTop } from 'd3-axis'\n\n// Core\nimport { XYComponentCore } from 'core/xy-component'\n\n// Types\nimport { Position } from 'types/position'\nimport { ContinuousScale } from 'types/scale'\nimport { Spacing } from 'types/spacing'\nimport { FitMode, TextAlign, TrimMode, UnovisText, UnovisTextOptions, VerticalAlign } from 'types/text'\n\n// Utils\nimport { smartTransition } from 'utils/d3'\nimport { renderTextToSvgTextElement, trimSVGText } from 'utils/text'\nimport { isEqual } from 'utils/data'\nimport { rectIntersect } from 'utils/misc'\n\n// Local Types\nimport { AxisType } from './types'\n\n// Config\nimport { AxisDefaultConfig, AxisConfigInterface } from './config'\n\n// Styles\nimport * as s from './style'\n\nexport class Axis<Datum> extends XYComponentCore<Datum, AxisConfigInterface<Datum>> {\n static selectors = s\n protected _defaultConfig: AxisConfigInterface<Datum> = AxisDefaultConfig\n public config: AxisConfigInterface<Datum> = this._defaultConfig\n private axisGroup: Selection<SVGGElement, unknown, SVGGElement, unknown>\n private gridGroup: Selection<SVGGElement, unknown, SVGGElement, unknown>\n\n private _axisRawBBox: DOMRect\n private _axisSizeBBox: SVGRect\n private _requiredMargin: Spacing\n private _defaultNumTicks = 3\n private _collideTickLabelsAnimFrameId: ReturnType<typeof requestAnimationFrame>\n\n protected events = {}\n\n constructor (config?: AxisConfigInterface<Datum>) {\n super()\n if (config) this.setConfig(config)\n this.axisGroup = this.g.append('g')\n this.gridGroup = this.g.append('g')\n .attr('class', s.grid)\n }\n\n /** Renders axis to an invisible grouped to calculate automatic chart margins */\n public preRender (): void {\n const { config } = this\n const axisRenderHelperGroup = this.g.append('g').attr('opacity', 0)\n\n this._renderAxis(axisRenderHelperGroup, 0)\n\n // Store axis raw BBox (without the label) for further label positioning (see _renderAxisLabel)\n this._axisRawBBox = axisRenderHelperGroup.node().getBBox()\n\n // Align tick text\n if (config.tickTextAlign) this._alignTickLabels()\n\n // Render label and store total axis size and required margins\n this._renderAxisLabel(axisRenderHelperGroup)\n this._axisSizeBBox = this._getAxisSize(axisRenderHelperGroup)\n this._requiredMargin = this._getRequiredMargin(this._axisSizeBBox)\n\n axisRenderHelperGroup.remove()\n }\n\n public getPosition (): Position {\n const { config: { type, position } } = this\n return (position ?? ((type === AxisType.X) ? Position.Bottom : Position.Left)) as Position\n }\n\n private _getAxisSize (selection: Selection<SVGGElement, unknown, SVGGElement, undefined>): SVGRect {\n const bBox = selection.node().getBBox()\n return bBox\n }\n\n private _getRequiredMargin (axisSize = this._axisSizeBBox): Spacing {\n const { config: { type, position } } = this\n\n switch (type) {\n case AxisType.X: {\n const tolerancePx = 1\n const xEnd = this._axisSizeBBox.x + this._axisSizeBBox.width\n\n const left = this._axisSizeBBox.x < 0 ? Math.abs(this._axisSizeBBox.x) : 0\n const right = (xEnd - this._width) > tolerancePx ? xEnd - this._width : 0\n\n switch (position) {\n case Position.Top: return { top: axisSize.height, left, right }\n case Position.Bottom: default: return { bottom: axisSize.height, left, right }\n }\n }\n case AxisType.Y: {\n const bleedY = axisSize.height > this._height ? (axisSize.height - this._height) / 2 : 0\n const top = bleedY\n const bottom = bleedY\n\n switch (position) {\n case Position.Right: return { right: axisSize.width, top, bottom }\n case Position.Left: default: return { left: axisSize.width, top, bottom }\n }\n }\n }\n }\n\n getRequiredMargin (): Spacing {\n return this._requiredMargin\n }\n\n /** Calculates axis transform:translate offset based on passed container margins */\n getOffset (containerMargin: Spacing): {left: number; top: number} {\n const { config: { type, position } } = this\n\n switch (type) {\n case AxisType.X:\n switch (position) {\n case Position.Top: return { top: containerMargin.top, left: containerMargin.left }\n case Position.Bottom: default: return { top: containerMargin.top + this._height, left: containerMargin.left }\n }\n case AxisType.Y:\n switch (position) {\n case Position.Right: return { top: containerMargin.top, left: containerMargin.left + this._width }\n case Position.Left: default: return { top: containerMargin.top, left: containerMargin.left }\n }\n }\n }\n\n public _render (duration = this.config.duration, selection = this.axisGroup): void {\n const { config } = this\n\n this._renderAxis(selection, duration)\n this._renderAxisLabel(selection)\n\n if (config.gridLine) {\n const gridGen = this._buildGrid().tickFormat(() => '')\n gridGen.tickValues(this._getConfiguredTickValues())\n // Interrupting all active transitions first to prevent them from being stuck.\n // Somehow we see it happening in Angular apps.\n this.gridGroup.selectAll('*').interrupt()\n smartTransition(this.gridGroup, duration).call(gridGen).style('opacity', 1)\n } else {\n smartTransition(this.gridGroup, duration).style('opacity', 0)\n }\n\n if (config.tickTextAlign) this._alignTickLabels()\n\n this._resolveTickLabelOverlap(selection)\n }\n\n private _buildAxis (): D3Axis<any> {\n const { config: { type, position, tickPadding } } = this\n\n const ticks = this._getNumTicks()\n switch (type) {\n case AxisType.X:\n switch (position) {\n case Position.Top: return axisTop(this.xScale).ticks(ticks).tickPadding(tickPadding)\n case Position.Bottom: default: return axisBottom(this.xScale).ticks(ticks).tickPadding(tickPadding)\n }\n case AxisType.Y:\n switch (position) {\n case Position.Right: return axisRight(this.yScale).ticks(ticks).tickPadding(tickPadding)\n case Position.Left: default: return axisLeft(this.yScale).ticks(ticks).tickPadding(tickPadding)\n }\n }\n }\n\n private _buildGrid (): D3Axis<any> {\n const { config: { type, position } } = this\n\n const ticks = this._getNumTicks()\n switch (type) {\n case AxisType.X:\n switch (position) {\n case Position.Top: return axisTop(this.xScale).ticks(ticks * 2).tickSize(-this._height).tickSizeOuter(0)\n case Position.Bottom: default: return axisBottom(this.xScale).ticks(ticks * 2).tickSize(-this._height).tickSizeOuter(0)\n }\n case AxisType.Y:\n switch (position) {\n case Position.Right: return axisRight(this.yScale).ticks(ticks * 2).tickSize(-this._width).tickSizeOuter(0)\n case Position.Left: default: return axisLeft(this.yScale).ticks(ticks * 2).tickSize(-this._width).tickSizeOuter(0)\n }\n }\n }\n\n private _renderAxis (selection = this.axisGroup, duration = this.config.duration): void {\n const { config } = this\n\n const axisGen = this._buildAxis()\n const tickValues: (number[] | Date[]) = this._getConfiguredTickValues() || axisGen.scale<ContinuousScale>().ticks(this._getNumTicks())\n axisGen.tickValues(tickValues)\n\n // Interrupting all active transitions first to prevent them from being stuck.\n // Somehow we see it happening in Angular apps.\n selection.selectAll('*').interrupt()\n smartTransition(selection, duration).call(axisGen)\n\n const ticks = selection.selectAll<SVGGElement, number | Date>('g.tick')\n\n ticks\n .classed(s.tick, true)\n .style('font-size', config.tickTextFontSize)\n\n // Selecting the <text> elements of the ticks to apply formatting. By default, this selection\n // will include exiting elements, so we're filtering them out.\n const tickText = selection.selectAll<SVGTextElement, number | Date>('g.tick > text')\n .filter(tickValue => tickValues.some((t: number | Date) => isEqual(tickValue, t))) // We use isEqual to compare Dates\n .classed(s.tickLabel, true)\n .classed(s.tickLabelHideable, Boolean(config.tickTextHideOverlapping))\n .style('fill', config.tickTextColor) as Selection<SVGTextElement, number, SVGGElement, unknown> | Selection<SVGTextElement, Date, SVGGElement, unknown>\n\n\n // We interrupt the transition on tick's <text> to make it 'wrappable'\n tickText.nodes().forEach(node => interrupt(node))\n\n tickText.each((value: number | Date, i: number, elements: ArrayLike<SVGTextElement>) => {\n let text = config.tickFormat?.(value as number & Date, i, tickValues as (number & Date)[]) ?? `${value}`\n const textElement = elements[i] as SVGTextElement\n const textMaxWidth = config.tickTextWidth || (config.type === AxisType.X ? this._containerWidth / (ticks.size() + 1) : this._containerWidth / 5)\n const styleDeclaration = getComputedStyle(textElement)\n const fontSize = Number.parseFloat(styleDeclaration.fontSize)\n const fontFamily = styleDeclaration.fontFamily\n const textOptions: UnovisTextOptions = {\n verticalAlign: config.type === AxisType.X ? VerticalAlign.Top : VerticalAlign.Middle,\n width: textMaxWidth,\n textRotationAngle: config.tickTextAngle,\n separator: config.tickTextSeparator,\n wordBreak: config.tickTextForceWordBreak,\n }\n\n if (config.tickTextFitMode === FitMode.Trim) {\n const textElementSelection = select<SVGTextElement, string>(textElement).text(text)\n trimSVGText(textElementSelection, textMaxWidth, config.tickTextTrimType as TrimMode, true, fontSize, 0.58)\n text = select<SVGTextElement, string>(textElement).text()\n }\n\n const textBlock: UnovisText = { text, fontFamily, fontSize }\n renderTextToSvgTextElement(textElement, textBlock, textOptions)\n })\n\n selection\n .classed(s.axis, true)\n .classed(s.hideTickLine, !config.tickLine)\n .classed(s.hideDomain, !config.domainLine)\n\n if (config.fullSize) {\n const path = this._getFullDomainPath(0)\n smartTransition(selection.select('.domain'), duration).attr('d', path)\n }\n }\n\n private _resolveTickLabelOverlap (selection = this.axisGroup): void {\n const { config } = this\n const tickTextSelection = selection.selectAll<SVGTextElement, number | Date>('g.tick > text')\n\n if (!config.tickTextHideOverlapping) {\n tickTextSelection.style('opacity', null)\n return\n }\n\n cancelAnimationFrame(this._collideTickLabelsAnimFrameId)\n // Colliding labels in the next frame to prevent forced reflow\n this._collideTickLabelsAnimFrameId = requestAnimationFrame(() => {\n this._collideTickLabels(tickTextSelection)\n })\n }\n\n private _collideTickLabels (selection: Selection<SVGTextElement, number | Date, SVGGElement, unknown>): void {\n type SVGOverlappingTextElement = SVGTextElement & {\n _visible: boolean;\n }\n\n // Reset visibility of all labels\n selection.each((d, i, elements) => {\n const node = elements[i] as SVGOverlappingTextElement\n node._visible = true\n })\n\n // We do three iterations because not all overlapping labels can be resolved in the first iteration\n const numIterations = 3\n for (let i = 0; i < numIterations; i += 1) {\n // Run collision detection and set labels visibility\n selection.each((d, i, elements) => {\n const label1 = elements[i] as SVGOverlappingTextElement\n const isLabel1Visible = label1._visible\n if (!isLabel1Visible) return\n\n // Calculate bounding rect of point's label\n const label1BoundingRect = label1.getBoundingClientRect()\n\n for (let j = i + 1; j < elements.length; j += 1) {\n if (i === j) continue\n const label2 = elements[j] as SVGOverlappingTextElement\n const isLabel2Visible = label2._visible\n if (isLabel2Visible) {\n const label2BoundingRect = label2.getBoundingClientRect()\n const intersect = rectIntersect(label1BoundingRect, label2BoundingRect, -5)\n if (intersect) {\n label2._visible = false\n break\n }\n }\n }\n })\n }\n\n // Hide the overlapping labels\n selection.each((d, i, elements) => {\n const label = elements[i] as SVGOverlappingTextElement\n select(label).style('opacity', label._visible ? 1 : 0)\n })\n }\n\n private _getNumTicks (): number {\n const { config: { type, numTicks } } = this\n\n if (numTicks) return numTicks\n\n if (type === AxisType.X) {\n const xRange = this.xScale.range() as [number, number]\n const width = xRange[1] - xRange[0]\n return Math.floor(width / 175)\n }\n\n if (type === AxisType.Y) {\n const yRange = this.yScale.range() as [number, number]\n const height = Math.abs(yRange[0] - yRange[1])\n return Math.pow(height, 0.85) / 25\n }\n\n return this._defaultNumTicks\n }\n\n private _getConfiguredTickValues (): number[] | null {\n const { config } = this\n const scale = config.type === AxisType.X ? this.xScale : this.yScale\n const scaleDomain = scale?.domain() as [number, number]\n\n if (config.tickValues) {\n return config.tickValues.filter(v => (v >= scaleDomain[0]) && (v <= scaleDomain[1]))\n }\n\n if (config.minMaxTicksOnly || (config.type === AxisType.X && this._width < config.minMaxTicksOnlyWhenWidthIsLess)) {\n return scaleDomain as number[]\n }\n\n return null\n }\n\n private _getFullDomainPath (tickSize = 0): string {\n const { config: { type } } = this\n switch (type) {\n case AxisType.X: return `M0.5, ${tickSize} V0.5 H${this._width + 0.5} V${tickSize}`\n case AxisType.Y: return `M${-tickSize}, ${this._height + 0.5} H0.5 V0.5 H${-tickSize}`\n }\n }\n\n private _renderAxisLabel (selection = this.axisGroup): void {\n const { type, label, labelMargin, labelFontSize } = this.config\n\n // Remove the old label first to calculate the axis size properly\n selection.selectAll(`.${s.label}`).remove()\n\n // Calculate label position and rotation\n const axisPosition = this.getPosition()\n // We always use this.axisRenderHelperGroup to calculate the size of the axis because\n // this.axisGroup will give us incorrect values due to animation\n const { width: axisWidth, height: axisHeight } = this._axisRawBBox ?? selection.node().getBBox()\n\n const offsetX = type === AxisType.X ? this._width / 2 : (-1) ** (+(axisPosition === Position.Left)) * axisWidth\n const offsetY = type === AxisType.X ? (-1) ** (+(axisPosition === Position.Top)) * axisHeight : this._height / 2\n\n const marginX = type === AxisType.X ? 0 : (-1) ** (+(axisPosition === Position.Left)) * labelMargin\n const marginY = type === AxisType.X ? (-1) ** (+(axisPosition === Position.Top)) * labelMargin : 0\n\n const rotation = type === AxisType.Y ? -90 : 0\n // Append new label\n selection\n .append('text')\n .attr('class', s.label)\n .text(label)\n .attr('dy', `${this._getLabelDY()}em`)\n .attr('transform', `translate(${offsetX + marginX},${offsetY + marginY}) rotate(${rotation})`)\n .style('font-size', labelFontSize)\n .style('fill', this.config.labelColor)\n }\n\n private _getLabelDY (): number {\n const { type, position } = this.config\n switch (type) {\n case AxisType.X:\n switch (position) {\n case Position.Top: return 0\n case Position.Bottom: default: return 0.75\n }\n case AxisType.Y:\n switch (position) {\n case Position.Right: return 0.75\n case Position.Left: default: return -0.25\n }\n }\n }\n\n private _alignTickLabels (): void {\n const { config: { type, tickTextAlign, tickTextAngle, position } } = this\n const tickText = this.g.selectAll('g.tick > text')\n\n const textAnchor = this._getTickTextAnchor(tickTextAlign as TextAlign)\n const translateX = type === AxisType.X\n ? 0\n : this._getYTickTextTranslate(tickTextAlign as TextAlign, position as Position)\n\n const translateValue = tickTextAngle ? `translate(${translateX},0) rotate(${tickTextAngle})` : `translate(${translateX},0)`\n tickText\n .attr('transform', translateValue)\n .attr('text-anchor', textAnchor)\n }\n\n private _getTickTextAnchor (textAlign: TextAlign): string {\n switch (textAlign) {\n case TextAlign.Left: return 'start'\n case TextAlign.Right: return 'end'\n case TextAlign.Center: return 'middle'\n default: return null\n }\n }\n\n private _getYTickTextTranslate (textAlign: TextAlign, axisPosition: Position = Position.Left): number {\n const defaultTickTextSpacingPx = 9 // Default in D3\n const width = this._axisRawBBox.width - defaultTickTextSpacingPx\n\n switch (textAlign) {\n case TextAlign.Left: return axisPosition === Position.Left ? width * -1 : 0\n case TextAlign.Right: return axisPosition === Position.Left ? 0 : width\n case TextAlign.Center: return axisPosition === Position.Left ? width * (-0.5) : width * 0.5\n default: return 0\n }\n }\n}\n"],"names":["_Axis","XYComponentCore","config","AxisDefaultConfig","s.grid","axisRenderHelperGroup","type","position","AxisType","Position","selection","axisSize","xEnd","left","right","bleedY","top","bottom","containerMargin","duration","gridGen","smartTransition","tickPadding","ticks","axisTop","axisBottom","axisRight","axisLeft","axisGen","tickValues","s.tick","tickText","tickValue","t","isEqual","s.tickLabel","s.tickLabelHideable","node","interrupt","value","i","elements","text","_a","textElement","textMaxWidth","styleDeclaration","fontSize","fontFamily","textOptions","VerticalAlign","FitMode","textElementSelection","select","trimSVGText","renderTextToSvgTextElement","s.axis","s.hideTickLine","s.hideDomain","path","tickTextSelection","d","numIterations","label1","label1BoundingRect","j","label2","label2BoundingRect","rectIntersect","label","numTicks","xRange","width","yRange","height","scale","scaleDomain","v","tickSize","labelMargin","labelFontSize","s.label","axisPosition","axisWidth","axisHeight","offsetX","offsetY","marginX","marginY","rotation","tickTextAlign","tickTextAngle","textAnchor","translateX","translateValue","textAlign","TextAlign","s","Axis"],"mappings":"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"}
@@ -6,6 +6,8 @@ export interface TreemapConfigInterface<Datum> extends ComponentConfigInterface
6
6
  value?: NumericAccessor<Datum>;
7
7
  /** Array of accessor functions to defined the nested groups. Default: `[]` */
8
8
  layers: StringAccessor<Datum>[];
9
+ /** A function that accepts a value number and returns a string. Default: `undefined` */
10
+ numberFormat?: (value: number) => string;
9
11
  /** Color accessor function for tiles. Default: `undefined` */
10
12
  tileColor?: ColorAccessor<TreemapNode<Datum>>;
11
13
  /** Padding passed to D3 treemap layout. Default: `2` */
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sources":["../../../src/components/treemap/config.ts"],"sourcesContent":["import { ComponentConfigInterface, ComponentDefaultConfig } from 'core/component/config'\nimport { ColorAccessor, NumericAccessor, StringAccessor } from 'types/accessor'\nimport { TreemapNode } from './types'\n\nexport interface TreemapConfigInterface<Datum> extends ComponentConfigInterface {\n id?: ((d: Datum, i: number) => string | number);\n /* Numeric accessor for segment size value. Default: `undefined`. */\n value?: NumericAccessor<Datum>;\n\n /** Array of accessor functions to defined the nested groups. Default: `[]` */\n layers: StringAccessor<Datum>[];\n\n /** Color accessor function for tiles. Default: `undefined` */\n tileColor?: ColorAccessor<TreemapNode<Datum>>;\n\n /** Padding passed to D3 treemap layout. Default: `2` */\n tilePadding?: number;\n\n /**\n * Top padding passed to D3 treemap layout.\n * Useful to make room for internal node labels.\n * Default: `undefined`\n */\n tilePaddingTop?: number;\n\n /** Label internal nodes. Default: `false` */\n labelInternalNodes?: boolean;\n\n /** Label offset in the X direction. Default: `4` */\n labelOffsetX?: number;\n\n /** Label offset in the Y direction. Default: `4` */\n labelOffsetY?: number;\n}\n\nexport const TreemapDefaultConfig: TreemapConfigInterface<unknown> = {\n ...ComponentDefaultConfig,\n id: (d: unknown, i: number): string | number => (d as { id: string }).id ?? i,\n value: undefined,\n tileColor: undefined,\n layers: [],\n tilePadding: 2,\n tilePaddingTop: undefined,\n labelInternalNodes: false,\n labelOffsetX: 4,\n labelOffsetY: 4,\n}\n"],"names":["TreemapDefaultConfig","ComponentDefaultConfig","d","i"],"mappings":";AAmCO,MAAMA,IAAwD;AAAA,EACnE,GAAGC;AAAA,EACH,IAAI,CAACC,GAAYC,MAAgCD,EAAqB,MAAMC;AAAA,EAC5E,OAAO;AAAA,EACP,WAAW;AAAA,EACX,QAAQ,CAAC;AAAA,EACT,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,oBAAoB;AAAA,EACpB,cAAc;AAAA,EACd,cAAc;AAChB;"}
1
+ {"version":3,"file":"config.js","sources":["../../../src/components/treemap/config.ts"],"sourcesContent":["import { ComponentConfigInterface, ComponentDefaultConfig } from 'core/component/config'\nimport { ColorAccessor, NumericAccessor, StringAccessor } from 'types/accessor'\nimport { TreemapNode } from './types'\n\nexport interface TreemapConfigInterface<Datum> extends ComponentConfigInterface {\n id?: ((d: Datum, i: number) => string | number);\n /* Numeric accessor for segment size value. Default: `undefined`. */\n value?: NumericAccessor<Datum>;\n\n /** Array of accessor functions to defined the nested groups. Default: `[]` */\n layers: StringAccessor<Datum>[];\n\n /** A function that accepts a value number and returns a string. Default: `undefined` */\n numberFormat?: (value: number) => string;\n\n /** Color accessor function for tiles. Default: `undefined` */\n tileColor?: ColorAccessor<TreemapNode<Datum>>;\n\n /** Padding passed to D3 treemap layout. Default: `2` */\n tilePadding?: number;\n\n /**\n * Top padding passed to D3 treemap layout.\n * Useful to make room for internal node labels.\n * Default: `undefined`\n */\n tilePaddingTop?: number;\n\n /** Label internal nodes. Default: `false` */\n labelInternalNodes?: boolean;\n\n /** Label offset in the X direction. Default: `4` */\n labelOffsetX?: number;\n\n /** Label offset in the Y direction. Default: `4` */\n labelOffsetY?: number;\n}\n\nexport const TreemapDefaultConfig: TreemapConfigInterface<unknown> = {\n ...ComponentDefaultConfig,\n id: (d: unknown, i: number): string | number => (d as { id: string }).id ?? i,\n value: undefined,\n tileColor: undefined,\n layers: [],\n tilePadding: 2,\n tilePaddingTop: undefined,\n labelInternalNodes: false,\n labelOffsetX: 4,\n labelOffsetY: 4,\n}\n"],"names":["TreemapDefaultConfig","ComponentDefaultConfig","d","i"],"mappings":";AAsCO,MAAMA,IAAwD;AAAA,EACnE,GAAGC;AAAA,EACH,IAAI,CAACC,GAAYC,MAAgCD,EAAqB,MAAMC;AAAA,EAC5E,OAAO;AAAA,EACP,WAAW;AAAA,EACX,QAAQ,CAAC;AAAA,EACT,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,oBAAoB;AAAA,EACpB,cAAc;AAAA,EACd,cAAc;AAChB;"}
@@ -1,55 +1,59 @@
1
- import { hierarchy as x, treemap as k } from "d3-hierarchy";
2
- import { group as A, max as B } from "d3-array";
3
- import { scaleLinear as L } from "d3-scale";
4
- import { ComponentCore as S } from "../../core/component/index.js";
5
- import { SeriesDataModel as z } from "../../data-models/series.js";
6
- import { getColor as c } from "../../utils/color.js";
7
- import { isNumber as F, getString as I, getNumber as M } from "../../utils/data.js";
8
- import { smartTransition as f } from "../../utils/d3.js";
9
- import { TreemapDefaultConfig as U } from "./config.js";
10
- import * as X from "./style.js";
11
- import { tiles as Y, tile as C, tileBackground as _, tileForeground as b, label as v } from "./style.js";
12
- const p = class p extends S {
13
- constructor(a) {
14
- super(), this._defaultConfig = U, this.config = this._defaultConfig, this.datamodel = new z(), a && this.setConfig(a), this.tiles = this.g.append("g").attr("class", Y);
1
+ import { hierarchy as I, treemap as L } from "d3-hierarchy";
2
+ import { group as S, max as z } from "d3-array";
3
+ import { scaleLinear as M } from "d3-scale";
4
+ import { ComponentCore as U } from "../../core/component/index.js";
5
+ import { SeriesDataModel as X } from "../../data-models/series.js";
6
+ import { getColor as d } from "../../utils/color.js";
7
+ import { isNumber as Y, getString as j, getNumber as q } from "../../utils/data.js";
8
+ import { smartTransition as c } from "../../utils/d3.js";
9
+ import { TreemapDefaultConfig as G } from "./config.js";
10
+ import * as H from "./style.js";
11
+ import { tiles as J, tile as x, tileBackground as _, tileForeground as C, label as $ } from "./style.js";
12
+ const K = (w) => `${w}`, h = class h extends U {
13
+ constructor(l) {
14
+ super(), this._defaultConfig = G, this.config = this._defaultConfig, this.datamodel = new X(), l && this.setConfig(l), this.tiles = this.g.append("g").attr("class", J);
15
15
  }
16
- _render(a) {
16
+ _render(l) {
17
17
  var g;
18
- const { config: r, datamodel: { data: s } } = this, n = F(a) ? a : r.duration;
18
+ const { config: r, datamodel: { data: p }, _width: v, _height: N } = this, n = Y(l) ? l : r.duration, { numberFormat: P = K } = r;
19
19
  if (!((g = r.layers) != null && g.length)) {
20
20
  console.warn("Unovis | Treemap: No layers defined");
21
21
  return;
22
22
  }
23
- const N = r.layers.map((t) => (e) => I(s[e], t, e)), d = A(s.keys(), ...N), D = r.value !== void 0 ? x(d).sum((t) => typeof t == "number" && M(s[t], r.value, t)) : x(d).count(), h = k().size([this._width, this._height]).round(!0).padding(this.config.tilePadding);
24
- this.config.tilePaddingTop !== void 0 && h.paddingTop(this.config.tilePaddingTop);
25
- const m = h(D), y = m.descendants(), O = B(y, (t) => t.depth), T = L().domain([1, O]).range([1, 0.2]);
23
+ const D = r.layers.map((t) => (e) => j(p[e], t, e)), O = S(p.keys(), ...D), o = I(O);
24
+ r.value ? o.sum((t) => typeof t == "number" && q(p[t], r.value, t)) : o.count(), o.each((t) => {
25
+ t.children || (t.parent.children = null);
26
+ });
27
+ const f = L().size([v, N]).round(!0).padding(r.tilePadding);
28
+ this.config.tilePaddingTop !== void 0 && f.paddingTop(r.tilePaddingTop);
29
+ let T = 0;
30
+ o.each((t) => {
31
+ t._id = `node-${T++}`;
32
+ });
33
+ const m = f(o), y = m.descendants(), E = z(y, (t) => t.depth), F = M().domain([1, E]).range([1, 0.2]);
26
34
  m.eachBefore((t) => {
27
- t.children && t.children.forEach((e, P) => {
28
- const o = e, u = c(o, r.tileColor, P, o.depth !== 1);
29
- o._fill = u ?? t._fill, o._fillOpacity = u === null ? T(o.depth) : null;
35
+ t.children && t.children.forEach((e, B) => {
36
+ const s = e, u = d(s, r.tileColor, B, s.depth !== 1);
37
+ s._fill = u ?? t._fill, s._fillOpacity = u === null ? F(s.depth) : null;
30
38
  });
31
39
  });
32
- const $ = y.filter((t) => t.depth > 0), l = this.tiles.selectAll(`g.${C}`).data($, (t) => t._id), i = l.enter().append("g").attr("class", C);
33
- i.append("rect").attr("class", _).attr("x", (t) => t.x0).attr("y", (t) => t.y0).attr("width", (t) => t.x1 - t.x0).attr("height", (t) => t.y1 - t.y0), l.merge(i).select(`rect.${_}`).call(
34
- (t) => f(t, n).attr("x", (e) => e.x0).attr("y", (e) => e.y0).attr("width", (e) => e.x1 - e.x0).attr("height", (e) => e.y1 - e.y0)
35
- ), i.append("rect").attr("class", b).attr("x", (t) => t.x0).attr("y", (t) => t.y0).attr("width", (t) => t.x1 - t.x0).attr("height", (t) => t.y1 - t.y0).style("fill", (t) => t._fill ?? c(t, r.tileColor)).style("fill-opacity", 0), l.merge(i).select(`rect.${b}`).call(
36
- (t) => f(t, n).style("fill", (e) => e._fill ?? c(e, r.tileColor)).style("fill-opacity", (e) => e._fillOpacity ?? 1).attr("x", (e) => e.x0).attr("y", (e) => e.y0).attr("width", (e) => e.x1 - e.x0).attr("height", (e) => e.y1 - e.y0)
37
- ), i.append("text").attr("class", v), l.merge(i).filter(
40
+ const k = y.filter((t) => t.depth > 0), i = this.tiles.selectAll(`g.${x}`).data(k, (t) => t._id), a = i.enter().append("g").attr("class", x);
41
+ a.append("clipPath").attr("id", (t) => `clip-${t._id}`).append("rect"), a.append("rect").attr("class", _).attr("x", (t) => t.x0).attr("y", (t) => t.y0).attr("width", (t) => t.x1 - t.x0).attr("height", (t) => t.y1 - t.y0), i.merge(a).select(`rect.${_}`).call(
42
+ (t) => c(t, n).attr("x", (e) => e.x0).attr("y", (e) => e.y0).attr("width", (e) => e.x1 - e.x0).attr("height", (e) => e.y1 - e.y0)
43
+ ), a.append("rect").attr("class", C).attr("x", (t) => t.x0).attr("y", (t) => t.y0).attr("width", (t) => t.x1 - t.x0).attr("height", (t) => t.y1 - t.y0).style("fill", (t) => t._fill ?? d(t, r.tileColor)).style("fill-opacity", 0), i.merge(a).select(`rect.${C}`).call(
44
+ (t) => c(t, n).style("fill", (e) => e._fill ?? d(e, r.tileColor)).style("fill-opacity", (e) => e._fillOpacity ?? 1).attr("x", (e) => e.x0).attr("y", (e) => e.y0).attr("width", (e) => e.x1 - e.x0).attr("height", (e) => e.y1 - e.y0)
45
+ ), i.merge(a).select("clipPath rect").call(
46
+ (t) => c(t, n).attr("x", (e) => e.x0).attr("y", (e) => e.y0).attr("width", (e) => e.x1 - e.x0).attr("height", (e) => e.y1 - e.y0)
47
+ ), a.append("text").attr("class", $).attr("clip-path", (t) => `url(#clip-${t._id})`), i.merge(a).filter(
38
48
  r.labelInternalNodes ? () => !0 : (t) => !t.children
39
- ).select(`text.${v}`).attr("x", (t) => t.x0 + r.labelOffsetX).attr("y", (t) => t.y0 + r.labelOffsetY).text((t) => {
40
- if (typeof t.data == "number") {
41
- const e = t.data;
42
- return r.value(s[e]);
43
- } else
44
- return t.data[0];
45
- });
46
- const E = l.exit();
47
- f(E, n).style("opacity", 0).remove();
49
+ ).select(`text.${$}`).attr("clip-path", (t) => `url(#clip-${t._id})`).attr("x", (t) => t.x0 + r.labelOffsetX).attr("y", (t) => t.y0 + r.labelOffsetY).text((t) => `${t.data[0]}: ${P(t.value)}`);
50
+ const A = i.exit();
51
+ c(A, n).style("opacity", 0).remove();
48
52
  }
49
53
  };
50
- p.selectors = X;
51
- let w = p;
54
+ h.selectors = H;
55
+ let b = h;
52
56
  export {
53
- w as Treemap
57
+ b as Treemap
54
58
  };
55
59
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/components/treemap/index.ts"],"sourcesContent":["import { Selection } from 'd3-selection'\nimport { hierarchy, treemap } from 'd3-hierarchy'\nimport { group, max } from 'd3-array'\nimport { scaleLinear } from 'd3-scale'\nimport { ComponentCore } from 'core/component'\nimport { SeriesDataModel } from 'data-models/series'\nimport { getColor } from 'utils/color'\nimport { getString, getNumber, isNumber } from 'utils/data'\nimport { smartTransition } from 'utils/d3'\nimport { TreemapConfigInterface, TreemapDefaultConfig } from './config'\nimport { TreemapNode } from './types'\n\nimport * as s from './style'\n\nexport class Treemap<Datum> extends ComponentCore<Datum[], TreemapConfigInterface<Datum>> {\n static selectors = s\n protected _defaultConfig = TreemapDefaultConfig as TreemapConfigInterface<Datum>\n public config: TreemapConfigInterface<Datum> = this._defaultConfig\n\n datamodel: SeriesDataModel<Datum> = new SeriesDataModel()\n tiles: Selection<SVGGElement, unknown, SVGGElement, unknown>\n\n constructor (config?: TreemapConfigInterface<Datum>) {\n super()\n if (config) this.setConfig(config)\n this.tiles = this.g.append('g').attr('class', s.tiles)\n }\n\n _render (customDuration?: number): void {\n const { config, datamodel: { data } } = this\n const duration = isNumber(customDuration) ? customDuration : config.duration\n\n if (!config.layers?.length) {\n console.warn('Unovis | Treemap: No layers defined')\n return\n }\n\n // Map each layer accessor function to get string values from the data array\n const layerAccessors = config.layers.map(layerAccessor => {\n return (i: number) => getString(data[i], layerAccessor, i)\n })\n\n // Group the data indices by the layer accessors to create a hierarchical structure\n const nestedData = group(data.keys(), ...layerAccessors as [(d: number) => string])\n\n const rootNode = config.value !== undefined\n ? hierarchy(nestedData).sum(index => typeof index === 'number' && getNumber(data[index], config.value, index))\n : hierarchy(nestedData).count()\n\n const treemapLayout = treemap()\n .size([this._width, this._height])\n .round(true)\n .padding(this.config.tilePadding)\n\n if (this.config.tilePaddingTop !== undefined) {\n treemapLayout.paddingTop(this.config.tilePaddingTop)\n }\n\n const treemapData = treemapLayout(rootNode) as TreemapNode<Datum>\n\n const descendants = treemapData.descendants()\n\n // Set up the opacity scale based on depth\n const maxDepth = max(descendants, d => d.depth)\n const opacity = scaleLinear()\n .domain([1, maxDepth])\n .range([1, 0.2])\n\n // Set fill color and opacity for each node\n treemapData\n .eachBefore((node) => {\n if (!node.children) return\n node.children.forEach((child, i) => {\n const treemapChild = child as TreemapNode<Datum>\n\n // Calculate color for this child using the color accessor function\n const color = getColor(treemapChild, config.tileColor, i, treemapChild.depth !== 1)\n\n // If no color for this child, use the parent's color\n treemapChild._fill = color ?? (node as TreemapNode<Datum>)._fill\n\n // Set opacity based on depth\n treemapChild._fillOpacity = color === null ? opacity(treemapChild.depth) : null\n })\n })\n\n // Render tiles\n const visibleNodes = descendants.filter(d => d.depth > 0)\n const tiles = this.tiles\n .selectAll<SVGGElement, TreemapNode<Datum>>(`g.${s.tile}`)\n .data(visibleNodes, d => d._id)\n const tilesEnter = tiles\n .enter()\n .append('g')\n .attr('class', s.tile)\n\n // Tile background rectangles\n tilesEnter\n .append('rect')\n .attr('class', s.tileBackground)\n\n // Initialize tile positions so that the initial transition is smooth\n .attr('x', d => d.x0)\n .attr('y', d => d.y0)\n .attr('width', d => d.x1 - d.x0)\n .attr('height', d => d.y1 - d.y0)\n\n tiles.merge(tilesEnter).select(`rect.${s.tileBackground}`)\n .call(selection => smartTransition(selection, duration)\n .attr('x', d => d.x0)\n .attr('y', d => d.y0)\n .attr('width', d => d.x1 - d.x0)\n .attr('height', d => d.y1 - d.y0)\n )\n\n // Tile foreground rectangles\n tilesEnter\n .append('rect')\n .attr('class', s.tileForeground)\n // Initialize tile positions so that the initial transition is smooth\n .attr('x', d => d.x0)\n .attr('y', d => d.y0)\n .attr('width', d => d.x1 - d.x0)\n .attr('height', d => d.y1 - d.y0)\n .style('fill', d => d._fill ?? getColor(d, config.tileColor))\n\n // Make the tiles fade in on enter\n .style('fill-opacity', 0)\n\n tiles.merge(tilesEnter).select(`rect.${s.tileForeground}`)\n .call(selection => smartTransition(selection, duration)\n .style('fill', d => d._fill ?? getColor(d, config.tileColor))\n .style('fill-opacity', d => d._fillOpacity ?? 1)\n .attr('x', d => d.x0)\n .attr('y', d => d.y0)\n .attr('width', d => d.x1 - d.x0)\n .attr('height', d => d.y1 - d.y0)\n )\n\n // Tile labels\n tilesEnter\n .append('text')\n .attr('class', s.label)\n tiles.merge(tilesEnter)\n .filter(config.labelInternalNodes\n ? () => true\n : d => !d.children\n )\n .select(`text.${s.label}`)\n .attr('x', d => d.x0 + config.labelOffsetX)\n .attr('y', d => d.y0 + config.labelOffsetY)\n .text(d => {\n if (typeof d.data === 'number') {\n const index = d.data\n // Leaf node case\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return config.value(data[index])\n } else {\n // Internal node case\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return d.data[0]\n }\n })\n\n // Exit\n const tilesExit = tiles.exit()\n smartTransition(tilesExit, duration)\n .style('opacity', 0)\n .remove()\n }\n}\n"],"names":["_Treemap","ComponentCore","config","TreemapDefaultConfig","SeriesDataModel","s.tiles","customDuration","data","duration","isNumber","_a","layerAccessors","layerAccessor","i","getString","nestedData","group","rootNode","hierarchy","index","getNumber","treemapLayout","treemap","treemapData","descendants","maxDepth","max","d","opacity","scaleLinear","node","child","treemapChild","color","getColor","visibleNodes","tiles","s.tile","tilesEnter","s.tileBackground","selection","smartTransition","s.tileForeground","s.label","tilesExit","s","Treemap"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/components/treemap/index.ts"],"sourcesContent":["import { Selection } from 'd3-selection'\nimport { hierarchy, treemap } from 'd3-hierarchy'\nimport { group, max } from 'd3-array'\nimport { scaleLinear } from 'd3-scale'\nimport { ComponentCore } from 'core/component'\nimport { SeriesDataModel } from 'data-models/series'\nimport { getColor } from 'utils/color'\nimport { getString, getNumber, isNumber } from 'utils/data'\nimport { smartTransition } from 'utils/d3'\nimport { TreemapConfigInterface, TreemapDefaultConfig } from './config'\nimport { TreemapNode } from './types'\n\nimport * as s from './style'\n\nconst defaultNumberFormat = (value: number): string => `${value}`\n\nexport class Treemap<Datum> extends ComponentCore<Datum[], TreemapConfigInterface<Datum>> {\n static selectors = s\n protected _defaultConfig = TreemapDefaultConfig as TreemapConfigInterface<Datum>\n public config: TreemapConfigInterface<Datum> = this._defaultConfig\n\n datamodel: SeriesDataModel<Datum> = new SeriesDataModel()\n tiles: Selection<SVGGElement, unknown, SVGGElement, unknown>\n\n constructor (config?: TreemapConfigInterface<Datum>) {\n super()\n if (config) this.setConfig(config)\n this.tiles = this.g.append('g').attr('class', s.tiles)\n }\n\n _render (customDuration?: number): void {\n const { config, datamodel: { data }, _width, _height } = this\n const duration = isNumber(customDuration) ? customDuration : config.duration\n const { numberFormat = defaultNumberFormat } = config\n\n if (!config.layers?.length) {\n console.warn('Unovis | Treemap: No layers defined')\n return\n }\n\n // Map each layer accessor function to get string values from the data array\n const layerAccessors = config.layers.map(layerAccessor => {\n return (i: number) => getString(data[i], layerAccessor, i)\n })\n\n // Group the data indices by the layer accessors to create a hierarchical structure\n const nestedData = group(data.keys(), ...layerAccessors as [(d: number) => string])\n\n // Create the hierarchy from the grouped data,\n // which by itself is not quite right because there is an extra\n // level of nesting that we don't want, just above the leaf nodes.\n const rootNode = hierarchy(nestedData)\n\n // Compute the aggregation\n if (config.value) {\n rootNode.sum(index => typeof index === 'number' && getNumber(data[index], config.value, index))\n } else {\n rootNode.count()\n }\n\n // Fix the hierarchy by removing the extra level of nesting\n rootNode.each(d => {\n if (!d.children) {\n d.parent.children = null\n }\n })\n\n const treemapLayout = treemap()\n .size([_width, _height])\n .round(true)\n .padding(config.tilePadding)\n\n if (this.config.tilePaddingTop !== undefined) {\n treemapLayout.paddingTop(config.tilePaddingTop)\n }\n\n // Generate unique IDs for each node before creating the treemap layout\n let nodeId = 0\n rootNode.each(d => {\n (d as unknown as TreemapNode<Datum>)._id = `node-${nodeId++}`\n })\n\n const treemapData = treemapLayout(rootNode) as TreemapNode<Datum>\n const descendants = treemapData.descendants()\n\n // Set up the opacity scale based on depth\n const maxDepth = max(descendants, d => d.depth)\n const opacity = scaleLinear()\n .domain([1, maxDepth])\n .range([1, 0.2])\n\n // Set fill color and opacity for each node\n treemapData\n .eachBefore((node) => {\n if (!node.children) return\n node.children.forEach((child, i) => {\n const treemapChild = child as TreemapNode<Datum>\n\n // Calculate color for this child using the color accessor function\n const color = getColor(treemapChild, config.tileColor, i, treemapChild.depth !== 1)\n\n // If no color for this child, use the parent's color\n treemapChild._fill = color ?? (node as TreemapNode<Datum>)._fill\n\n // Set opacity based on depth\n treemapChild._fillOpacity = color === null ? opacity(treemapChild.depth) : null\n })\n })\n\n // Render tiles\n const visibleNodes = descendants.filter(d => d.depth > 0)\n const tiles = this.tiles\n .selectAll<SVGGElement, TreemapNode<Datum>>(`g.${s.tile}`)\n .data(visibleNodes, d => d._id)\n const tilesEnter = tiles\n .enter()\n .append('g')\n .attr('class', s.tile)\n\n // Add clipPath elements\n tilesEnter\n .append('clipPath')\n .attr('id', d => `clip-${d._id}`)\n .append('rect')\n\n // Tile background rectangles\n tilesEnter\n .append('rect')\n .attr('class', s.tileBackground)\n\n // Initialize tile positions so that the initial transition is smooth\n .attr('x', d => d.x0)\n .attr('y', d => d.y0)\n .attr('width', d => d.x1 - d.x0)\n .attr('height', d => d.y1 - d.y0)\n\n tiles.merge(tilesEnter).select(`rect.${s.tileBackground}`)\n .call(selection => smartTransition(selection, duration)\n .attr('x', d => d.x0)\n .attr('y', d => d.y0)\n .attr('width', d => d.x1 - d.x0)\n .attr('height', d => d.y1 - d.y0)\n )\n\n // Tile foreground rectangles\n tilesEnter\n .append('rect')\n .attr('class', s.tileForeground)\n // Initialize tile positions so that the initial transition is smooth\n .attr('x', d => d.x0)\n .attr('y', d => d.y0)\n .attr('width', d => d.x1 - d.x0)\n .attr('height', d => d.y1 - d.y0)\n .style('fill', d => d._fill ?? getColor(d, config.tileColor))\n\n // Make the tiles fade in on enter\n .style('fill-opacity', 0)\n\n tiles.merge(tilesEnter).select(`rect.${s.tileForeground}`)\n .call(selection => smartTransition(selection, duration)\n .style('fill', d => d._fill ?? getColor(d, config.tileColor))\n .style('fill-opacity', d => d._fillOpacity ?? 1)\n .attr('x', d => d.x0)\n .attr('y', d => d.y0)\n .attr('width', d => d.x1 - d.x0)\n .attr('height', d => d.y1 - d.y0)\n )\n\n // Update clipPath rects\n tiles.merge(tilesEnter).select('clipPath rect')\n .call(selection => smartTransition(selection, duration)\n .attr('x', d => d.x0)\n .attr('y', d => d.y0)\n .attr('width', d => d.x1 - d.x0)\n .attr('height', d => d.y1 - d.y0)\n )\n\n // Tile labels\n tilesEnter\n .append('text')\n .attr('class', s.label)\n .attr('clip-path', d => `url(#clip-${d._id})`)\n tiles.merge(tilesEnter)\n .filter(config.labelInternalNodes\n ? () => true\n : d => !d.children\n )\n .select(`text.${s.label}`)\n .attr('clip-path', d => `url(#clip-${d._id})`)\n .attr('x', d => d.x0 + config.labelOffsetX)\n .attr('y', d => d.y0 + config.labelOffsetY)\n .text(d => {\n // @ts-expect-error This is a workaround for the D3 types\n return `${d.data[0]}: ${numberFormat(d.value)}`\n })\n\n // Exit\n const tilesExit = tiles.exit()\n smartTransition(tilesExit, duration)\n .style('opacity', 0)\n .remove()\n }\n}\n"],"names":["defaultNumberFormat","value","_Treemap","ComponentCore","config","TreemapDefaultConfig","SeriesDataModel","s.tiles","customDuration","data","_width","_height","duration","isNumber","numberFormat","_a","layerAccessors","layerAccessor","i","getString","nestedData","group","rootNode","hierarchy","index","getNumber","d","treemapLayout","treemap","nodeId","treemapData","descendants","maxDepth","max","opacity","scaleLinear","node","child","treemapChild","color","getColor","visibleNodes","tiles","s.tile","tilesEnter","s.tileBackground","selection","smartTransition","s.tileForeground","s.label","tilesExit","s","Treemap"],"mappings":"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"}
@@ -16,10 +16,7 @@ const t = {
16
16
  "--vis-dark-treemap-label-text-color": "#fff"
17
17
  }, r = e`
18
18
  label: treemap-component;
19
- width: 100%;
20
- height: 100%;
21
- position: relative;
22
- `, s = l(t);
19
+ `, i = l(t);
23
20
  o(t, r);
24
21
  const c = e`
25
22
  label: g-tiles;
@@ -44,6 +41,6 @@ export {
44
41
  f as tileBackground,
45
42
  b as tileForeground,
46
43
  c as tiles,
47
- s as variables
44
+ i as variables
48
45
  };
49
46
  //# sourceMappingURL=style.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"style.js","sources":["../../../src/components/treemap/style.ts"],"sourcesContent":["import { css } from '@emotion/css'\n\n// Utils\nimport { getCssVarNames, injectGlobalCssVariables } from 'utils/style'\n\nconst cssVarDefaults = {\n '--vis-treemap-tile-stroke-color': '#fff',\n '--vis-treemap-tile-stroke-width': '1px',\n '--vis-treemap-tile-fill-color': '#B9BEC3',\n '--vis-treemap-tile-background-color': '#fff',\n '--vis-treemap-tile-cursor': 'default',\n /* Undefined by default to allow proper fallback to var(--vis-font-family) */\n '--vis-treemap-label-font-family': undefined as undefined,\n '--vis-treemap-label-text-color': '#5b5f6d',\n '--vis-treemap-label-font-size': '12px',\n\n /* Dark Theme */\n '--vis-dark-treemap-tile-stroke-color': '#2c2c2c',\n '--vis-dark-treemap-tile-fill-color': '#5b5f6d',\n '--vis-dark-treemap-label-text-color': '#fff',\n}\n\nexport const root = css`\n label: treemap-component;\n width: 100%;\n height: 100%;\n position: relative;\n`\n\nexport const variables = getCssVarNames(cssVarDefaults)\ninjectGlobalCssVariables(cssVarDefaults, root)\n\nexport const tiles = css`\n label: g-tiles;\n`\n\nexport const tile = css`\n label: tile;\n`\n\nexport const tileBackground = css`\n label: tile-background;\n fill: var(--vis-treemap-tile-background-color);\n`\n\nexport const tileForeground = css`\n label: tile-foreground;\n`\n\nexport const label = css`\n label: label;\n text-anchor: start;\n dominant-baseline: hanging;\n user-select: none;\n font-size: var(--vis-treemap-label-font-size);\n`\n"],"names":["cssVarDefaults","root","css","variables","getCssVarNames","injectGlobalCssVariables","tiles","tile","tileBackground","tileForeground","label"],"mappings":";;AAKA,MAAMA,IAAiB;AAAA,EACrB,mCAAmC;AAAA,EACnC,mCAAmC;AAAA,EACnC,iCAAiC;AAAA,EACjC,uCAAuC;AAAA,EACvC,6BAA6B;AAAA;AAAA,EAE7B,mCAAmC;AAAA,EACnC,kCAAkC;AAAA,EAClC,iCAAiC;AAAA;AAAA,EAGjC,wCAAwC;AAAA,EACxC,sCAAsC;AAAA,EACtC,uCAAuC;AACzC,GAEaC,IAAOC;AAAA;AAAA;AAAA;AAAA;AAAA,GAOPC,IAAYC,EAAeJ,CAAc;AACtDK,EAAyBL,GAAgBC,CAAI;AAEtC,MAAMK,IAAQJ;AAAA;AAAA,GAIRK,IAAOL;AAAA;AAAA,GAIPM,IAAiBN;AAAA;AAAA;AAAA,GAKjBO,IAAiBP;AAAA;AAAA,GAIjBQ,IAAQR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;"}
1
+ {"version":3,"file":"style.js","sources":["../../../src/components/treemap/style.ts"],"sourcesContent":["import { css } from '@emotion/css'\n\n// Utils\nimport { getCssVarNames, injectGlobalCssVariables } from 'utils/style'\n\nconst cssVarDefaults = {\n '--vis-treemap-tile-stroke-color': '#fff',\n '--vis-treemap-tile-stroke-width': '1px',\n '--vis-treemap-tile-fill-color': '#B9BEC3',\n '--vis-treemap-tile-background-color': '#fff',\n '--vis-treemap-tile-cursor': 'default',\n /* Undefined by default to allow proper fallback to var(--vis-font-family) */\n '--vis-treemap-label-font-family': undefined as undefined,\n '--vis-treemap-label-text-color': '#5b5f6d',\n '--vis-treemap-label-font-size': '12px',\n\n /* Dark Theme */\n '--vis-dark-treemap-tile-stroke-color': '#2c2c2c',\n '--vis-dark-treemap-tile-fill-color': '#5b5f6d',\n '--vis-dark-treemap-label-text-color': '#fff',\n}\n\nexport const root = css`\n label: treemap-component;\n`\n\nexport const variables = getCssVarNames(cssVarDefaults)\ninjectGlobalCssVariables(cssVarDefaults, root)\n\nexport const tiles = css`\n label: g-tiles;\n`\n\nexport const tile = css`\n label: tile;\n`\n\nexport const tileBackground = css`\n label: tile-background;\n fill: var(--vis-treemap-tile-background-color);\n`\n\nexport const tileForeground = css`\n label: tile-foreground;\n`\n\nexport const label = css`\n label: label;\n text-anchor: start;\n dominant-baseline: hanging;\n user-select: none;\n font-size: var(--vis-treemap-label-font-size);\n`\n"],"names":["cssVarDefaults","root","css","variables","getCssVarNames","injectGlobalCssVariables","tiles","tile","tileBackground","tileForeground","label"],"mappings":";;AAKA,MAAMA,IAAiB;AAAA,EACrB,mCAAmC;AAAA,EACnC,mCAAmC;AAAA,EACnC,iCAAiC;AAAA,EACjC,uCAAuC;AAAA,EACvC,6BAA6B;AAAA;AAAA,EAE7B,mCAAmC;AAAA,EACnC,kCAAkC;AAAA,EAClC,iCAAiC;AAAA;AAAA,EAGjC,wCAAwC;AAAA,EACxC,sCAAsC;AAAA,EACtC,uCAAuC;AACzC,GAEaC,IAAOC;AAAA;AAAA,GAIPC,IAAYC,EAAeJ,CAAc;AACtDK,EAAyBL,GAAgBC,CAAI;AAEtC,MAAMK,IAAQJ;AAAA;AAAA,GAIRK,IAAOL;AAAA;AAAA,GAIPM,IAAiBN;AAAA;AAAA;AAAA,GAKjBO,IAAiBP;AAAA;AAAA,GAIjBQ,IAAQR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@unovis/ts",
3
3
  "description": "Modular data visualization framework for React, Angular, Svelte, Vue, Solid, and vanilla TypeScript or JavaScript",
4
- "version": "1.5.1-exf.10",
4
+ "version": "1.5.1-exf.11",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/f5/unovis.git",
@@ -33,9 +33,9 @@
33
33
  "lib/styles/index.js"
34
34
  ],
35
35
  "scripts": {
36
- "build": "sha=$(tar cf - ./src | shasum); if [[ $(echo $sha) == $(< .srcsha) ]] && [[ -d \"./lib\" ]]; then echo \"Lib Build Exists\"; else npm run forcebuild; echo $sha > .srcsha; fi",
36
+ "build": "sha=$(tar cf - ./src | shasum); if [[ $(echo $sha) == $(< .srcsha) ]] && [[ -d \"./lib\" ]]; then echo \"Lib Build Exists\"; else npm run forcebuild; echo $sha > .srcsha; fi; cp ./{LICENSE,README.md,package.json} ./lib",
37
37
  "forcebuild": "vite build",
38
- "publish:dist": "rm -rf lib/.cache; cp ./{LICENSE,README.md,package.json} ./lib; cd ./lib; npm publish",
38
+ "publish:dist": "rm -rf lib/.cache; cd ./lib; npm publish",
39
39
  "type:check": "tsc --noEmit"
40
40
  },
41
41
  "devDependencies": {