@plenustech/design-system 0.2.3 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/charts/ChartGauge/ChartGauge.cjs +2 -0
- package/dist/components/charts/ChartGauge/ChartGauge.cjs.map +1 -0
- package/dist/components/charts/ChartGauge/ChartGauge.js +307 -0
- package/dist/components/charts/ChartGauge/ChartGauge.js.map +1 -0
- package/dist/components/charts/ChartGauge/ChartGauge.module.css.cjs +2 -0
- package/dist/components/charts/ChartGauge/ChartGauge.module.css.cjs.map +1 -0
- package/dist/components/charts/ChartGauge/ChartGauge.module.css.js +76 -0
- package/dist/components/charts/ChartGauge/ChartGauge.module.css.js.map +1 -0
- package/dist/components/charts/ChartGauge/gaugeLayout.cjs +2 -0
- package/dist/components/charts/ChartGauge/gaugeLayout.cjs.map +1 -0
- package/dist/components/charts/ChartGauge/gaugeLayout.js +107 -0
- package/dist/components/charts/ChartGauge/gaugeLayout.js.map +1 -0
- package/dist/components/charts/ChartGauge/gaugeReading.cjs +2 -0
- package/dist/components/charts/ChartGauge/gaugeReading.cjs.map +1 -0
- package/dist/components/charts/ChartGauge/gaugeReading.js +112 -0
- package/dist/components/charts/ChartGauge/gaugeReading.js.map +1 -0
- package/dist/components/charts/ChartGauge/gaugeScale.cjs +2 -0
- package/dist/components/charts/ChartGauge/gaugeScale.cjs.map +1 -0
- package/dist/components/charts/ChartGauge/gaugeScale.js +57 -0
- package/dist/components/charts/ChartGauge/gaugeScale.js.map +1 -0
- package/dist/components/charts/ChartMap/ChartMap.cjs +2 -0
- package/dist/components/charts/ChartMap/ChartMap.cjs.map +1 -0
- package/dist/components/charts/ChartMap/ChartMap.js +523 -0
- package/dist/components/charts/ChartMap/ChartMap.js.map +1 -0
- package/dist/components/charts/ChartMap/ChartMap.module.css.cjs +2 -0
- package/dist/components/charts/ChartMap/ChartMap.module.css.cjs.map +1 -0
- package/dist/components/charts/ChartMap/ChartMap.module.css.js +124 -0
- package/dist/components/charts/ChartMap/ChartMap.module.css.js.map +1 -0
- package/dist/components/charts/ChartMap/ChartMapLegend.cjs +2 -0
- package/dist/components/charts/ChartMap/ChartMapLegend.cjs.map +1 -0
- package/dist/components/charts/ChartMap/ChartMapLegend.js +102 -0
- package/dist/components/charts/ChartMap/ChartMapLegend.js.map +1 -0
- package/dist/components/charts/ChartMap/ChartMapTable.cjs +2 -0
- package/dist/components/charts/ChartMap/ChartMapTable.cjs.map +1 -0
- package/dist/components/charts/ChartMap/ChartMapTable.js +118 -0
- package/dist/components/charts/ChartMap/ChartMapTable.js.map +1 -0
- package/dist/components/charts/ChartMap/mapGeometry.cjs +2 -0
- package/dist/components/charts/ChartMap/mapGeometry.cjs.map +1 -0
- package/dist/components/charts/ChartMap/mapGeometry.js +113 -0
- package/dist/components/charts/ChartMap/mapGeometry.js.map +1 -0
- package/dist/components/charts/ChartMap/mapLabels.cjs +2 -0
- package/dist/components/charts/ChartMap/mapLabels.cjs.map +1 -0
- package/dist/components/charts/ChartMap/mapLabels.js +80 -0
- package/dist/components/charts/ChartMap/mapLabels.js.map +1 -0
- package/dist/components/charts/ChartMap/mapScales.cjs +2 -0
- package/dist/components/charts/ChartMap/mapScales.cjs.map +1 -0
- package/dist/components/charts/ChartMap/mapScales.js +131 -0
- package/dist/components/charts/ChartMap/mapScales.js.map +1 -0
- package/dist/components/charts/ChartMap/polylabel.cjs +2 -0
- package/dist/components/charts/ChartMap/polylabel.cjs.map +1 -0
- package/dist/components/charts/ChartMap/polylabel.js +50 -0
- package/dist/components/charts/ChartMap/polylabel.js.map +1 -0
- package/dist/components/charts/ChartTimeline/ChartTimeline.cjs +2 -0
- package/dist/components/charts/ChartTimeline/ChartTimeline.cjs.map +1 -0
- package/dist/components/charts/ChartTimeline/ChartTimeline.js +703 -0
- package/dist/components/charts/ChartTimeline/ChartTimeline.js.map +1 -0
- package/dist/components/charts/ChartTimeline/ChartTimeline.module.css.cjs +2 -0
- package/dist/components/charts/ChartTimeline/ChartTimeline.module.css.cjs.map +1 -0
- package/dist/components/charts/ChartTimeline/ChartTimeline.module.css.js +124 -0
- package/dist/components/charts/ChartTimeline/ChartTimeline.module.css.js.map +1 -0
- package/dist/components/charts/ChartTimeline/ChartTimelineTable.cjs +2 -0
- package/dist/components/charts/ChartTimeline/ChartTimelineTable.cjs.map +1 -0
- package/dist/components/charts/ChartTimeline/ChartTimelineTable.js +42 -0
- package/dist/components/charts/ChartTimeline/ChartTimelineTable.js.map +1 -0
- package/dist/components/charts/ChartTimeline/timelineLayout.cjs +2 -0
- package/dist/components/charts/ChartTimeline/timelineLayout.cjs.map +1 -0
- package/dist/components/charts/ChartTimeline/timelineLayout.js +109 -0
- package/dist/components/charts/ChartTimeline/timelineLayout.js.map +1 -0
- package/dist/components/charts/ChartTimeline/timelineTime.cjs +2 -0
- package/dist/components/charts/ChartTimeline/timelineTime.cjs.map +1 -0
- package/dist/components/charts/ChartTimeline/timelineTime.js +91 -0
- package/dist/components/charts/ChartTimeline/timelineTime.js.map +1 -0
- package/dist/components/charts/ChartTimeline/timelineTooltip.cjs +2 -0
- package/dist/components/charts/ChartTimeline/timelineTooltip.cjs.map +1 -0
- package/dist/components/charts/ChartTimeline/timelineTooltip.js +77 -0
- package/dist/components/charts/ChartTimeline/timelineTooltip.js.map +1 -0
- package/dist/components/charts/core/ChartLegend.cjs +1 -1
- package/dist/components/charts/core/ChartLegend.cjs.map +1 -1
- package/dist/components/charts/core/ChartLegend.js +37 -25
- package/dist/components/charts/core/ChartLegend.js.map +1 -1
- package/dist/components/charts/core/useChartMetrics.cjs +1 -1
- package/dist/components/charts/core/useChartMetrics.cjs.map +1 -1
- package/dist/components/charts/core/useChartMetrics.js +20 -25
- package/dist/components/charts/core/useChartMetrics.js.map +1 -1
- package/dist/components/data-display/List/List.cjs.map +1 -1
- package/dist/components/data-display/List/List.js.map +1 -1
- package/dist/components/data-display/List/List.module.css.cjs +1 -1
- package/dist/components/data-display/List/List.module.css.js +34 -24
- package/dist/components/data-display/List/List.module.css.js.map +1 -1
- package/dist/components/data-display/List/ListingOptions.cjs +1 -1
- package/dist/components/data-display/List/ListingOptions.cjs.map +1 -1
- package/dist/components/data-display/List/ListingOptions.js +98 -74
- package/dist/components/data-display/List/ListingOptions.js.map +1 -1
- package/dist/components/data-display/List/useListing.cjs.map +1 -1
- package/dist/components/data-display/List/useListing.js.map +1 -1
- package/dist/components/forms/ComboBox/ComboBox.cjs.map +1 -1
- package/dist/components/forms/ComboBox/ComboBox.js.map +1 -1
- package/dist/components/navigation/TabsNav/TabsNav.cjs +2 -0
- package/dist/components/navigation/TabsNav/TabsNav.cjs.map +1 -0
- package/dist/components/navigation/TabsNav/TabsNav.js +21 -0
- package/dist/components/navigation/TabsNav/TabsNav.js.map +1 -0
- package/dist/components/navigation/TabsNav/TabsNav.module.css.cjs +2 -0
- package/dist/components/navigation/TabsNav/TabsNav.module.css.cjs.map +1 -0
- package/dist/components/navigation/TabsNav/TabsNav.module.css.js +18 -0
- package/dist/components/navigation/TabsNav/TabsNav.module.css.js.map +1 -0
- package/dist/components/overlays/Dialog/Dialog.cjs.map +1 -1
- package/dist/components/overlays/Dialog/Dialog.js.map +1 -1
- package/dist/components/overlays/Dialog/DialogFrame.cjs +1 -1
- package/dist/components/overlays/Dialog/DialogFrame.cjs.map +1 -1
- package/dist/components/overlays/Dialog/DialogFrame.js +30 -30
- package/dist/components/overlays/Dialog/DialogFrame.js.map +1 -1
- package/dist/components/overlays/Drawer/Drawer.cjs.map +1 -1
- package/dist/components/overlays/Drawer/Drawer.js.map +1 -1
- package/dist/design-system.css +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +184 -174
- package/dist/index.js.map +1 -1
- package/dist/types/components/charts/ChartGauge/ChartGauge.d.ts +83 -0
- package/dist/types/components/charts/ChartGauge/gaugeLayout.d.ts +64 -0
- package/dist/types/components/charts/ChartGauge/gaugeReading.d.ts +97 -0
- package/dist/types/components/charts/ChartGauge/gaugeScale.d.ts +38 -0
- package/dist/types/components/charts/ChartGauge/index.d.ts +2 -0
- package/dist/types/components/charts/ChartMap/ChartMap.d.ts +104 -0
- package/dist/types/components/charts/ChartMap/ChartMapLegend.d.ts +44 -0
- package/dist/types/components/charts/ChartMap/ChartMapTable.d.ts +38 -0
- package/dist/types/components/charts/ChartMap/index.d.ts +4 -0
- package/dist/types/components/charts/ChartMap/mapGeometry.d.ts +56 -0
- package/dist/types/components/charts/ChartMap/mapLabels.d.ts +51 -0
- package/dist/types/components/charts/ChartMap/mapScales.d.ts +76 -0
- package/dist/types/components/charts/ChartMap/polylabel.d.ts +9 -0
- package/dist/types/components/charts/ChartTimeline/ChartTimeline.d.ts +137 -0
- package/dist/types/components/charts/ChartTimeline/ChartTimelineTable.d.ts +25 -0
- package/dist/types/components/charts/ChartTimeline/index.d.ts +2 -0
- package/dist/types/components/charts/ChartTimeline/timelineLayout.d.ts +70 -0
- package/dist/types/components/charts/ChartTimeline/timelineTime.d.ts +16 -0
- package/dist/types/components/charts/ChartTimeline/timelineTooltip.d.ts +45 -0
- package/dist/types/components/charts/core/ChartLegend.d.ts +3 -1
- package/dist/types/components/data-display/List/List.d.ts +1 -1
- package/dist/types/components/data-display/List/useListing.d.ts +7 -1
- package/dist/types/components/forms/ComboBox/ComboBox.d.ts +7 -1
- package/dist/types/components/navigation/TabsNav/TabsNav.d.ts +20 -0
- package/dist/types/components/navigation/TabsNav/index.d.ts +2 -0
- package/dist/types/components/overlays/Dialog/Dialog.d.ts +19 -7
- package/dist/types/components/overlays/Dialog/DialogFrame.d.ts +8 -2
- package/dist/types/components/overlays/Drawer/Drawer.d.ts +2 -2
- package/dist/types/index.d.ts +9 -1
- package/dist/types/utils/formatters/formatarDuracao.d.ts +5 -0
- package/dist/types/utils/formatters/index.d.ts +1 -0
- package/dist/utils/formatters/formatarDuracao.cjs +2 -0
- package/dist/utils/formatters/formatarDuracao.cjs.map +1 -0
- package/dist/utils/formatters/formatarDuracao.js +10 -0
- package/dist/utils/formatters/formatarDuracao.js.map +1 -0
- package/package.json +3 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gaugeLayout.cjs","sources":["../../../../src/components/charts/ChartGauge/gaugeLayout.ts"],"sourcesContent":["import { measureLabel, truncateToWidth, type LabelFont } from '../core';\nimport type { ChartGaugeScaleLabels, ChartGaugeTicks } from './ChartGauge';\nimport type { CenterLine, GaugeCenter } from './gaugeReading';\n\n/** Até essa meia-abertura o arco é uma meia-lua, e o centro se apoia na linha de base. */\nconst SEMICIRCLE_LIMIT = (95 * Math.PI) / 180;\nconst SEARCH_STEPS = 24;\nconst OUTSIDE_LABEL_GAP = 5;\n\nexport type TextAnchor = 'start' | 'middle' | 'end';\n\nexport interface AngledLabel {\n angle: number;\n text: string;\n}\n\nexport interface OutsideLabel extends AngledLabel {\n kind: 'segment' | 'target';\n}\n\nexport interface PlacedLabel<T extends AngledLabel = AngledLabel> {\n anchor: TextAnchor;\n label: T;\n x: number;\n y: number;\n}\n\nexport interface GaugeLayoutInput {\n center: GaugeCenter;\n compact: boolean;\n /** Radianos a partir do topo, no sentido horário. */\n endAngle: number;\n font: LabelFont;\n height: number;\n /** Rótulos de ponta, mínimo e máximo, quando `scaleLabels` é `minMax`. */\n minMaxLabels: readonly [AngledLabel, AngledLabel];\n needle: boolean;\n /** Régua e marca da meta, além do raio externo do arco. */\n outerBand: number;\n outsideLabels: readonly OutsideLabel[];\n scaleLabels: ChartGaugeScaleLabels;\n startAngle: number;\n thickness: number;\n /** Rótulos das marcas principais, na ordem em que disputam espaço. */\n tickLabels: readonly AngledLabel[];\n ticks: ChartGaugeTicks;\n width: number;\n}\n\nexport interface GaugeCenterLayout {\n height: number;\n lineHeight: number;\n lines: readonly CenterLine[];\n top: number;\n value?: { family: string; size: number; text: string };\n width: number;\n}\n\nexport interface GaugeLayout {\n center: GaugeCenterLayout;\n cx: number;\n cy: number;\n innerRadius: number;\n outsideLabels: readonly PlacedLabel<OutsideLabel>[];\n pinRadius: number;\n radius: number;\n scaleLabels: readonly PlacedLabel[];\n thickness: number;\n}\n\ninterface Box {\n x0: number;\n x1: number;\n y0: number;\n y1: number;\n}\n\nexport function pointAt(angle: number, radius: number): [number, number] {\n return [radius * Math.sin(angle), -radius * Math.cos(angle)];\n}\n\nfunction lineText(line: CenterLine) {\n if (line.kind === 'text') {\n return line.text;\n }\n\n return line.kind === 'delta' && line.label ? `${line.glyph} ${line.text} ${line.label}` : `${line.glyph} ${line.text}`;\n}\n\nfunction anchorX(anchor: TextAnchor, x: number, width: number) {\n return anchor === 'start' ? x : anchor === 'end' ? x - width : x - width / 2;\n}\n\n/** Rótulo que colide com um já posto não entra. */\nfunction place(placed: Box[], box: Box) {\n if (placed.some((other) => box.x0 < other.x1 && box.x1 > other.x0 && box.y0 < other.y1 && box.y1 > other.y0)) {\n return false;\n }\n\n placed.push(box);\n return true;\n}\n\n/**\n * O centro cabe no vazio do arco: o valor desce na escala tipográfica até caber, e as linhas que não cabem saem, de\n * baixo para cima. Na meia-lua com ponteiro, o bloco vai para baixo do pino, fora do arco.\n */\nfunction layoutCenter(radius: number, input: GaugeLayoutInput, tickLabelWidth: number) {\n const { center, compact, font, needle, scaleLabels, ticks } = input;\n const thickness = Math.min(input.thickness, radius * 0.42);\n const innerRadius = radius - thickness;\n const semicircle = Math.max(Math.abs(input.startAngle), Math.abs(input.endAngle)) <= SEMICIRCLE_LIMIT;\n const belowPin = needle && semicircle;\n const pinRadius = compact ? 4 : 7;\n const lineHeight = font.lineHeight;\n const inset = (ticks !== 'hidden' ? 10 : 3) + (scaleLabels === 'ticks' ? 14 + 0.35 * tickLabelWidth : 0);\n const room = Math.max(innerRadius - inset, 6);\n const maxWidth = belowPin\n ? Infinity\n : (!needle && (semicircle || scaleLabels !== 'ticks') ? 1.8 : 1.6) * room;\n const maxHeight = belowPin ? Infinity : semicircle ? room * 0.92 : needle ? room * 0.8 - pinRadius : room * 1.45;\n\n const measure = (line: CenterLine) => measureLabel(lineText(line), font);\n // A linha larga demais tenta a forma curta antes de sair.\n const shortened = (line: CenterLine): CenterLine => {\n if (measure(line) <= maxWidth) return line;\n if (line.kind === 'delta') return { ...line, label: undefined };\n return line.kind === 'warn' ? { ...line, text: line.short } : line;\n };\n const fitted = center.lines.map(shortened).filter((line) => measure(line) <= maxWidth);\n\n const cap = radius * (compact ? 0.36 : 0.3);\n const steps = font.centerSteps.filter((step) => step.size <= cap);\n const candidates = steps.length > 0 ? steps : font.centerSteps.slice(-1);\n const linesHeight = fitted.length * lineHeight + 4;\n\n // Na meia-lua sem ponteiro, o valor fica no alto do bloco, onde a corda do arco é mais curta.\n const roomFor = (size: number) => {\n const chordY = linesHeight + size * 0.8;\n if (belowPin) return 1.6 * room;\n if (semicircle && !needle) return 1.84 * Math.sqrt(Math.max(room * room - chordY * chordY, room * room * 0.2));\n return 0.95 * maxWidth;\n };\n\n let value: GaugeCenterLayout['value'];\n\n if (center.value !== undefined) {\n const fontOf = (size: number, display: boolean) => ({ ...font, family: display ? font.headingFamily : font.family, size });\n const step =\n candidates.find((option) => measureLabel(center.value!, fontOf(option.size, option.display)) <= roomFor(option.size)) ??\n candidates[candidates.length - 1];\n const stepFont = fontOf(step.size, step.display);\n value = { family: stepFont.family, size: step.size, text: truncateToWidth(center.value, stepFont, roomFor(step.size)) };\n }\n\n const lines = [...fitted];\n const heightOf = () => (value ? value.size : 0) + lines.length * lineHeight;\n\n while (lines.length > 0 && heightOf() > maxHeight) {\n lines.pop();\n }\n\n const height = heightOf();\n const top = needle ? pinRadius + (compact ? 3 : 8) : semicircle ? -height - (compact ? 1 : 4) : -height / 2;\n const width = Math.max(\n value ? measureLabel(value.text, { ...font, family: value.family, size: value.size }) : 0,\n ...lines.map(measure),\n 0,\n );\n\n return {\n center: { height, lineHeight, lines, top, value, width },\n innerRadius,\n pinRadius,\n thickness,\n };\n}\n\nfunction outsidePlacement(label: OutsideLabel, radius: number, font: LabelFont) {\n const [x, y] = pointAt(label.angle, radius + OUTSIDE_LABEL_GAP);\n const sin = Math.sin(label.angle);\n const anchor: TextAnchor = sin > 0.3 ? 'start' : sin < -0.3 ? 'end' : 'middle';\n const width = measureLabel(label.text, font);\n\n return { anchor, label, width, x, y: y - Math.cos(label.angle) * 8 };\n}\n\nfunction minMaxPlacement(label: AngledLabel, radius: number, thickness: number) {\n const [x, y] = pointAt(label.angle, radius - thickness / 2);\n\n return { anchor: 'middle' as const, label, x, y: y + thickness / 2 + 14 };\n}\n\nfunction extentsAt(radius: number, input: GaugeLayoutInput, tickLabelWidth: number) {\n const metrics = layoutCenter(radius, input, tickLabelWidth);\n const outer = radius + input.outerBand;\n const box: Box = { x0: Infinity, x1: -Infinity, y0: Infinity, y1: -Infinity };\n const add = (x0: number, x1: number, y0: number, y1: number) => {\n box.x0 = Math.min(box.x0, x0);\n box.x1 = Math.max(box.x1, x1);\n box.y0 = Math.min(box.y0, y0);\n box.y1 = Math.max(box.y1, y1);\n };\n const addPoint = ([x, y]: [number, number]) => add(x, x, y, y);\n const cardinal = [-Math.PI, -Math.PI / 2, 0, Math.PI / 2, Math.PI].filter(\n (angle) => angle > input.startAngle && angle < input.endAngle,\n );\n\n [input.startAngle, input.endAngle, ...cardinal].forEach((angle) => addPoint(pointAt(angle, outer)));\n [input.startAngle, input.endAngle].forEach((angle) => addPoint(pointAt(angle, metrics.innerRadius)));\n\n input.outsideLabels.forEach((label) => {\n const { anchor, width, x, y } = outsidePlacement(label, outer, input.font);\n const x0 = anchorX(anchor, x, width);\n add(x0, x0 + width, y - 8, y + 8);\n });\n\n if (input.scaleLabels === 'minMax') {\n input.minMaxLabels.forEach((label) => {\n const { x, y } = minMaxPlacement(label, radius, metrics.thickness);\n const width = measureLabel(label.text, input.font);\n add(x - width / 2, x + width / 2, y - 10, y + 4);\n });\n }\n\n const { center } = metrics;\n\n if (center.height > 0) {\n add(-center.width / 2, center.width / 2, center.top, center.top + center.height + 2);\n }\n\n if (input.needle) {\n add(-metrics.pinRadius, metrics.pinRadius, -metrics.pinRadius, metrics.pinRadius);\n }\n\n return { box, metrics };\n}\n\n/** Maior raio em que arco, rótulos e centro cabem na área, e a posição de cada rótulo nele. */\nexport function layoutGauge(input: GaugeLayoutInput): GaugeLayout {\n const { font, height, width } = input;\n const tickLabelWidth =\n input.scaleLabels === 'ticks' ? Math.max(0, ...input.tickLabels.map((label) => measureLabel(label.text, font))) : 0;\n const fits = (radius: number) => {\n const { box } = extentsAt(radius, input, tickLabelWidth);\n return box.x1 - box.x0 <= width - 2 && box.y1 - box.y0 <= height - 2;\n };\n\n let low = 4;\n let high = Math.max(width, height);\n\n for (let step = 0; step < SEARCH_STEPS; step += 1) {\n const middle = (low + high) / 2;\n if (fits(middle)) low = middle;\n else high = middle;\n }\n\n const radius = low;\n const { box, metrics } = extentsAt(radius, input, tickLabelWidth);\n const { center, innerRadius, thickness } = metrics;\n\n const outsidePlaced: Box[] = [];\n const outsideLabels = [...input.outsideLabels]\n .sort((a, b) => Number(b.kind === 'target') - Number(a.kind === 'target'))\n .map((label) => outsidePlacement(label, radius + input.outerBand, font))\n .filter(({ anchor, width: labelWidth, x, y }) => {\n const x0 = anchorX(anchor, x, labelWidth);\n return place(outsidePlaced, { x0: x0 - 3, x1: x0 + labelWidth + 3, y0: y - 7, y1: y + 7 });\n })\n .map(({ anchor, label, x, y }) => ({ anchor, label, x, y }));\n\n return {\n center,\n cx: -box.x0 + (width - (box.x1 - box.x0)) / 2,\n cy: -box.y0 + (height - (box.y1 - box.y0)) / 2,\n innerRadius,\n outsideLabels,\n pinRadius: metrics.pinRadius,\n radius,\n scaleLabels: placeScaleLabels(input, innerRadius, radius, thickness, center),\n thickness,\n };\n}\n\nfunction placeScaleLabels(\n input: GaugeLayoutInput,\n innerRadius: number,\n radius: number,\n thickness: number,\n center: GaugeCenterLayout,\n): PlacedLabel[] {\n if (input.scaleLabels === 'minMax') {\n return input.minMaxLabels.map((label) => minMaxPlacement(label, radius, thickness));\n }\n\n if (input.scaleLabels === 'hidden') {\n return [];\n }\n\n const labelRadius = innerRadius - (input.ticks !== 'hidden' ? 14 : 6);\n const placed: Box[] = [\n { x0: -center.width / 2 - 3, x1: center.width / 2 + 3, y0: center.top - 2, y1: center.top + center.height + 2 },\n ];\n\n return input.tickLabels.flatMap((label) => {\n const [x, baseY] = pointAt(label.angle, labelRadius);\n const sin = Math.sin(label.angle);\n const y = baseY + Math.cos(label.angle) * 6;\n const anchor: TextAnchor = sin > 0.3 ? 'end' : sin < -0.3 ? 'start' : 'middle';\n const labelWidth = measureLabel(label.text, input.font);\n const x0 = anchorX(anchor, x, labelWidth);\n\n return place(placed, { x0: x0 - 2, x1: x0 + labelWidth + 2, y0: y - 7, y1: y + 7 }) ? [{ anchor, label, x, y }] : [];\n });\n}\n"],"names":["SEMICIRCLE_LIMIT","SEARCH_STEPS","OUTSIDE_LABEL_GAP","pointAt","angle","radius","lineText","line","anchorX","anchor","x","width","place","placed","box","other","layoutCenter","input","tickLabelWidth","center","compact","font","needle","scaleLabels","ticks","thickness","innerRadius","semicircle","belowPin","pinRadius","lineHeight","inset","room","maxWidth","maxHeight","measure","measureLabel","shortened","fitted","cap","steps","step","candidates","linesHeight","roomFor","size","chordY","value","fontOf","display","option","stepFont","truncateToWidth","lines","heightOf","height","top","outsidePlacement","label","y","sin","minMaxPlacement","extentsAt","metrics","outer","add","x0","x1","y0","y1","addPoint","cardinal","layoutGauge","fits","low","high","middle","outsidePlaced","outsideLabels","b","labelWidth","placeScaleLabels","labelRadius","baseY"],"mappings":"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"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { measureLabel as b, truncateToWidth as D } from "../core/measureText.js";
|
|
2
|
+
const U = 95 * Math.PI / 180, X = 24, j = 5;
|
|
3
|
+
function P(t, e) {
|
|
4
|
+
return [e * Math.sin(t), -e * Math.cos(t)];
|
|
5
|
+
}
|
|
6
|
+
function J(t) {
|
|
7
|
+
return t.kind === "text" ? t.text : t.kind === "delta" && t.label ? `${t.glyph} ${t.text} ${t.label}` : `${t.glyph} ${t.text}`;
|
|
8
|
+
}
|
|
9
|
+
function S(t, e, o) {
|
|
10
|
+
return t === "start" ? e : t === "end" ? e - o : e - o / 2;
|
|
11
|
+
}
|
|
12
|
+
function B(t, e) {
|
|
13
|
+
return t.some((o) => e.x0 < o.x1 && e.x1 > o.x0 && e.y0 < o.y1 && e.y1 > o.y0) ? !1 : (t.push(e), !0);
|
|
14
|
+
}
|
|
15
|
+
function K(t, e, o) {
|
|
16
|
+
const { center: c, compact: r, font: n, needle: h, scaleLabels: f, ticks: g } = e, x = Math.min(e.thickness, t * 0.42), s = t - x, i = Math.max(Math.abs(e.startAngle), Math.abs(e.endAngle)) <= U, m = h && i, y = r ? 4 : 7, u = n.lineHeight, I = (g !== "hidden" ? 10 : 3) + (f === "ticks" ? 14 + 0.35 * o : 0), a = Math.max(s - I, 6), d = m ? 1 / 0 : (!h && (i || f !== "ticks") ? 1.8 : 1.6) * a, w = m ? 1 / 0 : i ? a * 0.92 : h ? a * 0.8 - y : a * 1.45, M = (l) => b(J(l), n), z = (l) => M(l) <= d ? l : l.kind === "delta" ? { ...l, label: void 0 } : l.kind === "warn" ? { ...l, text: l.short } : l, v = c.lines.map(z).filter((l) => M(l) <= d), W = t * (r ? 0.36 : 0.3), H = n.centerSteps.filter((l) => l.size <= W), E = H.length > 0 ? H : n.centerSteps.slice(-1), G = v.length * u + 4, T = (l) => {
|
|
17
|
+
const k = G + l * 0.8;
|
|
18
|
+
return m ? 1.6 * a : i && !h ? 1.84 * Math.sqrt(Math.max(a * a - k * k, a * a * 0.2)) : 0.95 * d;
|
|
19
|
+
};
|
|
20
|
+
let L;
|
|
21
|
+
if (c.value !== void 0) {
|
|
22
|
+
const l = (R, q) => ({ ...n, family: q ? n.headingFamily : n.family, size: R }), k = E.find((R) => b(c.value, l(R.size, R.display)) <= T(R.size)) ?? E[E.length - 1], C = l(k.size, k.display);
|
|
23
|
+
L = { family: C.family, size: k.size, text: D(c.value, C, T(k.size)) };
|
|
24
|
+
}
|
|
25
|
+
const A = [...v], $ = () => (L ? L.size : 0) + A.length * u;
|
|
26
|
+
for (; A.length > 0 && $() > w; )
|
|
27
|
+
A.pop();
|
|
28
|
+
const p = $(), N = h ? y + (r ? 3 : 8) : i ? -p - (r ? 1 : 4) : -p / 2, Y = Math.max(
|
|
29
|
+
L ? b(L.text, { ...n, family: L.family, size: L.size }) : 0,
|
|
30
|
+
...A.map(M),
|
|
31
|
+
0
|
|
32
|
+
);
|
|
33
|
+
return {
|
|
34
|
+
center: { height: p, lineHeight: u, lines: A, top: N, value: L, width: Y },
|
|
35
|
+
innerRadius: s,
|
|
36
|
+
pinRadius: y,
|
|
37
|
+
thickness: x
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function F(t, e, o) {
|
|
41
|
+
const [c, r] = P(t.angle, e + j), n = Math.sin(t.angle), h = n > 0.3 ? "start" : n < -0.3 ? "end" : "middle", f = b(t.text, o);
|
|
42
|
+
return { anchor: h, label: t, width: f, x: c, y: r - Math.cos(t.angle) * 8 };
|
|
43
|
+
}
|
|
44
|
+
function O(t, e, o) {
|
|
45
|
+
const [c, r] = P(t.angle, e - o / 2);
|
|
46
|
+
return { anchor: "middle", label: t, x: c, y: r + o / 2 + 14 };
|
|
47
|
+
}
|
|
48
|
+
function _(t, e, o) {
|
|
49
|
+
const c = K(t, e, o), r = t + e.outerBand, n = { x0: 1 / 0, x1: -1 / 0, y0: 1 / 0, y1: -1 / 0 }, h = (s, i, m, y) => {
|
|
50
|
+
n.x0 = Math.min(n.x0, s), n.x1 = Math.max(n.x1, i), n.y0 = Math.min(n.y0, m), n.y1 = Math.max(n.y1, y);
|
|
51
|
+
}, f = ([s, i]) => h(s, s, i, i), g = [-Math.PI, -Math.PI / 2, 0, Math.PI / 2, Math.PI].filter(
|
|
52
|
+
(s) => s > e.startAngle && s < e.endAngle
|
|
53
|
+
);
|
|
54
|
+
[e.startAngle, e.endAngle, ...g].forEach((s) => f(P(s, r))), [e.startAngle, e.endAngle].forEach((s) => f(P(s, c.innerRadius))), e.outsideLabels.forEach((s) => {
|
|
55
|
+
const { anchor: i, width: m, x: y, y: u } = F(s, r, e.font), I = S(i, y, m);
|
|
56
|
+
h(I, I + m, u - 8, u + 8);
|
|
57
|
+
}), e.scaleLabels === "minMax" && e.minMaxLabels.forEach((s) => {
|
|
58
|
+
const { x: i, y: m } = O(s, t, c.thickness), y = b(s.text, e.font);
|
|
59
|
+
h(i - y / 2, i + y / 2, m - 10, m + 4);
|
|
60
|
+
});
|
|
61
|
+
const { center: x } = c;
|
|
62
|
+
return x.height > 0 && h(-x.width / 2, x.width / 2, x.top, x.top + x.height + 2), e.needle && h(-c.pinRadius, c.pinRadius, -c.pinRadius, c.pinRadius), { box: n, metrics: c };
|
|
63
|
+
}
|
|
64
|
+
function Z(t) {
|
|
65
|
+
const { font: e, height: o, width: c } = t, r = t.scaleLabels === "ticks" ? Math.max(0, ...t.tickLabels.map((a) => b(a.text, e))) : 0, n = (a) => {
|
|
66
|
+
const { box: d } = _(a, t, r);
|
|
67
|
+
return d.x1 - d.x0 <= c - 2 && d.y1 - d.y0 <= o - 2;
|
|
68
|
+
};
|
|
69
|
+
let h = 4, f = Math.max(c, o);
|
|
70
|
+
for (let a = 0; a < X; a += 1) {
|
|
71
|
+
const d = (h + f) / 2;
|
|
72
|
+
n(d) ? h = d : f = d;
|
|
73
|
+
}
|
|
74
|
+
const g = h, { box: x, metrics: s } = _(g, t, r), { center: i, innerRadius: m, thickness: y } = s, u = [], I = [...t.outsideLabels].sort((a, d) => +(d.kind === "target") - +(a.kind === "target")).map((a) => F(a, g + t.outerBand, e)).filter(({ anchor: a, width: d, x: w, y: M }) => {
|
|
75
|
+
const z = S(a, w, d);
|
|
76
|
+
return B(u, { x0: z - 3, x1: z + d + 3, y0: M - 7, y1: M + 7 });
|
|
77
|
+
}).map(({ anchor: a, label: d, x: w, y: M }) => ({ anchor: a, label: d, x: w, y: M }));
|
|
78
|
+
return {
|
|
79
|
+
center: i,
|
|
80
|
+
cx: -x.x0 + (c - (x.x1 - x.x0)) / 2,
|
|
81
|
+
cy: -x.y0 + (o - (x.y1 - x.y0)) / 2,
|
|
82
|
+
innerRadius: m,
|
|
83
|
+
outsideLabels: I,
|
|
84
|
+
pinRadius: s.pinRadius,
|
|
85
|
+
radius: g,
|
|
86
|
+
scaleLabels: Q(t, m, g, y, i),
|
|
87
|
+
thickness: y
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function Q(t, e, o, c, r) {
|
|
91
|
+
if (t.scaleLabels === "minMax")
|
|
92
|
+
return t.minMaxLabels.map((f) => O(f, o, c));
|
|
93
|
+
if (t.scaleLabels === "hidden")
|
|
94
|
+
return [];
|
|
95
|
+
const n = e - (t.ticks !== "hidden" ? 14 : 6), h = [
|
|
96
|
+
{ x0: -r.width / 2 - 3, x1: r.width / 2 + 3, y0: r.top - 2, y1: r.top + r.height + 2 }
|
|
97
|
+
];
|
|
98
|
+
return t.tickLabels.flatMap((f) => {
|
|
99
|
+
const [g, x] = P(f.angle, n), s = Math.sin(f.angle), i = x + Math.cos(f.angle) * 6, m = s > 0.3 ? "end" : s < -0.3 ? "start" : "middle", y = b(f.text, t.font), u = S(m, g, y);
|
|
100
|
+
return B(h, { x0: u - 2, x1: u + y + 2, y0: i - 7, y1: i + 7 }) ? [{ anchor: m, label: f, x: g, y: i }] : [];
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
export {
|
|
104
|
+
Z as layoutGauge,
|
|
105
|
+
P as pointAt
|
|
106
|
+
};
|
|
107
|
+
//# sourceMappingURL=gaugeLayout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gaugeLayout.js","sources":["../../../../src/components/charts/ChartGauge/gaugeLayout.ts"],"sourcesContent":["import { measureLabel, truncateToWidth, type LabelFont } from '../core';\nimport type { ChartGaugeScaleLabels, ChartGaugeTicks } from './ChartGauge';\nimport type { CenterLine, GaugeCenter } from './gaugeReading';\n\n/** Até essa meia-abertura o arco é uma meia-lua, e o centro se apoia na linha de base. */\nconst SEMICIRCLE_LIMIT = (95 * Math.PI) / 180;\nconst SEARCH_STEPS = 24;\nconst OUTSIDE_LABEL_GAP = 5;\n\nexport type TextAnchor = 'start' | 'middle' | 'end';\n\nexport interface AngledLabel {\n angle: number;\n text: string;\n}\n\nexport interface OutsideLabel extends AngledLabel {\n kind: 'segment' | 'target';\n}\n\nexport interface PlacedLabel<T extends AngledLabel = AngledLabel> {\n anchor: TextAnchor;\n label: T;\n x: number;\n y: number;\n}\n\nexport interface GaugeLayoutInput {\n center: GaugeCenter;\n compact: boolean;\n /** Radianos a partir do topo, no sentido horário. */\n endAngle: number;\n font: LabelFont;\n height: number;\n /** Rótulos de ponta, mínimo e máximo, quando `scaleLabels` é `minMax`. */\n minMaxLabels: readonly [AngledLabel, AngledLabel];\n needle: boolean;\n /** Régua e marca da meta, além do raio externo do arco. */\n outerBand: number;\n outsideLabels: readonly OutsideLabel[];\n scaleLabels: ChartGaugeScaleLabels;\n startAngle: number;\n thickness: number;\n /** Rótulos das marcas principais, na ordem em que disputam espaço. */\n tickLabels: readonly AngledLabel[];\n ticks: ChartGaugeTicks;\n width: number;\n}\n\nexport interface GaugeCenterLayout {\n height: number;\n lineHeight: number;\n lines: readonly CenterLine[];\n top: number;\n value?: { family: string; size: number; text: string };\n width: number;\n}\n\nexport interface GaugeLayout {\n center: GaugeCenterLayout;\n cx: number;\n cy: number;\n innerRadius: number;\n outsideLabels: readonly PlacedLabel<OutsideLabel>[];\n pinRadius: number;\n radius: number;\n scaleLabels: readonly PlacedLabel[];\n thickness: number;\n}\n\ninterface Box {\n x0: number;\n x1: number;\n y0: number;\n y1: number;\n}\n\nexport function pointAt(angle: number, radius: number): [number, number] {\n return [radius * Math.sin(angle), -radius * Math.cos(angle)];\n}\n\nfunction lineText(line: CenterLine) {\n if (line.kind === 'text') {\n return line.text;\n }\n\n return line.kind === 'delta' && line.label ? `${line.glyph} ${line.text} ${line.label}` : `${line.glyph} ${line.text}`;\n}\n\nfunction anchorX(anchor: TextAnchor, x: number, width: number) {\n return anchor === 'start' ? x : anchor === 'end' ? x - width : x - width / 2;\n}\n\n/** Rótulo que colide com um já posto não entra. */\nfunction place(placed: Box[], box: Box) {\n if (placed.some((other) => box.x0 < other.x1 && box.x1 > other.x0 && box.y0 < other.y1 && box.y1 > other.y0)) {\n return false;\n }\n\n placed.push(box);\n return true;\n}\n\n/**\n * O centro cabe no vazio do arco: o valor desce na escala tipográfica até caber, e as linhas que não cabem saem, de\n * baixo para cima. Na meia-lua com ponteiro, o bloco vai para baixo do pino, fora do arco.\n */\nfunction layoutCenter(radius: number, input: GaugeLayoutInput, tickLabelWidth: number) {\n const { center, compact, font, needle, scaleLabels, ticks } = input;\n const thickness = Math.min(input.thickness, radius * 0.42);\n const innerRadius = radius - thickness;\n const semicircle = Math.max(Math.abs(input.startAngle), Math.abs(input.endAngle)) <= SEMICIRCLE_LIMIT;\n const belowPin = needle && semicircle;\n const pinRadius = compact ? 4 : 7;\n const lineHeight = font.lineHeight;\n const inset = (ticks !== 'hidden' ? 10 : 3) + (scaleLabels === 'ticks' ? 14 + 0.35 * tickLabelWidth : 0);\n const room = Math.max(innerRadius - inset, 6);\n const maxWidth = belowPin\n ? Infinity\n : (!needle && (semicircle || scaleLabels !== 'ticks') ? 1.8 : 1.6) * room;\n const maxHeight = belowPin ? Infinity : semicircle ? room * 0.92 : needle ? room * 0.8 - pinRadius : room * 1.45;\n\n const measure = (line: CenterLine) => measureLabel(lineText(line), font);\n // A linha larga demais tenta a forma curta antes de sair.\n const shortened = (line: CenterLine): CenterLine => {\n if (measure(line) <= maxWidth) return line;\n if (line.kind === 'delta') return { ...line, label: undefined };\n return line.kind === 'warn' ? { ...line, text: line.short } : line;\n };\n const fitted = center.lines.map(shortened).filter((line) => measure(line) <= maxWidth);\n\n const cap = radius * (compact ? 0.36 : 0.3);\n const steps = font.centerSteps.filter((step) => step.size <= cap);\n const candidates = steps.length > 0 ? steps : font.centerSteps.slice(-1);\n const linesHeight = fitted.length * lineHeight + 4;\n\n // Na meia-lua sem ponteiro, o valor fica no alto do bloco, onde a corda do arco é mais curta.\n const roomFor = (size: number) => {\n const chordY = linesHeight + size * 0.8;\n if (belowPin) return 1.6 * room;\n if (semicircle && !needle) return 1.84 * Math.sqrt(Math.max(room * room - chordY * chordY, room * room * 0.2));\n return 0.95 * maxWidth;\n };\n\n let value: GaugeCenterLayout['value'];\n\n if (center.value !== undefined) {\n const fontOf = (size: number, display: boolean) => ({ ...font, family: display ? font.headingFamily : font.family, size });\n const step =\n candidates.find((option) => measureLabel(center.value!, fontOf(option.size, option.display)) <= roomFor(option.size)) ??\n candidates[candidates.length - 1];\n const stepFont = fontOf(step.size, step.display);\n value = { family: stepFont.family, size: step.size, text: truncateToWidth(center.value, stepFont, roomFor(step.size)) };\n }\n\n const lines = [...fitted];\n const heightOf = () => (value ? value.size : 0) + lines.length * lineHeight;\n\n while (lines.length > 0 && heightOf() > maxHeight) {\n lines.pop();\n }\n\n const height = heightOf();\n const top = needle ? pinRadius + (compact ? 3 : 8) : semicircle ? -height - (compact ? 1 : 4) : -height / 2;\n const width = Math.max(\n value ? measureLabel(value.text, { ...font, family: value.family, size: value.size }) : 0,\n ...lines.map(measure),\n 0,\n );\n\n return {\n center: { height, lineHeight, lines, top, value, width },\n innerRadius,\n pinRadius,\n thickness,\n };\n}\n\nfunction outsidePlacement(label: OutsideLabel, radius: number, font: LabelFont) {\n const [x, y] = pointAt(label.angle, radius + OUTSIDE_LABEL_GAP);\n const sin = Math.sin(label.angle);\n const anchor: TextAnchor = sin > 0.3 ? 'start' : sin < -0.3 ? 'end' : 'middle';\n const width = measureLabel(label.text, font);\n\n return { anchor, label, width, x, y: y - Math.cos(label.angle) * 8 };\n}\n\nfunction minMaxPlacement(label: AngledLabel, radius: number, thickness: number) {\n const [x, y] = pointAt(label.angle, radius - thickness / 2);\n\n return { anchor: 'middle' as const, label, x, y: y + thickness / 2 + 14 };\n}\n\nfunction extentsAt(radius: number, input: GaugeLayoutInput, tickLabelWidth: number) {\n const metrics = layoutCenter(radius, input, tickLabelWidth);\n const outer = radius + input.outerBand;\n const box: Box = { x0: Infinity, x1: -Infinity, y0: Infinity, y1: -Infinity };\n const add = (x0: number, x1: number, y0: number, y1: number) => {\n box.x0 = Math.min(box.x0, x0);\n box.x1 = Math.max(box.x1, x1);\n box.y0 = Math.min(box.y0, y0);\n box.y1 = Math.max(box.y1, y1);\n };\n const addPoint = ([x, y]: [number, number]) => add(x, x, y, y);\n const cardinal = [-Math.PI, -Math.PI / 2, 0, Math.PI / 2, Math.PI].filter(\n (angle) => angle > input.startAngle && angle < input.endAngle,\n );\n\n [input.startAngle, input.endAngle, ...cardinal].forEach((angle) => addPoint(pointAt(angle, outer)));\n [input.startAngle, input.endAngle].forEach((angle) => addPoint(pointAt(angle, metrics.innerRadius)));\n\n input.outsideLabels.forEach((label) => {\n const { anchor, width, x, y } = outsidePlacement(label, outer, input.font);\n const x0 = anchorX(anchor, x, width);\n add(x0, x0 + width, y - 8, y + 8);\n });\n\n if (input.scaleLabels === 'minMax') {\n input.minMaxLabels.forEach((label) => {\n const { x, y } = minMaxPlacement(label, radius, metrics.thickness);\n const width = measureLabel(label.text, input.font);\n add(x - width / 2, x + width / 2, y - 10, y + 4);\n });\n }\n\n const { center } = metrics;\n\n if (center.height > 0) {\n add(-center.width / 2, center.width / 2, center.top, center.top + center.height + 2);\n }\n\n if (input.needle) {\n add(-metrics.pinRadius, metrics.pinRadius, -metrics.pinRadius, metrics.pinRadius);\n }\n\n return { box, metrics };\n}\n\n/** Maior raio em que arco, rótulos e centro cabem na área, e a posição de cada rótulo nele. */\nexport function layoutGauge(input: GaugeLayoutInput): GaugeLayout {\n const { font, height, width } = input;\n const tickLabelWidth =\n input.scaleLabels === 'ticks' ? Math.max(0, ...input.tickLabels.map((label) => measureLabel(label.text, font))) : 0;\n const fits = (radius: number) => {\n const { box } = extentsAt(radius, input, tickLabelWidth);\n return box.x1 - box.x0 <= width - 2 && box.y1 - box.y0 <= height - 2;\n };\n\n let low = 4;\n let high = Math.max(width, height);\n\n for (let step = 0; step < SEARCH_STEPS; step += 1) {\n const middle = (low + high) / 2;\n if (fits(middle)) low = middle;\n else high = middle;\n }\n\n const radius = low;\n const { box, metrics } = extentsAt(radius, input, tickLabelWidth);\n const { center, innerRadius, thickness } = metrics;\n\n const outsidePlaced: Box[] = [];\n const outsideLabels = [...input.outsideLabels]\n .sort((a, b) => Number(b.kind === 'target') - Number(a.kind === 'target'))\n .map((label) => outsidePlacement(label, radius + input.outerBand, font))\n .filter(({ anchor, width: labelWidth, x, y }) => {\n const x0 = anchorX(anchor, x, labelWidth);\n return place(outsidePlaced, { x0: x0 - 3, x1: x0 + labelWidth + 3, y0: y - 7, y1: y + 7 });\n })\n .map(({ anchor, label, x, y }) => ({ anchor, label, x, y }));\n\n return {\n center,\n cx: -box.x0 + (width - (box.x1 - box.x0)) / 2,\n cy: -box.y0 + (height - (box.y1 - box.y0)) / 2,\n innerRadius,\n outsideLabels,\n pinRadius: metrics.pinRadius,\n radius,\n scaleLabels: placeScaleLabels(input, innerRadius, radius, thickness, center),\n thickness,\n };\n}\n\nfunction placeScaleLabels(\n input: GaugeLayoutInput,\n innerRadius: number,\n radius: number,\n thickness: number,\n center: GaugeCenterLayout,\n): PlacedLabel[] {\n if (input.scaleLabels === 'minMax') {\n return input.minMaxLabels.map((label) => minMaxPlacement(label, radius, thickness));\n }\n\n if (input.scaleLabels === 'hidden') {\n return [];\n }\n\n const labelRadius = innerRadius - (input.ticks !== 'hidden' ? 14 : 6);\n const placed: Box[] = [\n { x0: -center.width / 2 - 3, x1: center.width / 2 + 3, y0: center.top - 2, y1: center.top + center.height + 2 },\n ];\n\n return input.tickLabels.flatMap((label) => {\n const [x, baseY] = pointAt(label.angle, labelRadius);\n const sin = Math.sin(label.angle);\n const y = baseY + Math.cos(label.angle) * 6;\n const anchor: TextAnchor = sin > 0.3 ? 'end' : sin < -0.3 ? 'start' : 'middle';\n const labelWidth = measureLabel(label.text, input.font);\n const x0 = anchorX(anchor, x, labelWidth);\n\n return place(placed, { x0: x0 - 2, x1: x0 + labelWidth + 2, y0: y - 7, y1: y + 7 }) ? [{ anchor, label, x, y }] : [];\n });\n}\n"],"names":["SEMICIRCLE_LIMIT","SEARCH_STEPS","OUTSIDE_LABEL_GAP","pointAt","angle","radius","lineText","line","anchorX","anchor","x","width","place","placed","box","other","layoutCenter","input","tickLabelWidth","center","compact","font","needle","scaleLabels","ticks","thickness","innerRadius","semicircle","belowPin","pinRadius","lineHeight","inset","room","maxWidth","maxHeight","measure","measureLabel","shortened","fitted","cap","steps","step","candidates","linesHeight","roomFor","size","chordY","value","fontOf","display","option","stepFont","truncateToWidth","lines","heightOf","height","top","outsidePlacement","label","y","sin","minMaxPlacement","extentsAt","metrics","outer","add","x0","x1","y0","y1","addPoint","cardinal","layoutGauge","fits","low","high","middle","outsidePlaced","outsideLabels","b","labelWidth","placeScaleLabels","labelRadius","baseY"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("./gaugeScale.cjs"),d=require("../../../utils/formatters/formatarNumero.cjs");function P(e){const{base:a,formatTooltipValue:n,formatValue:t,segmentUnit:o,valueDisplay:i}=e;return{againstTarget:a!==null&&(i==="percentOfTarget"||o==="percentOfTarget"),base:a,formatExact:n??t,formatValue:t,showsPercent:a!==null&&i==="percentOfTarget"}}function v(e,a){return d.formatarPercentual(a/(e.base??1))}function f(e,a){return e.showsPercent?v(e,a):e.formatValue(a)}function $(e,a,n){const t=e.base??0;return e.showsPercent?`${n(a)} de ${n(t)}`:`${v(e,a)} de ${n(t)}`}function T(e,a){return`${f(e,a.from)} a ${f(e,a.to)}`}function w(e){return e.label||"Faixa"}function x(e){return(e.value>0?"+":e.value<0?"−":"±")+(e.format??d.formatarNumero)(Math.abs(e.value))}function p(e){return e!==void 0&&h.isNumber(e.value)}function y(e){const a=e.value>0?"positive":e.value<0?"negative":"neutral";return{glyph:e.value>0?"▲":e.value<0?"▼":"●",intent:e.intent??a,kind:"delta",label:e.label,text:x(e)}}function N(e){const{centerLabel:a,compact:n,delta:t,domain:o,emptyMessage:i,reading:r,showCenter:g,status:u,value:s}=e;if(u==="loading")return{lines:[{kind:"text",text:"Carregando…"}]};if(u==="empty")return{lines:[{kind:"text",text:i}],value:"—"};if(!g)return{lines:[]};const m=[],l=s>o.max;if(l||s<o.min){const c=l?"acima":"abaixo";m.push({glyph:l?"▲":"▼",kind:"warn",short:c,text:n?c:`${c} do ${l?"máximo":"mínimo"}`})}const b=a||(r.againstTarget?$(r,s,r.formatValue):"");return b&&!(n&&m.length>0)&&m.push({kind:"text",text:b}),!n&&p(t)&&m.push(y(t)),{lines:m,value:f(r,s)}}function k(e){const{delta:a,domain:n,reading:t,segment:o,target:i,value:r}=e,{againstTarget:g,formatExact:u,formatValue:s,showsPercent:m}=t,l=g?m?[`${v(t,r)} da meta`,$(t,r,u)]:[u(r),`${v(t,r)} da meta de ${u(t.base??0)}`]:[s(r)],b=c=>m?f(t,c):g?u(c):s(c);if(r>n.max&&l.push(`acima do máximo de ${b(n.max)}`),r<n.min&&l.push(`abaixo do mínimo de ${b(n.min)}`),o!=null&&o.label&&l.push(`faixa ${o.label}`),i&&h.isNumber(i.value)&&!g){const c=i.label&&i.label!=="Meta"?i.label:"meta";l.push(`${c} ${s(i.value)}`)}return p(a)&&l.push(`variação ${x(a)}${a.label?` ${a.label}`:""}`),l.join(", ")}function V(e){return e&&h.isNumber(e.value)?[{label:e.label||"Meta",values:[e.value]}]:[]}function A(e){const{color:a,delta:n,domain:t,reading:o,segment:i,target:r,title:g,value:u}=e,s=o.showsPercent,m=[{color:a,emphasis:!s,label:"Valor",values:[u]},...V(r)];o.againstTarget&&m.push({color:s?a:void 0,emphasis:s,format:d.formatarPercentual,label:"Atingido",values:[u/(o.base??1)]}),p(n)&&m.push({format:()=>x(n),label:"Variação",values:[n.value]});const l=u>t.max?`Acima do máximo de ${f(o,t.max)}`:u<t.min?`Abaixo do mínimo de ${f(o,t.min)}`:i?`${i.label?`Faixa ${i.label} · `:"Faixa "}${T(o,i)}`:`Escala ${f(o,t.min)} a ${f(o,t.max)}`;return{rows:m,subtitle:l,title:g}}function M(e){const{current:a,reading:n,segment:t,target:o,value:i}=e,r=a===t;return{rows:[{color:r?t.color:void 0,emphasis:r,label:"Valor atual",values:[i]},...V(o)],subtitle:`${T(n,t)}${r?" · o valor está aqui":""}`,title:w(t)}}exports.deltaText=x;exports.formatAttainment=v;exports.formatShown=f;exports.gaugeCenter=N;exports.gaugeReading=P;exports.gaugeValueText=k;exports.hasDelta=p;exports.otherReading=$;exports.rangeText=T;exports.segmentName=w;exports.segmentTooltip=M;exports.valueTooltip=A;
|
|
2
|
+
//# sourceMappingURL=gaugeReading.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gaugeReading.cjs","sources":["../../../../src/components/charts/ChartGauge/gaugeReading.ts"],"sourcesContent":["import { formatarNumero, formatarPercentual } from '../../../utils/formatters';\nimport type { ChartTooltipRow } from '../ChartTooltip';\nimport type { SeriesIntent } from '../palette';\nimport type { ChartGaugeDelta, ChartGaugeTarget } from './ChartGauge';\nimport { isNumber, type GaugeDomain, type GaugeSegment } from './gaugeScale';\n\n/** Como o medidor lê o valor: no formato do consumidor ou contra a meta. */\nexport interface GaugeReading {\n /** Leitura contra a meta: a outra leitura no centro, a linha Atingido no balão e as duas no `aria-valuetext`. */\n againstTarget: boolean;\n /** Meta positiva, base do atingimento. */\n base: number | null;\n formatExact: (value: number) => string;\n formatValue: (value: number) => string;\n /** Centro, escala e intervalos em percentual da meta. */\n showsPercent: boolean;\n}\n\nexport type CenterLine =\n | { kind: 'text'; text: string }\n | { glyph: string; kind: 'warn'; short: string; text: string }\n | { glyph: string; intent: SeriesIntent; kind: 'delta'; label?: string; text: string };\n\nexport interface GaugeCenter {\n lines: readonly CenterLine[];\n value?: string;\n}\n\nexport type GaugeStatus = 'loading' | 'empty' | 'value';\n\nexport interface GaugeTooltip {\n rows: ChartTooltipRow[];\n subtitle?: string;\n title?: string;\n}\n\n/** Quem pede `percentOfTarget`, na exibição ou nas faixas, liga a leitura contra a meta; sem meta, vale o valor. */\nexport function gaugeReading(options: {\n base: number | null;\n formatTooltipValue?: (value: number) => string;\n formatValue: (value: number) => string;\n segmentUnit: string;\n valueDisplay: string;\n}): GaugeReading {\n const { base, formatTooltipValue, formatValue, segmentUnit, valueDisplay } = options;\n\n return {\n againstTarget: base !== null && (valueDisplay === 'percentOfTarget' || segmentUnit === 'percentOfTarget'),\n base,\n formatExact: formatTooltipValue ?? formatValue,\n formatValue,\n showsPercent: base !== null && valueDisplay === 'percentOfTarget',\n };\n}\n\nexport function formatAttainment(reading: GaugeReading, value: number) {\n return formatarPercentual(value / (reading.base ?? 1));\n}\n\n/** O número como a exibição escolhida o mostra. */\nexport function formatShown(reading: GaugeReading, value: number) {\n return reading.showsPercent ? formatAttainment(reading, value) : reading.formatValue(value);\n}\n\n/** A leitura que a exibição não escolheu, como \"92% de R$ 2 mi\" ou \"R$ 1,84 mi de R$ 2 mi\". */\nexport function otherReading(reading: GaugeReading, value: number, format: (value: number) => string) {\n const base = reading.base ?? 0;\n\n return reading.showsPercent\n ? `${format(value)} de ${format(base)}`\n : `${formatAttainment(reading, value)} de ${format(base)}`;\n}\n\nexport function rangeText(reading: GaugeReading, segment: GaugeSegment) {\n return `${formatShown(reading, segment.from)} a ${formatShown(reading, segment.to)}`;\n}\n\nexport function segmentName(segment: GaugeSegment) {\n return segment.label || 'Faixa';\n}\n\n/** O sinal é do componente; o `format` recebe o módulo da variação. */\nexport function deltaText(delta: ChartGaugeDelta) {\n const sign = delta.value > 0 ? '+' : delta.value < 0 ? '−' : '±';\n\n return sign + (delta.format ?? formatarNumero)(Math.abs(delta.value));\n}\n\nexport function hasDelta(delta: ChartGaugeDelta | undefined): delta is ChartGaugeDelta {\n return delta !== undefined && isNumber(delta.value);\n}\n\nfunction deltaLine(delta: ChartGaugeDelta): CenterLine {\n const automatic = delta.value > 0 ? 'positive' : delta.value < 0 ? 'negative' : 'neutral';\n\n return {\n glyph: delta.value > 0 ? '▲' : delta.value < 0 ? '▼' : '●',\n intent: delta.intent ?? automatic,\n kind: 'delta',\n label: delta.label,\n text: deltaText(delta),\n };\n}\n\nexport function gaugeCenter(options: {\n centerLabel?: string;\n compact: boolean;\n delta?: ChartGaugeDelta;\n domain: GaugeDomain;\n emptyMessage: string;\n reading: GaugeReading;\n showCenter: boolean;\n status: GaugeStatus;\n value: number;\n}): GaugeCenter {\n const { centerLabel, compact, delta, domain, emptyMessage, reading, showCenter, status, value } = options;\n\n if (status === 'loading') {\n return { lines: [{ kind: 'text', text: 'Carregando…' }] };\n }\n\n if (status === 'empty') {\n return { lines: [{ kind: 'text', text: emptyMessage }], value: '—' };\n }\n\n if (!showCenter) {\n return { lines: [] };\n }\n\n const lines: CenterLine[] = [];\n const over = value > domain.max;\n\n if (over || value < domain.min) {\n const short = over ? 'acima' : 'abaixo';\n lines.push({ glyph: over ? '▲' : '▼', kind: 'warn', short, text: compact ? short : `${short} do ${over ? 'máximo' : 'mínimo'}` });\n }\n\n const label = centerLabel || (reading.againstTarget ? otherReading(reading, value, reading.formatValue) : '');\n\n // No compacto, o aviso de fora da escala vence o rótulo.\n if (label && !(compact && lines.length > 0)) {\n lines.push({ kind: 'text', text: label });\n }\n\n if (!compact && hasDelta(delta)) {\n lines.push(deltaLine(delta));\n }\n\n return { lines, value: formatShown(reading, value) };\n}\n\n/** A frase do `aria-valuetext`: o valor, o que excede a escala, a faixa, a meta e a variação. */\nexport function gaugeValueText(options: {\n delta?: ChartGaugeDelta;\n domain: GaugeDomain;\n reading: GaugeReading;\n segment?: GaugeSegment;\n target?: ChartGaugeTarget;\n value: number;\n}) {\n const { delta, domain, reading, segment, target, value } = options;\n const { againstTarget, formatExact, formatValue, showsPercent } = reading;\n const parts = !againstTarget\n ? [formatValue(value)]\n : showsPercent\n ? [`${formatAttainment(reading, value)} da meta`, otherReading(reading, value, formatExact)]\n : [formatExact(value), `${formatAttainment(reading, value)} da meta de ${formatExact(reading.base ?? 0)}`];\n const limit = (bound: number) =>\n showsPercent ? formatShown(reading, bound) : againstTarget ? formatExact(bound) : formatValue(bound);\n\n if (value > domain.max) {\n parts.push(`acima do máximo de ${limit(domain.max)}`);\n }\n\n if (value < domain.min) {\n parts.push(`abaixo do mínimo de ${limit(domain.min)}`);\n }\n\n if (segment?.label) {\n parts.push(`faixa ${segment.label}`);\n }\n\n if (target && isNumber(target.value) && !againstTarget) {\n const name = target.label && target.label !== 'Meta' ? target.label : 'meta';\n parts.push(`${name} ${formatValue(target.value)}`);\n }\n\n if (hasDelta(delta)) {\n parts.push(`variação ${deltaText(delta)}${delta.label ? ` ${delta.label}` : ''}`);\n }\n\n return parts.join(', ');\n}\n\nfunction targetRow(target: ChartGaugeTarget | undefined): ChartTooltipRow[] {\n return target && isNumber(target.value) ? [{ label: target.label || 'Meta', values: [target.value] }] : [];\n}\n\n/** Balão do centro ou do arco sem faixas: a faixa do valor, o valor, a meta, o atingido e a variação. */\nexport function valueTooltip(options: {\n color: string;\n delta?: ChartGaugeDelta;\n domain: GaugeDomain;\n reading: GaugeReading;\n segment?: GaugeSegment;\n target?: ChartGaugeTarget;\n title: string;\n value: number;\n}): GaugeTooltip {\n const { color, delta, domain, reading, segment, target, title, value } = options;\n const percent = reading.showsPercent;\n const rows: ChartTooltipRow[] = [\n { color, emphasis: !percent, label: 'Valor', values: [value] },\n ...targetRow(target),\n ];\n\n if (reading.againstTarget) {\n rows.push({\n color: percent ? color : undefined,\n emphasis: percent,\n format: formatarPercentual,\n label: 'Atingido',\n values: [value / (reading.base ?? 1)],\n });\n }\n\n if (hasDelta(delta)) {\n rows.push({ format: () => deltaText(delta), label: 'Variação', values: [delta.value] });\n }\n\n const subtitle =\n value > domain.max\n ? `Acima do máximo de ${formatShown(reading, domain.max)}`\n : value < domain.min\n ? `Abaixo do mínimo de ${formatShown(reading, domain.min)}`\n : segment\n ? `${segment.label ? `Faixa ${segment.label} · ` : 'Faixa '}${rangeText(reading, segment)}`\n : `Escala ${formatShown(reading, domain.min)} a ${formatShown(reading, domain.max)}`;\n\n return { rows, subtitle, title };\n}\n\n/** Balão de uma faixa: o intervalo dela, o valor atual e se ele está ali. */\nexport function segmentTooltip(options: {\n current?: GaugeSegment;\n reading: GaugeReading;\n segment: GaugeSegment;\n target?: ChartGaugeTarget;\n value: number;\n}): GaugeTooltip {\n const { current, reading, segment, target, value } = options;\n const inside = current === segment;\n\n return {\n rows: [\n { color: inside ? segment.color : undefined, emphasis: inside, label: 'Valor atual', values: [value] },\n ...targetRow(target),\n ],\n subtitle: `${rangeText(reading, segment)}${inside ? ' · o valor está aqui' : ''}`,\n title: segmentName(segment),\n };\n}\n"],"names":["gaugeReading","options","base","formatTooltipValue","formatValue","segmentUnit","valueDisplay","formatAttainment","reading","value","formatarPercentual","formatShown","otherReading","format","rangeText","segment","segmentName","deltaText","delta","formatarNumero","hasDelta","isNumber","deltaLine","automatic","gaugeCenter","centerLabel","compact","domain","emptyMessage","showCenter","status","lines","over","short","label","gaugeValueText","target","againstTarget","formatExact","showsPercent","parts","limit","bound","name","targetRow","valueTooltip","color","title","percent","rows","subtitle","segmentTooltip","current","inside"],"mappings":"8KAqCO,SAASA,EAAaC,EAMZ,CACf,KAAM,CAAE,KAAAC,EAAM,mBAAAC,EAAoB,YAAAC,EAAa,YAAAC,EAAa,aAAAC,GAAiBL,EAE7E,MAAO,CACL,cAAeC,IAAS,OAASI,IAAiB,mBAAqBD,IAAgB,mBACvF,KAAAH,EACA,YAAaC,GAAsBC,EACnC,YAAAA,EACA,aAAcF,IAAS,MAAQI,IAAiB,iBAAA,CAEpD,CAEO,SAASC,EAAiBC,EAAuBC,EAAe,CACrE,OAAOC,EAAAA,mBAAmBD,GAASD,EAAQ,MAAQ,EAAE,CACvD,CAGO,SAASG,EAAYH,EAAuBC,EAAe,CAChE,OAAOD,EAAQ,aAAeD,EAAiBC,EAASC,CAAK,EAAID,EAAQ,YAAYC,CAAK,CAC5F,CAGO,SAASG,EAAaJ,EAAuBC,EAAeI,EAAmC,CACpG,MAAMX,EAAOM,EAAQ,MAAQ,EAE7B,OAAOA,EAAQ,aACX,GAAGK,EAAOJ,CAAK,CAAC,OAAOI,EAAOX,CAAI,CAAC,GACnC,GAAGK,EAAiBC,EAASC,CAAK,CAAC,OAAOI,EAAOX,CAAI,CAAC,EAC5D,CAEO,SAASY,EAAUN,EAAuBO,EAAuB,CACtE,MAAO,GAAGJ,EAAYH,EAASO,EAAQ,IAAI,CAAC,MAAMJ,EAAYH,EAASO,EAAQ,EAAE,CAAC,EACpF,CAEO,SAASC,EAAYD,EAAuB,CACjD,OAAOA,EAAQ,OAAS,OAC1B,CAGO,SAASE,EAAUC,EAAwB,CAGhD,OAFaA,EAAM,MAAQ,EAAI,IAAMA,EAAM,MAAQ,EAAI,IAAM,MAE9CA,EAAM,QAAUC,EAAAA,gBAAgB,KAAK,IAAID,EAAM,KAAK,CAAC,CACtE,CAEO,SAASE,EAASF,EAA8D,CACrF,OAAOA,IAAU,QAAaG,WAASH,EAAM,KAAK,CACpD,CAEA,SAASI,EAAUJ,EAAoC,CACrD,MAAMK,EAAYL,EAAM,MAAQ,EAAI,WAAaA,EAAM,MAAQ,EAAI,WAAa,UAEhF,MAAO,CACL,MAAOA,EAAM,MAAQ,EAAI,IAAMA,EAAM,MAAQ,EAAI,IAAM,IACvD,OAAQA,EAAM,QAAUK,EACxB,KAAM,QACN,MAAOL,EAAM,MACb,KAAMD,EAAUC,CAAK,CAAA,CAEzB,CAEO,SAASM,EAAYvB,EAUZ,CACd,KAAM,CAAE,YAAAwB,EAAa,QAAAC,EAAS,MAAAR,EAAO,OAAAS,EAAQ,aAAAC,EAAc,QAAApB,EAAS,WAAAqB,EAAY,OAAAC,EAAQ,MAAArB,CAAA,EAAUR,EAElG,GAAI6B,IAAW,UACb,MAAO,CAAE,MAAO,CAAC,CAAE,KAAM,OAAQ,KAAM,aAAA,CAAe,CAAA,EAGxD,GAAIA,IAAW,QACb,MAAO,CAAE,MAAO,CAAC,CAAE,KAAM,OAAQ,KAAMF,CAAA,CAAc,EAAG,MAAO,GAAA,EAGjE,GAAI,CAACC,EACH,MAAO,CAAE,MAAO,EAAC,EAGnB,MAAME,EAAsB,CAAA,EACtBC,EAAOvB,EAAQkB,EAAO,IAE5B,GAAIK,GAAQvB,EAAQkB,EAAO,IAAK,CAC9B,MAAMM,EAAQD,EAAO,QAAU,SAC/BD,EAAM,KAAK,CAAE,MAAOC,EAAO,IAAM,IAAK,KAAM,OAAQ,MAAAC,EAAO,KAAMP,EAAUO,EAAQ,GAAGA,CAAK,OAAOD,EAAO,SAAW,QAAQ,GAAI,CAClI,CAEA,MAAME,EAAQT,IAAgBjB,EAAQ,cAAgBI,EAAaJ,EAASC,EAAOD,EAAQ,WAAW,EAAI,IAG1G,OAAI0B,GAAS,EAAER,GAAWK,EAAM,OAAS,IACvCA,EAAM,KAAK,CAAE,KAAM,OAAQ,KAAMG,EAAO,EAGtC,CAACR,GAAWN,EAASF,CAAK,GAC5Ba,EAAM,KAAKT,EAAUJ,CAAK,CAAC,EAGtB,CAAE,MAAAa,EAAO,MAAOpB,EAAYH,EAASC,CAAK,CAAA,CACnD,CAGO,SAAS0B,EAAelC,EAO5B,CACD,KAAM,CAAE,MAAAiB,EAAO,OAAAS,EAAQ,QAAAnB,EAAS,QAAAO,EAAS,OAAAqB,EAAQ,MAAA3B,GAAUR,EACrD,CAAE,cAAAoC,EAAe,YAAAC,EAAa,YAAAlC,EAAa,aAAAmC,GAAiB/B,EAC5DgC,EAASH,EAEXE,EACE,CAAC,GAAGhC,EAAiBC,EAASC,CAAK,CAAC,WAAYG,EAAaJ,EAASC,EAAO6B,CAAW,CAAC,EACzF,CAACA,EAAY7B,CAAK,EAAG,GAAGF,EAAiBC,EAASC,CAAK,CAAC,eAAe6B,EAAY9B,EAAQ,MAAQ,CAAC,CAAC,EAAE,EAHzG,CAACJ,EAAYK,CAAK,CAAC,EAIjBgC,EAASC,GACbH,EAAe5B,EAAYH,EAASkC,CAAK,EAAIL,EAAgBC,EAAYI,CAAK,EAAItC,EAAYsC,CAAK,EAcrG,GAZIjC,EAAQkB,EAAO,KACjBa,EAAM,KAAK,sBAAsBC,EAAMd,EAAO,GAAG,CAAC,EAAE,EAGlDlB,EAAQkB,EAAO,KACjBa,EAAM,KAAK,uBAAuBC,EAAMd,EAAO,GAAG,CAAC,EAAE,EAGnDZ,GAAA,MAAAA,EAAS,OACXyB,EAAM,KAAK,SAASzB,EAAQ,KAAK,EAAE,EAGjCqB,GAAUf,EAAAA,SAASe,EAAO,KAAK,GAAK,CAACC,EAAe,CACtD,MAAMM,EAAOP,EAAO,OAASA,EAAO,QAAU,OAASA,EAAO,MAAQ,OACtEI,EAAM,KAAK,GAAGG,CAAI,IAAIvC,EAAYgC,EAAO,KAAK,CAAC,EAAE,CACnD,CAEA,OAAIhB,EAASF,CAAK,GAChBsB,EAAM,KAAK,YAAYvB,EAAUC,CAAK,CAAC,GAAGA,EAAM,MAAQ,IAAIA,EAAM,KAAK,GAAK,EAAE,EAAE,EAG3EsB,EAAM,KAAK,IAAI,CACxB,CAEA,SAASI,EAAUR,EAAyD,CAC1E,OAAOA,GAAUf,EAAAA,SAASe,EAAO,KAAK,EAAI,CAAC,CAAE,MAAOA,EAAO,OAAS,OAAQ,OAAQ,CAACA,EAAO,KAAK,CAAA,CAAG,EAAI,CAAA,CAC1G,CAGO,SAASS,EAAa5C,EASZ,CACf,KAAM,CAAE,MAAA6C,EAAO,MAAA5B,EAAO,OAAAS,EAAQ,QAAAnB,EAAS,QAAAO,EAAS,OAAAqB,EAAQ,MAAAW,EAAO,MAAAtC,CAAA,EAAUR,EACnE+C,EAAUxC,EAAQ,aAClByC,EAA0B,CAC9B,CAAE,MAAAH,EAAO,SAAU,CAACE,EAAS,MAAO,QAAS,OAAQ,CAACvC,CAAK,CAAA,EAC3D,GAAGmC,EAAUR,CAAM,CAAA,EAGjB5B,EAAQ,eACVyC,EAAK,KAAK,CACR,MAAOD,EAAUF,EAAQ,OACzB,SAAUE,EACV,OAAQtC,EAAAA,mBACR,MAAO,WACP,OAAQ,CAACD,GAASD,EAAQ,MAAQ,EAAE,CAAA,CACrC,EAGCY,EAASF,CAAK,GAChB+B,EAAK,KAAK,CAAE,OAAQ,IAAMhC,EAAUC,CAAK,EAAG,MAAO,WAAY,OAAQ,CAACA,EAAM,KAAK,EAAG,EAGxF,MAAMgC,EACJzC,EAAQkB,EAAO,IACX,sBAAsBhB,EAAYH,EAASmB,EAAO,GAAG,CAAC,GACtDlB,EAAQkB,EAAO,IACb,uBAAuBhB,EAAYH,EAASmB,EAAO,GAAG,CAAC,GACvDZ,EACE,GAAGA,EAAQ,MAAQ,SAASA,EAAQ,KAAK,MAAQ,QAAQ,GAAGD,EAAUN,EAASO,CAAO,CAAC,GACvF,UAAUJ,EAAYH,EAASmB,EAAO,GAAG,CAAC,MAAMhB,EAAYH,EAASmB,EAAO,GAAG,CAAC,GAE1F,MAAO,CAAE,KAAAsB,EAAM,SAAAC,EAAU,MAAAH,CAAA,CAC3B,CAGO,SAASI,EAAelD,EAMd,CACf,KAAM,CAAE,QAAAmD,EAAS,QAAA5C,EAAS,QAAAO,EAAS,OAAAqB,EAAQ,MAAA3B,GAAUR,EAC/CoD,EAASD,IAAYrC,EAE3B,MAAO,CACL,KAAM,CACJ,CAAE,MAAOsC,EAAStC,EAAQ,MAAQ,OAAW,SAAUsC,EAAQ,MAAO,cAAe,OAAQ,CAAC5C,CAAK,CAAA,EACnG,GAAGmC,EAAUR,CAAM,CAAA,EAErB,SAAU,GAAGtB,EAAUN,EAASO,CAAO,CAAC,GAAGsC,EAAS,uBAAyB,EAAE,GAC/E,MAAOrC,EAAYD,CAAO,CAAA,CAE9B"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { isNumber as p } from "./gaugeScale.js";
|
|
2
|
+
import { formatarPercentual as h, formatarNumero as V } from "../../../utils/formatters/formatarNumero.js";
|
|
3
|
+
function M(e) {
|
|
4
|
+
const { base: a, formatTooltipValue: n, formatValue: t, segmentUnit: o, valueDisplay: i } = e;
|
|
5
|
+
return {
|
|
6
|
+
againstTarget: a !== null && (i === "percentOfTarget" || o === "percentOfTarget"),
|
|
7
|
+
base: a,
|
|
8
|
+
formatExact: n ?? t,
|
|
9
|
+
formatValue: t,
|
|
10
|
+
showsPercent: a !== null && i === "percentOfTarget"
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
function b(e, a) {
|
|
14
|
+
return h(a / (e.base ?? 1));
|
|
15
|
+
}
|
|
16
|
+
function f(e, a) {
|
|
17
|
+
return e.showsPercent ? b(e, a) : e.formatValue(a);
|
|
18
|
+
}
|
|
19
|
+
function d(e, a, n) {
|
|
20
|
+
const t = e.base ?? 0;
|
|
21
|
+
return e.showsPercent ? `${n(a)} de ${n(t)}` : `${b(e, a)} de ${n(t)}`;
|
|
22
|
+
}
|
|
23
|
+
function T(e, a) {
|
|
24
|
+
return `${f(e, a.from)} a ${f(e, a.to)}`;
|
|
25
|
+
}
|
|
26
|
+
function P(e) {
|
|
27
|
+
return e.label || "Faixa";
|
|
28
|
+
}
|
|
29
|
+
function x(e) {
|
|
30
|
+
return (e.value > 0 ? "+" : e.value < 0 ? "−" : "±") + (e.format ?? V)(Math.abs(e.value));
|
|
31
|
+
}
|
|
32
|
+
function $(e) {
|
|
33
|
+
return e !== void 0 && p(e.value);
|
|
34
|
+
}
|
|
35
|
+
function k(e) {
|
|
36
|
+
const a = e.value > 0 ? "positive" : e.value < 0 ? "negative" : "neutral";
|
|
37
|
+
return {
|
|
38
|
+
glyph: e.value > 0 ? "▲" : e.value < 0 ? "▼" : "●",
|
|
39
|
+
intent: e.intent ?? a,
|
|
40
|
+
kind: "delta",
|
|
41
|
+
label: e.label,
|
|
42
|
+
text: x(e)
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function C(e) {
|
|
46
|
+
const { centerLabel: a, compact: n, delta: t, domain: o, emptyMessage: i, reading: l, showCenter: g, status: s, value: u } = e;
|
|
47
|
+
if (s === "loading")
|
|
48
|
+
return { lines: [{ kind: "text", text: "Carregando…" }] };
|
|
49
|
+
if (s === "empty")
|
|
50
|
+
return { lines: [{ kind: "text", text: i }], value: "—" };
|
|
51
|
+
if (!g)
|
|
52
|
+
return { lines: [] };
|
|
53
|
+
const m = [], r = u > o.max;
|
|
54
|
+
if (r || u < o.min) {
|
|
55
|
+
const c = r ? "acima" : "abaixo";
|
|
56
|
+
m.push({ glyph: r ? "▲" : "▼", kind: "warn", short: c, text: n ? c : `${c} do ${r ? "máximo" : "mínimo"}` });
|
|
57
|
+
}
|
|
58
|
+
const v = a || (l.againstTarget ? d(l, u, l.formatValue) : "");
|
|
59
|
+
return v && !(n && m.length > 0) && m.push({ kind: "text", text: v }), !n && $(t) && m.push(k(t)), { lines: m, value: f(l, u) };
|
|
60
|
+
}
|
|
61
|
+
function E(e) {
|
|
62
|
+
const { delta: a, domain: n, reading: t, segment: o, target: i, value: l } = e, { againstTarget: g, formatExact: s, formatValue: u, showsPercent: m } = t, r = g ? m ? [`${b(t, l)} da meta`, d(t, l, s)] : [s(l), `${b(t, l)} da meta de ${s(t.base ?? 0)}`] : [u(l)], v = (c) => m ? f(t, c) : g ? s(c) : u(c);
|
|
63
|
+
if (l > n.max && r.push(`acima do máximo de ${v(n.max)}`), l < n.min && r.push(`abaixo do mínimo de ${v(n.min)}`), o != null && o.label && r.push(`faixa ${o.label}`), i && p(i.value) && !g) {
|
|
64
|
+
const c = i.label && i.label !== "Meta" ? i.label : "meta";
|
|
65
|
+
r.push(`${c} ${u(i.value)}`);
|
|
66
|
+
}
|
|
67
|
+
return $(a) && r.push(`variação ${x(a)}${a.label ? ` ${a.label}` : ""}`), r.join(", ");
|
|
68
|
+
}
|
|
69
|
+
function w(e) {
|
|
70
|
+
return e && p(e.value) ? [{ label: e.label || "Meta", values: [e.value] }] : [];
|
|
71
|
+
}
|
|
72
|
+
function F(e) {
|
|
73
|
+
const { color: a, delta: n, domain: t, reading: o, segment: i, target: l, title: g, value: s } = e, u = o.showsPercent, m = [
|
|
74
|
+
{ color: a, emphasis: !u, label: "Valor", values: [s] },
|
|
75
|
+
...w(l)
|
|
76
|
+
];
|
|
77
|
+
o.againstTarget && m.push({
|
|
78
|
+
color: u ? a : void 0,
|
|
79
|
+
emphasis: u,
|
|
80
|
+
format: h,
|
|
81
|
+
label: "Atingido",
|
|
82
|
+
values: [s / (o.base ?? 1)]
|
|
83
|
+
}), $(n) && m.push({ format: () => x(n), label: "Variação", values: [n.value] });
|
|
84
|
+
const r = s > t.max ? `Acima do máximo de ${f(o, t.max)}` : s < t.min ? `Abaixo do mínimo de ${f(o, t.min)}` : i ? `${i.label ? `Faixa ${i.label} · ` : "Faixa "}${T(o, i)}` : `Escala ${f(o, t.min)} a ${f(o, t.max)}`;
|
|
85
|
+
return { rows: m, subtitle: r, title: g };
|
|
86
|
+
}
|
|
87
|
+
function N(e) {
|
|
88
|
+
const { current: a, reading: n, segment: t, target: o, value: i } = e, l = a === t;
|
|
89
|
+
return {
|
|
90
|
+
rows: [
|
|
91
|
+
{ color: l ? t.color : void 0, emphasis: l, label: "Valor atual", values: [i] },
|
|
92
|
+
...w(o)
|
|
93
|
+
],
|
|
94
|
+
subtitle: `${T(n, t)}${l ? " · o valor está aqui" : ""}`,
|
|
95
|
+
title: P(t)
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
export {
|
|
99
|
+
x as deltaText,
|
|
100
|
+
b as formatAttainment,
|
|
101
|
+
f as formatShown,
|
|
102
|
+
C as gaugeCenter,
|
|
103
|
+
M as gaugeReading,
|
|
104
|
+
E as gaugeValueText,
|
|
105
|
+
$ as hasDelta,
|
|
106
|
+
d as otherReading,
|
|
107
|
+
T as rangeText,
|
|
108
|
+
P as segmentName,
|
|
109
|
+
N as segmentTooltip,
|
|
110
|
+
F as valueTooltip
|
|
111
|
+
};
|
|
112
|
+
//# sourceMappingURL=gaugeReading.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gaugeReading.js","sources":["../../../../src/components/charts/ChartGauge/gaugeReading.ts"],"sourcesContent":["import { formatarNumero, formatarPercentual } from '../../../utils/formatters';\nimport type { ChartTooltipRow } from '../ChartTooltip';\nimport type { SeriesIntent } from '../palette';\nimport type { ChartGaugeDelta, ChartGaugeTarget } from './ChartGauge';\nimport { isNumber, type GaugeDomain, type GaugeSegment } from './gaugeScale';\n\n/** Como o medidor lê o valor: no formato do consumidor ou contra a meta. */\nexport interface GaugeReading {\n /** Leitura contra a meta: a outra leitura no centro, a linha Atingido no balão e as duas no `aria-valuetext`. */\n againstTarget: boolean;\n /** Meta positiva, base do atingimento. */\n base: number | null;\n formatExact: (value: number) => string;\n formatValue: (value: number) => string;\n /** Centro, escala e intervalos em percentual da meta. */\n showsPercent: boolean;\n}\n\nexport type CenterLine =\n | { kind: 'text'; text: string }\n | { glyph: string; kind: 'warn'; short: string; text: string }\n | { glyph: string; intent: SeriesIntent; kind: 'delta'; label?: string; text: string };\n\nexport interface GaugeCenter {\n lines: readonly CenterLine[];\n value?: string;\n}\n\nexport type GaugeStatus = 'loading' | 'empty' | 'value';\n\nexport interface GaugeTooltip {\n rows: ChartTooltipRow[];\n subtitle?: string;\n title?: string;\n}\n\n/** Quem pede `percentOfTarget`, na exibição ou nas faixas, liga a leitura contra a meta; sem meta, vale o valor. */\nexport function gaugeReading(options: {\n base: number | null;\n formatTooltipValue?: (value: number) => string;\n formatValue: (value: number) => string;\n segmentUnit: string;\n valueDisplay: string;\n}): GaugeReading {\n const { base, formatTooltipValue, formatValue, segmentUnit, valueDisplay } = options;\n\n return {\n againstTarget: base !== null && (valueDisplay === 'percentOfTarget' || segmentUnit === 'percentOfTarget'),\n base,\n formatExact: formatTooltipValue ?? formatValue,\n formatValue,\n showsPercent: base !== null && valueDisplay === 'percentOfTarget',\n };\n}\n\nexport function formatAttainment(reading: GaugeReading, value: number) {\n return formatarPercentual(value / (reading.base ?? 1));\n}\n\n/** O número como a exibição escolhida o mostra. */\nexport function formatShown(reading: GaugeReading, value: number) {\n return reading.showsPercent ? formatAttainment(reading, value) : reading.formatValue(value);\n}\n\n/** A leitura que a exibição não escolheu, como \"92% de R$ 2 mi\" ou \"R$ 1,84 mi de R$ 2 mi\". */\nexport function otherReading(reading: GaugeReading, value: number, format: (value: number) => string) {\n const base = reading.base ?? 0;\n\n return reading.showsPercent\n ? `${format(value)} de ${format(base)}`\n : `${formatAttainment(reading, value)} de ${format(base)}`;\n}\n\nexport function rangeText(reading: GaugeReading, segment: GaugeSegment) {\n return `${formatShown(reading, segment.from)} a ${formatShown(reading, segment.to)}`;\n}\n\nexport function segmentName(segment: GaugeSegment) {\n return segment.label || 'Faixa';\n}\n\n/** O sinal é do componente; o `format` recebe o módulo da variação. */\nexport function deltaText(delta: ChartGaugeDelta) {\n const sign = delta.value > 0 ? '+' : delta.value < 0 ? '−' : '±';\n\n return sign + (delta.format ?? formatarNumero)(Math.abs(delta.value));\n}\n\nexport function hasDelta(delta: ChartGaugeDelta | undefined): delta is ChartGaugeDelta {\n return delta !== undefined && isNumber(delta.value);\n}\n\nfunction deltaLine(delta: ChartGaugeDelta): CenterLine {\n const automatic = delta.value > 0 ? 'positive' : delta.value < 0 ? 'negative' : 'neutral';\n\n return {\n glyph: delta.value > 0 ? '▲' : delta.value < 0 ? '▼' : '●',\n intent: delta.intent ?? automatic,\n kind: 'delta',\n label: delta.label,\n text: deltaText(delta),\n };\n}\n\nexport function gaugeCenter(options: {\n centerLabel?: string;\n compact: boolean;\n delta?: ChartGaugeDelta;\n domain: GaugeDomain;\n emptyMessage: string;\n reading: GaugeReading;\n showCenter: boolean;\n status: GaugeStatus;\n value: number;\n}): GaugeCenter {\n const { centerLabel, compact, delta, domain, emptyMessage, reading, showCenter, status, value } = options;\n\n if (status === 'loading') {\n return { lines: [{ kind: 'text', text: 'Carregando…' }] };\n }\n\n if (status === 'empty') {\n return { lines: [{ kind: 'text', text: emptyMessage }], value: '—' };\n }\n\n if (!showCenter) {\n return { lines: [] };\n }\n\n const lines: CenterLine[] = [];\n const over = value > domain.max;\n\n if (over || value < domain.min) {\n const short = over ? 'acima' : 'abaixo';\n lines.push({ glyph: over ? '▲' : '▼', kind: 'warn', short, text: compact ? short : `${short} do ${over ? 'máximo' : 'mínimo'}` });\n }\n\n const label = centerLabel || (reading.againstTarget ? otherReading(reading, value, reading.formatValue) : '');\n\n // No compacto, o aviso de fora da escala vence o rótulo.\n if (label && !(compact && lines.length > 0)) {\n lines.push({ kind: 'text', text: label });\n }\n\n if (!compact && hasDelta(delta)) {\n lines.push(deltaLine(delta));\n }\n\n return { lines, value: formatShown(reading, value) };\n}\n\n/** A frase do `aria-valuetext`: o valor, o que excede a escala, a faixa, a meta e a variação. */\nexport function gaugeValueText(options: {\n delta?: ChartGaugeDelta;\n domain: GaugeDomain;\n reading: GaugeReading;\n segment?: GaugeSegment;\n target?: ChartGaugeTarget;\n value: number;\n}) {\n const { delta, domain, reading, segment, target, value } = options;\n const { againstTarget, formatExact, formatValue, showsPercent } = reading;\n const parts = !againstTarget\n ? [formatValue(value)]\n : showsPercent\n ? [`${formatAttainment(reading, value)} da meta`, otherReading(reading, value, formatExact)]\n : [formatExact(value), `${formatAttainment(reading, value)} da meta de ${formatExact(reading.base ?? 0)}`];\n const limit = (bound: number) =>\n showsPercent ? formatShown(reading, bound) : againstTarget ? formatExact(bound) : formatValue(bound);\n\n if (value > domain.max) {\n parts.push(`acima do máximo de ${limit(domain.max)}`);\n }\n\n if (value < domain.min) {\n parts.push(`abaixo do mínimo de ${limit(domain.min)}`);\n }\n\n if (segment?.label) {\n parts.push(`faixa ${segment.label}`);\n }\n\n if (target && isNumber(target.value) && !againstTarget) {\n const name = target.label && target.label !== 'Meta' ? target.label : 'meta';\n parts.push(`${name} ${formatValue(target.value)}`);\n }\n\n if (hasDelta(delta)) {\n parts.push(`variação ${deltaText(delta)}${delta.label ? ` ${delta.label}` : ''}`);\n }\n\n return parts.join(', ');\n}\n\nfunction targetRow(target: ChartGaugeTarget | undefined): ChartTooltipRow[] {\n return target && isNumber(target.value) ? [{ label: target.label || 'Meta', values: [target.value] }] : [];\n}\n\n/** Balão do centro ou do arco sem faixas: a faixa do valor, o valor, a meta, o atingido e a variação. */\nexport function valueTooltip(options: {\n color: string;\n delta?: ChartGaugeDelta;\n domain: GaugeDomain;\n reading: GaugeReading;\n segment?: GaugeSegment;\n target?: ChartGaugeTarget;\n title: string;\n value: number;\n}): GaugeTooltip {\n const { color, delta, domain, reading, segment, target, title, value } = options;\n const percent = reading.showsPercent;\n const rows: ChartTooltipRow[] = [\n { color, emphasis: !percent, label: 'Valor', values: [value] },\n ...targetRow(target),\n ];\n\n if (reading.againstTarget) {\n rows.push({\n color: percent ? color : undefined,\n emphasis: percent,\n format: formatarPercentual,\n label: 'Atingido',\n values: [value / (reading.base ?? 1)],\n });\n }\n\n if (hasDelta(delta)) {\n rows.push({ format: () => deltaText(delta), label: 'Variação', values: [delta.value] });\n }\n\n const subtitle =\n value > domain.max\n ? `Acima do máximo de ${formatShown(reading, domain.max)}`\n : value < domain.min\n ? `Abaixo do mínimo de ${formatShown(reading, domain.min)}`\n : segment\n ? `${segment.label ? `Faixa ${segment.label} · ` : 'Faixa '}${rangeText(reading, segment)}`\n : `Escala ${formatShown(reading, domain.min)} a ${formatShown(reading, domain.max)}`;\n\n return { rows, subtitle, title };\n}\n\n/** Balão de uma faixa: o intervalo dela, o valor atual e se ele está ali. */\nexport function segmentTooltip(options: {\n current?: GaugeSegment;\n reading: GaugeReading;\n segment: GaugeSegment;\n target?: ChartGaugeTarget;\n value: number;\n}): GaugeTooltip {\n const { current, reading, segment, target, value } = options;\n const inside = current === segment;\n\n return {\n rows: [\n { color: inside ? segment.color : undefined, emphasis: inside, label: 'Valor atual', values: [value] },\n ...targetRow(target),\n ],\n subtitle: `${rangeText(reading, segment)}${inside ? ' · o valor está aqui' : ''}`,\n title: segmentName(segment),\n };\n}\n"],"names":["gaugeReading","options","base","formatTooltipValue","formatValue","segmentUnit","valueDisplay","formatAttainment","reading","value","formatarPercentual","formatShown","otherReading","format","rangeText","segment","segmentName","deltaText","delta","formatarNumero","hasDelta","isNumber","deltaLine","automatic","gaugeCenter","centerLabel","compact","domain","emptyMessage","showCenter","status","lines","over","short","label","gaugeValueText","target","againstTarget","formatExact","showsPercent","parts","limit","bound","name","targetRow","valueTooltip","color","title","percent","rows","subtitle","segmentTooltip","current","inside"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const b=require("../palette/seriesColor.cjs"),M=1.2,T=100,A=5,c=1e-9;function l(t){return typeof t=="number"&&Number.isFinite(t)}function h(t,{max:n,min:o}){return Math.min(Math.max(t,o),n)}function m(t){return t&&l(t.value)&&t.value>0?t.value:null}function p(t,n,o){const r=l(t)?t:0,u=m(o),s=l(n)?n:u!==null?u*M:T;return{max:s>r?s:r+1,min:r}}function x(t,n,{accent:o,unit:r}){const u=b.resolveSeriesColors(t,{accent:o}),s=[];let i=n.min;return t.forEach((e,a)=>{const f=Math.min(e.to===void 0?n.max:e.to*r,n.max);f>i&&(s.push({color:u[a],from:i,label:e.label,to:f}),i=f)}),s}function D(t,n){return t.find((o,r)=>n>=o.from&&(n<o.to||r===t.length-1&&n<=o.to))}function O(t,n){return l(t)?h(t,n):n.min<0&&n.max>0?0:n.min}function y(t,n,o){if(o===null){const a=Math.max(1,Math.round(n)||A);return Array.from({length:a+1},(f,g)=>t.min+g*(t.max-t.min)/a)}const r=t.min/o,u=t.max/o,s=u-r>=1?.5:.25,i=Math.ceil(r/s-c)*s||0,e=[];for(let a=i;a<=u+c;a=i+e.length*s)e.push(a);return(e.length===0||Math.abs(e[0]-r)>c)&&e.unshift(r),Math.abs(e[e.length-1]-u)>c&&e.push(u),e.map(a=>a*o)}function E(t,n){const o=t.length-1,r=n===null?-1:t.findIndex(i=>Math.abs(i-n)<c*Math.max(1,Math.abs(n))),u=r>0&&r<o?[0,o,r]:[0,o],s=t.map((i,e)=>e).filter(i=>i>0&&i<o&&i!==r);return[...u,...s]}exports.clampToDomain=h;exports.gaugeDomain=p;exports.gaugeOrigin=O;exports.gaugeSegments=x;exports.isNumber=l;exports.majorTicks=y;exports.segmentAt=D;exports.targetBase=m;exports.tickLabelPriority=E;
|
|
2
|
+
//# sourceMappingURL=gaugeScale.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gaugeScale.cjs","sources":["../../../../src/components/charts/ChartGauge/gaugeScale.ts"],"sourcesContent":["import { resolveSeriesColors } from '../palette';\nimport type { ChartGaugeSegment, ChartGaugeTarget } from './ChartGauge';\n\n/** Folga da escala padrão acima da meta: mostra a superação sem achatar as faixas. */\nconst TARGET_HEADROOM = 1.2;\nconst DEFAULT_MAX = 100;\nconst DEFAULT_TICK_COUNT = 5;\nconst EPSILON = 1e-9;\n\nexport interface GaugeDomain {\n max: number;\n min: number;\n}\n\nexport interface GaugeSegment {\n color: string;\n from: number;\n label?: string;\n to: number;\n}\n\nexport function isNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value);\n}\n\nexport function clampToDomain(value: number, { max, min }: GaugeDomain) {\n return Math.min(Math.max(value, min), max);\n}\n\n/** Meta que serve de base ao atingimento: só uma meta positiva divide. */\nexport function targetBase(target: ChartGaugeTarget | undefined) {\n return target && isNumber(target.value) && target.value > 0 ? target.value : null;\n}\n\n/** Sem `max` e com meta, a escala vai a 120% dela. Intervalo vazio ganha uma unidade, como nos eixos. */\nexport function gaugeDomain(min: number | undefined, max: number | undefined, target: ChartGaugeTarget | undefined) {\n const start = isNumber(min) ? min : 0;\n const base = targetBase(target);\n const end = isNumber(max) ? max : base !== null ? base * TARGET_HEADROOM : DEFAULT_MAX;\n\n return { max: end > start ? end : start + 1, min: start };\n}\n\n/**\n * Faixas em ordem crescente, cada uma do fim da anterior até o seu `to`, multiplicado por `unit` quando declarado em\n * fração da meta. Faixa com limite inválido, ou que não avança sobre a anterior, é ignorada.\n */\nexport function gaugeSegments(\n segments: readonly ChartGaugeSegment[],\n domain: GaugeDomain,\n { accent, unit }: { accent?: string; unit: number },\n) {\n const colors = resolveSeriesColors(segments, { accent });\n const resolved: GaugeSegment[] = [];\n let from = domain.min;\n\n segments.forEach((segment, index) => {\n const to = Math.min(segment.to === undefined ? domain.max : segment.to * unit, domain.max);\n\n if (!(to > from)) {\n return;\n }\n\n resolved.push({ color: colors[index], from, label: segment.label, to });\n from = to;\n });\n\n return resolved;\n}\n\nexport function segmentAt(segments: readonly GaugeSegment[], value: number) {\n return segments.find(\n (segment, index) =>\n value >= segment.from && (value < segment.to || (index === segments.length - 1 && value <= segment.to)),\n );\n}\n\n/** De onde o arco preenchido parte: o zero quando a escala o cruza; senão, o mínimo. */\nexport function gaugeOrigin(origin: number | undefined, domain: GaugeDomain) {\n if (isNumber(origin)) {\n return clampToDomain(origin, domain);\n }\n\n return domain.min < 0 && domain.max > 0 ? 0 : domain.min;\n}\n\n/**\n * Marcas principais. Em percentual da meta, a cada 50% dela (25% numa escala curta), com as pontas sempre incluídas;\n * senão, `tickCount` divisões iguais.\n */\nexport function majorTicks(domain: GaugeDomain, tickCount: number, percentBase: number | null) {\n if (percentBase === null) {\n const count = Math.max(1, Math.round(tickCount) || DEFAULT_TICK_COUNT);\n\n return Array.from({ length: count + 1 }, (_, index) => domain.min + (index * (domain.max - domain.min)) / count);\n }\n\n const low = domain.min / percentBase;\n const high = domain.max / percentBase;\n const step = high - low >= 1 ? 0.5 : 0.25;\n // O `|| 0` troca o -0 do arredondamento pelo zero.\n const first = Math.ceil(low / step - EPSILON) * step || 0;\n const ratios: number[] = [];\n\n for (let ratio = first; ratio <= high + EPSILON; ratio = first + ratios.length * step) {\n ratios.push(ratio);\n }\n\n if (ratios.length === 0 || Math.abs(ratios[0] - low) > EPSILON) {\n ratios.unshift(low);\n }\n\n if (Math.abs(ratios[ratios.length - 1] - high) > EPSILON) {\n ratios.push(high);\n }\n\n return ratios.map((ratio) => ratio * percentBase);\n}\n\n/** Ordem em que os rótulos da escala disputam espaço: as pontas, a meta e o resto. */\nexport function tickLabelPriority(ticks: readonly number[], target: number | null) {\n const last = ticks.length - 1;\n const atTarget =\n target === null ? -1 : ticks.findIndex((tick) => Math.abs(tick - target) < EPSILON * Math.max(1, Math.abs(target)));\n const first = atTarget > 0 && atTarget < last ? [0, last, atTarget] : [0, last];\n const rest = ticks.map((_, index) => index).filter((index) => index > 0 && index < last && index !== atTarget);\n\n return [...first, ...rest];\n}\n"],"names":["TARGET_HEADROOM","DEFAULT_MAX","DEFAULT_TICK_COUNT","EPSILON","isNumber","value","clampToDomain","max","min","targetBase","target","gaugeDomain","start","base","end","gaugeSegments","segments","domain","accent","unit","colors","resolveSeriesColors","resolved","from","segment","index","to","segmentAt","gaugeOrigin","origin","majorTicks","tickCount","percentBase","count","_","low","high","step","first","ratios","ratio","tickLabelPriority","ticks","last","atTarget","tick","rest"],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { resolveSeriesColors as m } from "../palette/seriesColor.js";
|
|
2
|
+
const M = 1.2, b = 100, T = 5, a = 1e-9;
|
|
3
|
+
function e(t) {
|
|
4
|
+
return typeof t == "number" && Number.isFinite(t);
|
|
5
|
+
}
|
|
6
|
+
function x(t, { max: n, min: o }) {
|
|
7
|
+
return Math.min(Math.max(t, o), n);
|
|
8
|
+
}
|
|
9
|
+
function p(t) {
|
|
10
|
+
return t && e(t.value) && t.value > 0 ? t.value : null;
|
|
11
|
+
}
|
|
12
|
+
function g(t, n, o) {
|
|
13
|
+
const r = e(t) ? t : 0, c = p(o), i = e(n) ? n : c !== null ? c * M : b;
|
|
14
|
+
return { max: i > r ? i : r + 1, min: r };
|
|
15
|
+
}
|
|
16
|
+
function E(t, n, { accent: o, unit: r }) {
|
|
17
|
+
const c = m(t, { accent: o }), i = [];
|
|
18
|
+
let s = n.min;
|
|
19
|
+
return t.forEach((u, l) => {
|
|
20
|
+
const f = Math.min(u.to === void 0 ? n.max : u.to * r, n.max);
|
|
21
|
+
f > s && (i.push({ color: c[l], from: s, label: u.label, to: f }), s = f);
|
|
22
|
+
}), i;
|
|
23
|
+
}
|
|
24
|
+
function _(t, n) {
|
|
25
|
+
return t.find(
|
|
26
|
+
(o, r) => n >= o.from && (n < o.to || r === t.length - 1 && n <= o.to)
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
function D(t, n) {
|
|
30
|
+
return e(t) ? x(t, n) : n.min < 0 && n.max > 0 ? 0 : n.min;
|
|
31
|
+
}
|
|
32
|
+
function O(t, n, o) {
|
|
33
|
+
if (o === null) {
|
|
34
|
+
const l = Math.max(1, Math.round(n) || T);
|
|
35
|
+
return Array.from({ length: l + 1 }, (f, h) => t.min + h * (t.max - t.min) / l);
|
|
36
|
+
}
|
|
37
|
+
const r = t.min / o, c = t.max / o, i = c - r >= 1 ? 0.5 : 0.25, s = Math.ceil(r / i - a) * i || 0, u = [];
|
|
38
|
+
for (let l = s; l <= c + a; l = s + u.length * i)
|
|
39
|
+
u.push(l);
|
|
40
|
+
return (u.length === 0 || Math.abs(u[0] - r) > a) && u.unshift(r), Math.abs(u[u.length - 1] - c) > a && u.push(c), u.map((l) => l * o);
|
|
41
|
+
}
|
|
42
|
+
function L(t, n) {
|
|
43
|
+
const o = t.length - 1, r = n === null ? -1 : t.findIndex((s) => Math.abs(s - n) < a * Math.max(1, Math.abs(n))), c = r > 0 && r < o ? [0, o, r] : [0, o], i = t.map((s, u) => u).filter((s) => s > 0 && s < o && s !== r);
|
|
44
|
+
return [...c, ...i];
|
|
45
|
+
}
|
|
46
|
+
export {
|
|
47
|
+
x as clampToDomain,
|
|
48
|
+
g as gaugeDomain,
|
|
49
|
+
D as gaugeOrigin,
|
|
50
|
+
E as gaugeSegments,
|
|
51
|
+
e as isNumber,
|
|
52
|
+
O as majorTicks,
|
|
53
|
+
_ as segmentAt,
|
|
54
|
+
p as targetBase,
|
|
55
|
+
L as tickLabelPriority
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=gaugeScale.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gaugeScale.js","sources":["../../../../src/components/charts/ChartGauge/gaugeScale.ts"],"sourcesContent":["import { resolveSeriesColors } from '../palette';\nimport type { ChartGaugeSegment, ChartGaugeTarget } from './ChartGauge';\n\n/** Folga da escala padrão acima da meta: mostra a superação sem achatar as faixas. */\nconst TARGET_HEADROOM = 1.2;\nconst DEFAULT_MAX = 100;\nconst DEFAULT_TICK_COUNT = 5;\nconst EPSILON = 1e-9;\n\nexport interface GaugeDomain {\n max: number;\n min: number;\n}\n\nexport interface GaugeSegment {\n color: string;\n from: number;\n label?: string;\n to: number;\n}\n\nexport function isNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value);\n}\n\nexport function clampToDomain(value: number, { max, min }: GaugeDomain) {\n return Math.min(Math.max(value, min), max);\n}\n\n/** Meta que serve de base ao atingimento: só uma meta positiva divide. */\nexport function targetBase(target: ChartGaugeTarget | undefined) {\n return target && isNumber(target.value) && target.value > 0 ? target.value : null;\n}\n\n/** Sem `max` e com meta, a escala vai a 120% dela. Intervalo vazio ganha uma unidade, como nos eixos. */\nexport function gaugeDomain(min: number | undefined, max: number | undefined, target: ChartGaugeTarget | undefined) {\n const start = isNumber(min) ? min : 0;\n const base = targetBase(target);\n const end = isNumber(max) ? max : base !== null ? base * TARGET_HEADROOM : DEFAULT_MAX;\n\n return { max: end > start ? end : start + 1, min: start };\n}\n\n/**\n * Faixas em ordem crescente, cada uma do fim da anterior até o seu `to`, multiplicado por `unit` quando declarado em\n * fração da meta. Faixa com limite inválido, ou que não avança sobre a anterior, é ignorada.\n */\nexport function gaugeSegments(\n segments: readonly ChartGaugeSegment[],\n domain: GaugeDomain,\n { accent, unit }: { accent?: string; unit: number },\n) {\n const colors = resolveSeriesColors(segments, { accent });\n const resolved: GaugeSegment[] = [];\n let from = domain.min;\n\n segments.forEach((segment, index) => {\n const to = Math.min(segment.to === undefined ? domain.max : segment.to * unit, domain.max);\n\n if (!(to > from)) {\n return;\n }\n\n resolved.push({ color: colors[index], from, label: segment.label, to });\n from = to;\n });\n\n return resolved;\n}\n\nexport function segmentAt(segments: readonly GaugeSegment[], value: number) {\n return segments.find(\n (segment, index) =>\n value >= segment.from && (value < segment.to || (index === segments.length - 1 && value <= segment.to)),\n );\n}\n\n/** De onde o arco preenchido parte: o zero quando a escala o cruza; senão, o mínimo. */\nexport function gaugeOrigin(origin: number | undefined, domain: GaugeDomain) {\n if (isNumber(origin)) {\n return clampToDomain(origin, domain);\n }\n\n return domain.min < 0 && domain.max > 0 ? 0 : domain.min;\n}\n\n/**\n * Marcas principais. Em percentual da meta, a cada 50% dela (25% numa escala curta), com as pontas sempre incluídas;\n * senão, `tickCount` divisões iguais.\n */\nexport function majorTicks(domain: GaugeDomain, tickCount: number, percentBase: number | null) {\n if (percentBase === null) {\n const count = Math.max(1, Math.round(tickCount) || DEFAULT_TICK_COUNT);\n\n return Array.from({ length: count + 1 }, (_, index) => domain.min + (index * (domain.max - domain.min)) / count);\n }\n\n const low = domain.min / percentBase;\n const high = domain.max / percentBase;\n const step = high - low >= 1 ? 0.5 : 0.25;\n // O `|| 0` troca o -0 do arredondamento pelo zero.\n const first = Math.ceil(low / step - EPSILON) * step || 0;\n const ratios: number[] = [];\n\n for (let ratio = first; ratio <= high + EPSILON; ratio = first + ratios.length * step) {\n ratios.push(ratio);\n }\n\n if (ratios.length === 0 || Math.abs(ratios[0] - low) > EPSILON) {\n ratios.unshift(low);\n }\n\n if (Math.abs(ratios[ratios.length - 1] - high) > EPSILON) {\n ratios.push(high);\n }\n\n return ratios.map((ratio) => ratio * percentBase);\n}\n\n/** Ordem em que os rótulos da escala disputam espaço: as pontas, a meta e o resto. */\nexport function tickLabelPriority(ticks: readonly number[], target: number | null) {\n const last = ticks.length - 1;\n const atTarget =\n target === null ? -1 : ticks.findIndex((tick) => Math.abs(tick - target) < EPSILON * Math.max(1, Math.abs(target)));\n const first = atTarget > 0 && atTarget < last ? [0, last, atTarget] : [0, last];\n const rest = ticks.map((_, index) => index).filter((index) => index > 0 && index < last && index !== atTarget);\n\n return [...first, ...rest];\n}\n"],"names":["TARGET_HEADROOM","DEFAULT_MAX","DEFAULT_TICK_COUNT","EPSILON","isNumber","value","clampToDomain","max","min","targetBase","target","gaugeDomain","start","base","end","gaugeSegments","segments","domain","accent","unit","colors","resolveSeriesColors","resolved","from","segment","index","to","segmentAt","gaugeOrigin","origin","majorTicks","tickCount","percentBase","count","_","low","high","step","first","ratios","ratio","tickLabelPriority","ticks","last","atTarget","tick","rest"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("react/jsx-runtime"),Lt=require("d3-array"),gt=require("d3-geo"),Kt=require("d3-scale"),o=require("react"),Ut=require("./ChartMapLegend.cjs"),zt=require("./ChartMapTable.cjs"),se=require("./mapGeometry.cjs"),Ee=require("./mapLabels.cjs"),Gt=require("./mapScales.cjs"),n=require("./ChartMap.module.css.cjs"),vt=require("../core/useChartMetrics.cjs"),xt=require("../core/useSeriesToggle.cjs"),Mt=require("../../../utils/formatters/formatarNumero.cjs"),Vt=require("../palette/seriesColor.cjs"),Wt=require("../../actions/Button/Button.cjs"),Xt=require("../../feedback/EmptyState/EmptyState.cjs"),Jt=require("../../icons/icons.cjs"),Qt=require("../ChartTooltip/ChartTooltip.cjs"),Yt=require("../core/measureText.cjs"),Zt={type:"sequential"},Rt=640,De=160,ea=240,ta="repeating-linear-gradient(45deg, var(--pl-chart-no-data-hatch) 0 1.5px, var(--pl-chart-no-data) 1.5px 4px)",aa="var(--pl-color-surface-subtle)",sa=c=>Mt.formatarPercentual(c,{casasDecimais:1}),na=(c,l,i)=>`${c} ${c===1?l:i}`;function la(c){return c>1e3?.25:c>100?.5:.8}function ra(){try{return process.env.NODE_ENV!=="production"}catch{return!1}}function ia({all:c,callouts:l,fixedHeight:i,font:x,labels:D,maxHeight:j,target:d,valueOf:M,width:y}){const C=g=>Yt.measureLabel(g,x),ge=x.size+1,p=g=>{const _=i?j:Math.round(Math.min(j,Math.max(De,se.naturalHeight(d,g)))),O=se.fitProjection(d,c,g,_);if(!D)return{height:_,plan:{callouts:[],inside:[]},projection:O};const ve=d.map(A=>{let G;return{bounds:se.projectedBounds(A,O),id:A.id,get parts(){return G??(G=se.projectedParts(A,O)),G},title:A.label,value:M(A)}});return{height:_,plan:Ee.planLabels(ve,{callouts:l,calloutStep:x.lineHeight,height:_,lineHeight:ge,measure:C,right:g}),projection:O}},B=p(y);if(B.plan.callouts.length===0)return B;const F=Math.ceil(Math.max(...B.plan.callouts.map(g=>Ee.calloutWidth(g,C)))+Ee.CALLOUT_GAP+4);return p(Math.max(y-F,y/2))}function oa({accent:c,colorScale:l=Zt,data:i=[],defaultHiddenSeries:x,emptyMessage:D="Sem dados",featureIdKey:j="id",featureLabelKey:d,featureNameKey:M="properties.name",focus:y,formatPercent:C=sa,formatTooltipValue:ge,formatValue:p=Mt.formatarNumero,geometry:B,height:F=440,hiddenClasses:g,hiddenSeries:_,legend:O="bottom",legendAlign:ve="center",markerMaxSize:A=20,markerMinSize:G=3,markers:yt,markerValueLabel:xe="Valor",noDataLabel:V="Sem dado",noDataStyle:Be="hatch",onHiddenClassesChange:Fe,onHiddenSeriesChange:$t,onHoverRegion:b,onMarkerClick:Me,onRegionClick:ye,regionLabels:$e="visible",selectedRegion:W,showDataLabels:ke="hidden",showShare:_e=!1,showTableToggle:kt=!0,showTooltip:jt=!0,smallRegionLabels:Le="callout",subtitle:Ke,title:ne,valueLabel:je="Valor"}){var ft;const Ue=o.useId(),ze=o.useId(),Ge=`${o.useId().replace(/[^\w-]/g,"")}-hatch`,be=vt.useChartMetrics(),L=vt.useChartMetrics(),Ve=o.useRef(null),X=xt.useSeriesToggle({defaultHiddenSeries:x,hiddenSeries:_,onHiddenSeriesChange:$t}),bt=o.useMemo(()=>g==null?void 0:g.map(String),[g]),Nt=xt.useSeriesToggle({hiddenSeries:bt,onHiddenSeriesChange:Fe&&(e=>Fe(e.map(Number)))}),[J,Tt]=o.useState(null),[We,Xe]=o.useState(null),[Je,le]=o.useState(null),[Ne,wt]=o.useState(null),[Q,St]=o.useState(!1),v=o.useMemo(()=>se.regionsOf(B,{idKey:j,labelKey:d,nameKey:M}),[j,d,M,B]),Te=(y??[]).join("\0"),{context:Qe,inPlay:re}=o.useMemo(()=>{const e=new Set(Te?Te.split("\0"):[]),t=v.filter(s=>e.has(s.id));return t.length>0?{context:v.filter(s=>!e.has(s.id)),inPlay:t}:{context:[],inPlay:v}},[Te,v]),we=l.type==="categorical"?X:Nt,Ye=we.isHidden,{entries:m,ranked:H,scale:$}=o.useMemo(()=>{const e=new Map;i.forEach(r=>{e.has(r.id)||e.set(r.id,r)});const t=re.map(r=>{const u=e.get(r.id),k=u==null?void 0:u.value;return{category:(u==null?void 0:u.category)??null,region:r,value:typeof k=="number"&&Number.isFinite(k)?k:null}}),s=Gt.buildMapScale(l,t.flatMap(r=>r.value??[]),p,c),h=t.filter(r=>r.value!==null).sort((r,u)=>u.value-r.value),f=new Map(h.map((r,u)=>[r.region.id,u+1])),w=t.map(r=>{const u=s.keyOf(r),k=f.get(r.region.id),S=s.numeric?r.value===null?void 0:p(r.value):s.labelOf(r),E=l.type==="none"?r.region.name:[r.region.name,S??V,k&&`${k}º de ${h.length}`].filter(Boolean).join(", ");return{...r,description:E,fill:s.fillOf(r),hidden:u!==void 0&&Ye(u),key:u,rank:k,valueText:S}});return{entries:w,ranked:w.filter(r=>r.rank!==void 0).sort((r,u)=>r.rank-u.rank),scale:s}},[c,l,i,p,re,Ye,V]),Se=Lt.sum(H,e=>e.value),ie=l.type==="none"?0:m.filter(e=>e.fill===void 0).length,oe=o.useMemo(()=>{const e=new Set(v.map(t=>t.id));return i.filter(t=>!e.has(t.id)).map(t=>t.id).join(", ")},[i,v]);o.useEffect(()=>{oe&&ra()&&console.warn(`ChartMap "${ne}": ${oe.split(", ").length} dado(s) sem região na geometria, fora do desenho: ${oe}.`)},[oe,ne]);const K=yt??[],Ze=o.useMemo(()=>Vt.resolveSeriesColors(K,{accent:c}),[c,K]),ce=new Set(K.flatMap(e=>e.points.filter(t=>[t.latitude,t.longitude,t.value].every(Number.isFinite)&&t.value>=0))),Re=ce.size>0,U=v.length===0||!Re&&($.numeric?H.length===0:l.type==="categorical"&&m.every(e=>e.fill===void 0)),Oe=O==="right"&&be.width>=Rt,Y=O==="right"&&!Oe?"bottom":O,Z=L.width,R=F==="fill",et=R?Math.max(L.height,De):F,tt=$e!=="hidden",at=ke!=="hidden"&&$.numeric,N=o.useMemo(()=>{if(Z===0||U)return;const e=new Map(m.map(t=>[t.region.id,t.valueText]));return ia({all:v,callouts:Le==="callout",fixedHeight:R,font:L.font,labels:tt,maxHeight:et,target:re,valueOf:t=>at?e.get(t.id):void 0,width:Z})},[U,m,R,re,tt,et,L.font,v,Le,at,Z]),q=N==null?void 0:N.projection,st=(N==null?void 0:N.height)??0,P=o.useMemo(()=>{if(!q)return new Map;const e=gt.geoPath(q);return new Map(v.map(t=>[t.id,e(t.shape)??""]))},[q,v]),qe=Kt.scaleSqrt().domain([0,Math.max(...[...ce].map(e=>e.value),1)]).range([0,A]),Ie=q?K.flatMap((e,t)=>X.isHidden(e.id)?[]:e.points.flatMap((s,h)=>{const f=ce.has(s)?q([s.longitude,s.latitude]):null;return f?[{color:Ze[t],key:`marker:${t}:${h}`,point:s,radius:Math.max(G,qe(s.value)),series:e,x:f[0],y:f[1]}]:[]})).sort((e,t)=>t.radius-e.radius):[],I=ye!==void 0,ee=Me!==void 0,nt=I||ee,Ce=e=>`region:${e}`,ue=[...I?m.map((e,t)=>Ce(t)):[],...ee?Ie.map(e=>e.key):[]],de=m.findIndex(e=>e.region.id===W),Ae=ue.includes(Je??"")?Je:I&&de>=0?Ce(de):ue[0],te=e=>e!=null&&e.startsWith("region:")?m[Number(e.slice(7))]:void 0,he=e=>Ie.find(t=>t.key===e),ae=te(We),fe=he(We),T=(J==null?void 0:J.kind)==="region"?J.entry:void 0,Ot=(T==null?void 0:T.region.id)??(ae==null?void 0:ae.region.id),qt=e=>({category:e.category,feature:e.region.feature,id:e.region.id,name:e.region.name,value:e.value}),It=({point:e,series:t})=>({id:e.id,series:t.id,value:e.value}),Ct=({point:e,series:t})=>`${e.label}, ${t.label}, ${p(e.value)}`;function me(e){var t,s;return((s=(t=e.target).getAttribute)==null?void 0:s.call(t,"data-mark"))??null}function lt(e){const t=te(e),s=he(e);Tt(t?{entry:t,kind:"region"}:s?{kind:"marker",marker:s}:null),b==null||b((t==null?void 0:t.region.id)??null)}function rt(e){const t=te(e),s=he(e);t&&ye?(le(e),ye(qt(t))):s&&Me&&(le(e),Me(It(s)))}function At(e,[t,s]){if(!q)return;const h=gt.geoPath(q),f=S=>{const E=te(S),z=he(S);return E?h.centroid(E.region.shape):z?[z.x,z.y]:[0,0]},[w,r]=f(e);let u,k=1/0;return ue.forEach(S=>{if(S===e)return;const[E,z]=f(S),mt=(E-w)*t+(z-r)*s,pt=mt+2*Math.abs((E-w)*s-(z-r)*t);mt>1&&pt<k&&(k=pt,u=S)}),u}function Ht(e){var h,f;const t=me(e),s={ArrowDown:[0,1],ArrowLeft:[-1,0],ArrowRight:[1,0],ArrowUp:[0,-1]};if(!(!t||!ue.includes(t))){if(e.key==="Enter"||e.key===" "){e.preventDefault(),rt(t);return}if(e.key in s){e.preventDefault();const w=At(t,s[e.key]);w&&(le(w),(f=(h=Ve.current)==null?void 0:h.querySelector(`[data-mark="${w}"]`))==null||f.focus())}}}const it={onBlur:()=>{Xe(null),b==null||b(null)},onClick:e=>rt(me(e)),onFocus:e=>{var s;const t=me(e);Xe(t),le(t),b==null||b(((s=te(t))==null?void 0:s.region.id)??null)},onKeyDown:Ht,onMouseOut:()=>lt(null),onMouseOver:e=>lt(me(e))},pe=la(v.length),ot=(N==null?void 0:N.plan)??{callouts:[],inside:[]},ct=L.font.size+1,ut=Be==="hatch"?`url(#${Ge})`:"var(--pl-chart-no-data)",Pt=o.useMemo(()=>m.map((e,t)=>{const s=Ce(t),h=Ne!==null&&e.key!==Ne;return a.jsx("path",{"aria-label":e.description,"aria-pressed":I&&W!==void 0?e.region.id===W:void 0,className:`${n.default.region} ${I?n.default.clickable:""} ${h?n.default.dimmed:""}`,d:P.get(e.region.id),"data-mark":s,fill:e.hidden?aa:e.fill??ut,role:I?"button":void 0,strokeWidth:pe,tabIndex:I?s===Ae?0:-1:void 0},t)}),[m,Ne,ut,P,I,W,pe,Ae]),Et=o.useMemo(()=>Qe.map((e,t)=>a.jsx("path",{className:n.default.context,d:P.get(e.id),strokeWidth:pe},t)),[Qe,P,pe]),Dt=(()=>{const e=na(m.length,"região","regiões"),t=ie>0?` ${ie} sem dado.`:"",s=nt?" Use as setas para percorrer as marcas.":"";if(!$.numeric||H.length===0)return`Mapa de ${e}.${t}${s}`;const[h,f]=[H[0],H[H.length-1]];return`Mapa de ${e}. Maior valor: ${h.region.name}, ${p(h.value)}. Menor: ${f.region.name}, ${p(f.value)}.${t}${s}`})();function dt(e,t){return`${n.default.label} ${t?n.default.labelOnHover:""} ${Ot===e?n.default.labelActive:""}`}const He=q&&a.jsxs("svg",{"aria-describedby":ze,"aria-labelledby":Ue,className:`${n.default.canvas} ${R?n.default.canvasFill:""}`,height:st,ref:Ve,role:nt?"group":"img",viewBox:`0 0 ${Z} ${st}`,width:Z,children:[a.jsx("defs",{children:a.jsxs("pattern",{height:6,id:Ge,patternTransform:"rotate(45)",patternUnits:"userSpaceOnUse",width:6,children:[a.jsx("rect",{className:n.default.hatchBackground,height:6,width:6}),a.jsx("line",{className:n.default.hatchLine,x1:0,x2:0,y1:0,y2:6})]})}),a.jsx("g",{"aria-hidden":"true",className:n.default.passThrough,children:Et}),a.jsx("g",{...it,children:Pt}),a.jsxs("g",{"aria-hidden":"true",className:n.default.passThrough,children:[de>=0&&a.jsx("path",{className:n.default.selectedOutline,d:P.get(m[de].region.id)}),T&&a.jsx("path",{className:n.default.hoverOutline,d:P.get(T.region.id)}),ae&&a.jsx("path",{className:n.default.focusOutline,d:P.get(ae.region.id)})]}),a.jsxs("g",{...it,children:[Ie.map(e=>a.jsx("circle",{"aria-label":Ct(e),className:`${n.default.marker} ${ee?n.default.clickable:""}`,cx:e.x,cy:e.y,"data-mark":e.key,fill:e.color,r:e.radius,role:ee?"button":"img",tabIndex:ee?e.key===Ae?0:-1:void 0},e.key)),fe&&a.jsx("circle",{"aria-hidden":"true",className:n.default.focusOutline,cx:fe.x,cy:fe.y,r:fe.radius+3})]}),a.jsxs("g",{"aria-hidden":"true",className:n.default.passThrough,children:[ot.inside.map(e=>a.jsxs("text",{className:dt(e.id,$e==="onHover"),x:e.x,y:e.y,children:[a.jsx("tspan",{dominantBaseline:"central",x:e.x,y:e.value?e.y-ct/2:e.y,children:e.title}),e.value&&a.jsx("tspan",{className:`${n.default.labelValue} ${ke==="onHover"?n.default.valueOnHover:""}`,dominantBaseline:"central",x:e.x,y:e.y+ct/2,children:e.value})]},e.id)),ot.callouts.map(e=>a.jsxs("g",{className:dt(e.id,$e==="onHover"),children:[a.jsx("path",{className:n.default.leader,d:`M${e.anchor[0]},${e.anchor[1]}L${e.x-12},${e.y}L${e.x-4},${e.y}`}),a.jsx("circle",{className:n.default.leaderDot,cx:e.anchor[0],cy:e.anchor[1],r:1.8}),a.jsxs("text",{className:n.default.callout,dominantBaseline:"central",x:e.x,y:e.y,children:[e.title,e.value&&a.jsx("tspan",{className:`${n.default.labelValue} ${ke==="onHover"?n.default.valueOnHover:""}`,dx:5,children:e.value})]})]},e.id))]})]}),Bt=ca(J,{formatPercent:C,formatTooltipValue:ge??p,markerValueLabel:xe,noDataLabel:V,rankedCount:H.length,scale:$,showShare:_e,total:Se,valueLabel:je,colorScale:l}),Pe=new Map;m.forEach(e=>e.key!==void 0&&Pe.set(e.key,(Pe.get(e.key)??0)+1));const ht=Y!=="none"&&a.jsx(Ut.ChartMapLegend,{align:ve,entries:$.entries.map(e=>({...e,count:Pe.get(e.key)??0,hidden:we.isHidden(e.key)})),formatValue:p,gradient:$.gradient,indicator:(T==null?void 0:T.value)==null||(ft=$.gradient)==null?void 0:ft.position(T.value),markerSeries:K.map((e,t)=>({color:Ze[t],hidden:X.isHidden(e.id),key:e.id,label:e.label})),markerSizes:Re?{maximum:qe.domain()[1],radiusOf:e=>Math.max(G,qe(e))}:void 0,markerValueLabel:xe,noData:ie>0?{color:Be==="hatch"?ta:"var(--pl-chart-no-data)",count:ie,label:V}:void 0,onHighlight:e=>wt(e),onToggle:we.toggle,onToggleMarkerSeries:X.toggle,position:Y,style:Oe?{width:Math.min(ea,Math.round(be.width*.3))}:void 0,valueLabel:je}),Ft=m.filter(e=>!e.hidden).map(e=>({classLabel:l.type==="classes"?$.labelOf(e):void 0,id:e.region.id,name:e.region.name,rank:e.rank,selected:e.region.id===W,share:e.value!==null&&Se>0?e.value/Se:void 0,value:e.value,valueText:e.valueText})),_t=K.flatMap(e=>X.isHidden(e.id)?[]:e.points.filter(t=>ce.has(t)).map(t=>({key:`${e.id}:${t.id}`,name:t.label,series:e.label,value:p(t.value)})));return a.jsxs("figure",{className:n.default.figure,children:[a.jsxs("figcaption",{className:n.default.header,children:[a.jsxs("span",{className:n.default.heading,children:[a.jsx("span",{className:n.default.title,id:Ue,children:ne}),Ke&&a.jsx("span",{className:n.default.subtitle,children:Ke})]}),kt&&!U&&a.jsx(Wt.Button,{"aria-pressed":Q,className:n.default.tableToggle,onClick:()=>St(e=>!e),size:"sm",variant:"secondary",children:"Ver como tabela"})]}),a.jsx("span",{className:n.default.visuallyHidden,id:ze,children:Dt}),a.jsxs("div",{className:`${n.default.body} ${Oe&&!Q?n.default.bodyRow:""}`,ref:be.ref,children:[Y==="top"&&!Q&&!U&&ht,U?a.jsx("div",{className:n.default.empty,children:a.jsx(Xt.EmptyState,{icon:a.jsx(Jt.IconChartBar,{}),size:"sm",title:D})}):Q?a.jsx(zt.ChartMapTable,{markerRows:_t,markerValueLabel:xe,maxHeight:typeof F=="number"?Math.max(F,De):void 0,noDataLabel:V,regionRows:Ft,showClasses:l.type==="classes",showRank:$.numeric,showShare:_e&&$.numeric,showValue:l.type!=="none",formatPercent:C,title:ne,valueLabel:je}):a.jsx("div",{className:`${n.default.plot} ${R?n.default.plotFill:""}`,ref:L.ref,children:He&&(jt?a.jsx(Qt.ChartTooltip,{...Bt,children:He}):He)}),(Y==="bottom"||Y==="right")&&!Q&&!U&&ht]})]})}function ca(c,l){if(c===null)return{rows:[]};if(c.kind==="marker"){const{color:M,point:y,series:C}=c.marker;return{columns:[{format:l.formatTooltipValue}],computed:"none",rows:[{color:M,label:l.markerValueLabel,values:[y.value]}],subtitle:C.label,title:y.label}}const{entry:i}=c,{region:x}=i,D=x.label!==x.name?x.label:void 0,j=(M,y)=>({format:()=>y,label:M,values:[0]}),d=[];if(l.colorScale.type==="none")d.push({label:D??x.name,values:[]});else if(!l.scale.numeric)d.push(i.valueText?{...j(l.valueLabel,i.valueText),color:i.fill}:{label:l.noDataLabel,values:[]});else if(i.value===null)d.push({label:l.noDataLabel,values:[]});else{d.push({color:i.fill,label:l.valueLabel,values:[i.value]});const M=l.colorScale.type==="classes"?l.scale.labelOf(i):void 0;M&&d.push(j("Faixa",M)),l.showShare&&l.total>0&&d.push({format:l.formatPercent,label:"% do total",values:[i.value/l.total]}),d.push(j("Posição",`${i.rank}º de ${l.rankedCount}`))}return i.hidden&&d.push({label:"Oculta pela legenda",values:[]}),{columns:[{format:l.formatTooltipValue}],computed:"none",rows:d,subtitle:D,title:x.name}}exports.ChartMap=oa;
|
|
2
|
+
//# sourceMappingURL=ChartMap.cjs.map
|