@ojiepermana/angular-chart 22.0.27
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/README.md +249 -0
- package/fesm2022/ojiepermana-angular-chart-area.mjs +266 -0
- package/fesm2022/ojiepermana-angular-chart-area.mjs.map +1 -0
- package/fesm2022/ojiepermana-angular-chart-bar.mjs +674 -0
- package/fesm2022/ojiepermana-angular-chart-bar.mjs.map +1 -0
- package/fesm2022/ojiepermana-angular-chart-core.mjs +764 -0
- package/fesm2022/ojiepermana-angular-chart-core.mjs.map +1 -0
- package/fesm2022/ojiepermana-angular-chart-line.mjs +281 -0
- package/fesm2022/ojiepermana-angular-chart-line.mjs.map +1 -0
- package/fesm2022/ojiepermana-angular-chart-pie.mjs +248 -0
- package/fesm2022/ojiepermana-angular-chart-pie.mjs.map +1 -0
- package/fesm2022/ojiepermana-angular-chart-primitives.mjs +1186 -0
- package/fesm2022/ojiepermana-angular-chart-primitives.mjs.map +1 -0
- package/fesm2022/ojiepermana-angular-chart-radar.mjs +329 -0
- package/fesm2022/ojiepermana-angular-chart-radar.mjs.map +1 -0
- package/fesm2022/ojiepermana-angular-chart-radial.mjs +255 -0
- package/fesm2022/ojiepermana-angular-chart-radial.mjs.map +1 -0
- package/fesm2022/ojiepermana-angular-chart-scatter.mjs +253 -0
- package/fesm2022/ojiepermana-angular-chart-scatter.mjs.map +1 -0
- package/fesm2022/ojiepermana-angular-chart.mjs +20 -0
- package/fesm2022/ojiepermana-angular-chart.mjs.map +1 -0
- package/package.json +76 -0
- package/types/ojiepermana-angular-chart-area.d.ts +58 -0
- package/types/ojiepermana-angular-chart-bar.d.ts +171 -0
- package/types/ojiepermana-angular-chart-core.d.ts +369 -0
- package/types/ojiepermana-angular-chart-line.d.ts +57 -0
- package/types/ojiepermana-angular-chart-pie.d.ts +93 -0
- package/types/ojiepermana-angular-chart-primitives.d.ts +265 -0
- package/types/ojiepermana-angular-chart-radar.d.ts +89 -0
- package/types/ojiepermana-angular-chart-radial.d.ts +86 -0
- package/types/ojiepermana-angular-chart-scatter.d.ts +95 -0
- package/types/ojiepermana-angular-chart.d.ts +2 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ojiepermana-angular-chart-core.mjs","sources":["../../../library/chart/core/chart-config.ts","../../../library/chart/core/chart-context.ts","../../../library/chart/core/chart-style.ts","../../../library/chart/core/chart-container.ts","../../../library/chart/core/cartesian-context.ts","../../../library/chart/core/categorical-viewport-context.ts","../../../library/chart/core/scatter-viewport-context.ts","../../../library/chart/core/ticks.ts","../../../library/chart/core/viewport.ts","../../../library/chart/core/pointer-util.ts","../../../library/chart/core/line-layout.ts","../../../library/chart/core/cartesian-adapter.ts","../../../library/chart/core/ojiepermana-angular-chart-core.ts"],"sourcesContent":["import type { Type } from '@angular/core';\n\n/**\n * Theme-aware color definition for a chart series.\n *\n * Either:\n * - a single `color` string (raw CSS color — hex, hsl, oklch, CSS var ref), or\n * - a `theme` map whose keys match the document color scheme (`light` / `dark`).\n *\n * Values are injected verbatim into a scoped `<style>` block as\n * `--color-<key>: <value>;`, so any valid CSS color works.\n *\n * Defaults reference the theme tokens from `@ojiepermana/angular-theme/styles`\n * (e.g. `'hsl(var(--chart-1))'`).\n */\nexport interface ChartSeriesConfig {\n /** Human-readable label (shown in legend, tooltip). */\n readonly label?: string;\n /** Optional icon component rendered next to the label. */\n readonly icon?: Type<unknown>;\n /** Raw color. Mutually exclusive with `theme`. */\n readonly color?: string;\n /** Theme-aware colors — keyed by color scheme. */\n readonly theme?: Readonly<Record<ChartThemeKey, string>>;\n}\n\n/** Supported color scheme keys. */\nexport type ChartThemeKey = 'light' | 'dark';\n\n/** Map of series-key → config. */\nexport type ChartConfig = Readonly<Record<string, ChartSeriesConfig>>;\n\n/** CSS selector under which a chart instance is scoped. */\nexport const CHART_DATA_ATTRIBUTE = 'data-chart';\n\n/** Default color schemes supported by the generated `<style>` block. */\nexport const CHART_THEMES: ReadonlyArray<{\n readonly key: ChartThemeKey;\n readonly selector: string;\n}> = [\n { key: 'light', selector: '' },\n { key: 'dark', selector: '[data-mode=\"dark\"]' },\n];\n\n/**\n * Generate the CSS rule-set for a chart instance: one `--color-<key>` per\n * series, scoped to the owning `[data-chart]` element, with optional dark\n * variant via `[data-mode=\"dark\"] [data-chart=\"…\"]`.\n *\n * Series without any color are skipped (consumer can fall back to a default).\n *\n * @param chartId Unique chart id (used as attribute value).\n * @param config Series configuration map.\n */\nexport function buildChartCss(chartId: string, config: ChartConfig): string {\n const entries = Object.entries(config).filter(([, cfg]) => cfg.color || cfg.theme);\n if (entries.length === 0) {\n return '';\n }\n\n return CHART_THEMES.map(({ key, selector }) => {\n const vars = entries\n .map(([seriesKey, cfg]) => {\n const value = cfg.theme?.[key] ?? cfg.color;\n return value ? ` --color-${escapeCssIdent(seriesKey)}: ${value};` : '';\n })\n .filter(Boolean)\n .join('\\n');\n\n if (!vars) {\n return '';\n }\n\n const scope = selector\n ? `${selector} [${CHART_DATA_ATTRIBUTE}=\"${chartId}\"]`\n : `[${CHART_DATA_ATTRIBUTE}=\"${chartId}\"]`;\n return `${scope} {\\n${vars}\\n}`;\n })\n .filter(Boolean)\n .join('\\n');\n}\n\n/**\n * Escape a string so it is safe to use as a CSS custom-property identifier.\n * Allows `[A-Za-z0-9_-]`; everything else becomes `_`.\n */\nfunction escapeCssIdent(input: string): string {\n return input.replace(/[^a-zA-Z0-9_-]/g, '_');\n}\n\n/** Resolve the `var(--color-<key>)` reference for a given series. */\nexport function seriesColorVar(seriesKey: string): string {\n return `var(--color-${seriesKey.replace(/[^a-zA-Z0-9_-]/g, '_')})`;\n}\n","import { Injectable, signal, computed, type Signal } from '@angular/core';\nimport type { ChartConfig } from './chart-config';\n\n/** Pixel dimensions of the chart render area. */\nexport interface ChartDimensions {\n readonly width: number;\n readonly height: number;\n}\n\n/** Active data point (for tooltip / crosshair) shared across primitives. */\nexport interface ChartActivePoint {\n readonly index: number;\n readonly datumIndex?: number;\n readonly seriesKey?: string;\n readonly clientX?: number;\n readonly clientY?: number;\n}\n\n/**\n * Shared chart state provided by `ChartContainer` to all nested chart\n * components (axes, grid, tooltip, legend, chart types).\n *\n * All state is exposed as signals so consumers can derive computed state\n * (scales, visible series, tooltip position) without manual subscriptions.\n */\n@Injectable()\nexport class ChartContext {\n /** Stable instance id — used in the `data-chart` attribute and CSS scope. */\n readonly id = signal<string>('');\n\n /** User-provided series config. */\n readonly config = signal<ChartConfig>({});\n\n /** Measured render-area dimensions (ResizeObserver-driven). */\n readonly dimensions = signal<ChartDimensions>({ width: 0, height: 0 });\n\n /** Currently highlighted data point (tooltip / crosshair). */\n readonly activePoint = signal<ChartActivePoint | null>(null);\n\n /** Series keys the user has toggled off via legend. */\n readonly hiddenSeries = signal<ReadonlySet<string>>(new Set());\n\n /** Ordered list of series keys (from `config`). */\n readonly seriesKeys: Signal<readonly string[]> = computed(() => Object.keys(this.config()));\n\n /** Series keys currently visible (config order minus `hiddenSeries`). */\n readonly visibleSeriesKeys: Signal<readonly string[]> = computed(() => {\n const hidden = this.hiddenSeries();\n return this.seriesKeys().filter((k) => !hidden.has(k));\n });\n\n /** Toggle visibility of a series. */\n toggleSeries(key: string): void {\n this.hiddenSeries.update((set) => {\n const next = new Set(set);\n if (next.has(key)) {\n next.delete(key);\n } else {\n next.add(key);\n }\n return next;\n });\n }\n}\n","import { ChangeDetectionStrategy, Component, ElementRef, Renderer2, computed, effect, inject } from '@angular/core';\nimport { ChartContext } from './chart-context';\nimport { buildChartCss } from './chart-config';\n\n/**\n * Emits a scoped `<style>` block mapping every series key in the current\n * `ChartConfig` to a `--color-<key>` CSS custom property, scoped to\n * `[data-chart=\"<id>\"]`. Dark-mode values are scoped under `[data-mode=\"dark\"]`.\n *\n * Implemented as an empty component that injects a real `<style>` element\n * into its host via `Renderer2`. We avoid rendering `<style>` directly in a\n * template — Angular hoists those into component CSS and strips\n * interpolations from them.\n *\n * Consumers never instantiate this directly — `ChartContainer` renders it.\n */\n@Component({\n selector: 'ChartStyle',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: '',\n})\nexport class ChartStyle {\n private readonly ctx = inject(ChartContext);\n private readonly host = inject(ElementRef<HTMLElement>);\n private readonly renderer = inject(Renderer2);\n private styleEl: HTMLStyleElement | null = null;\n\n protected readonly css = computed(() => buildChartCss(this.ctx.id(), this.ctx.config()));\n\n constructor() {\n effect(() => {\n const css = this.css();\n if (!this.styleEl) {\n this.styleEl = this.renderer.createElement('style');\n this.renderer.appendChild(this.host.nativeElement, this.styleEl);\n }\n this.styleEl!.textContent = css;\n });\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n NgZone,\n PLATFORM_ID,\n afterNextRender,\n computed,\n effect,\n inject,\n input,\n signal,\n viewChild,\n} from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { ChartContext } from './chart-context';\nimport { ChartStyle } from './chart-style';\nimport { CHART_DATA_ATTRIBUTE, type ChartConfig } from './chart-config';\n\nlet chartIdCounter = 0;\n\n/**\n * Root of every chart. Provides `ChartContext` to descendants, reflects the\n * chart id via `data-chart`, injects the per-instance CSS-variable\n * `<style>` block, and tracks its render-area dimensions via\n * `ResizeObserver`.\n *\n * Usage:\n * ```html\n * <Chart [config]=\"cfg\">\n * <ChartBar [data]=\"data\" />\n * <ChartLegend />\n * </Chart>\n * ```\n *\n * The chart render area is laid out on top; any projected `<ChartLegend>` is\n * rendered as a centered row beneath it. Render-area dimensions are measured on\n * the chart area only, so the legend never shrinks the chart.\n */\n@Component({\n selector: 'Chart',\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [ChartContext],\n imports: [ChartStyle],\n host: {\n '[attr.data-chart]': 'ctx.id()',\n class: 'relative flex flex-col text-xs',\n },\n template: `\n <ChartStyle />\n <div #area data-chart-area [class]=\"areaClass()\">\n <ng-content />\n </div>\n <ng-content select=\"ChartLegend\" />\n `,\n})\nexport class ChartContainer {\n protected readonly ctx = inject(ChartContext);\n private readonly zone = inject(NgZone);\n private readonly platformId = inject(PLATFORM_ID);\n private readonly destroyRef = inject(DestroyRef);\n private readonly areaRef = viewChild.required<ElementRef<HTMLElement>>('area');\n\n /** Series configuration. Required for color / label resolution. */\n readonly config = input.required<ChartConfig>();\n\n /**\n * Tailwind aspect-ratio utility for the chart render area. Defaults to\n * `aspect-video` for cartesian charts; override with `aspect-square` for\n * radial / pie layouts, or e.g. `aspect-auto h-[320px]` for a fixed height.\n */\n readonly aspect = input<string>('aspect-video');\n\n protected readonly areaClass = computed(() => `relative flex ${this.aspect()} w-full justify-center`);\n\n /**\n * Optional explicit id override. When omitted, a stable auto-id is\n * generated (`chart-<n>`), unique across the document.\n */\n readonly chartId = input<string | null>(null);\n\n constructor() {\n const autoId = `chart-${++chartIdCounter}`;\n\n // Sync id + config into the shared context.\n effect(() => {\n this.ctx.id.set(this.chartId() ?? autoId);\n });\n effect(() => {\n this.ctx.config.set(this.config());\n });\n\n // Observe host size (browser only; client-only is a confirmed constraint).\n if (isPlatformBrowser(this.platformId)) {\n afterNextRender(() => this.observeSize());\n }\n }\n\n private observeSize(): void {\n const el = this.areaRef().nativeElement;\n if (typeof ResizeObserver === 'undefined') {\n const rect = el.getBoundingClientRect();\n this.ctx.dimensions.set({ width: rect.width, height: rect.height });\n return;\n }\n\n const observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const { width, height } = entry.contentRect;\n // Avoid NgZone churn — dimensions signal drives CD on its own.\n this.zone.run(() => this.ctx.dimensions.set({ width, height }));\n }\n });\n observer.observe(el);\n this.destroyRef.onDestroy(() => observer.disconnect());\n }\n}\n\n/**\n * Re-export the `data-chart` attribute constant for primitives that want to\n * target the same scope in their own templates.\n */\nexport { CHART_DATA_ATTRIBUTE };\n","import { Injectable, signal, type Signal } from '@angular/core';\nimport type { ScaleBand, ScaleLinear } from 'd3-scale';\n\n/** A single row of chart data — one categorical key + N numeric series. */\nexport type ChartDatum = Readonly<Record<string, unknown>>;\n\n/** Render-area margins inside the chart's SVG (px). */\nexport interface ChartMargin {\n readonly top: number;\n readonly right: number;\n readonly bottom: number;\n readonly left: number;\n}\n\n/** Axis orientation for cartesian charts. */\nexport type ChartOrientation = 'vertical' | 'horizontal';\n\n/** Primary axis scale — band for categorical, linear for numeric. */\nexport type CategoryScale = ScaleBand<string>;\nexport type ValueScale = ScaleLinear<number, number>;\n\n/**\n * Cartesian plotting frame shared between a chart type (Bar, Line, Area…)\n * and its axis / grid primitives.\n *\n * The owning chart component provides an instance and publishes its scales;\n * descendants read them via signals and re-render when dimensions or data\n * change.\n */\n@Injectable()\nexport class CartesianContext {\n /** Inner width (outer width − margin.left − margin.right). */\n readonly innerWidth = signal<number>(0);\n\n /** Inner height (outer height − margin.top − margin.bottom). */\n readonly innerHeight = signal<number>(0);\n\n /** Margins around the plotting area. */\n readonly margin = signal<ChartMargin>({ top: 8, right: 8, bottom: 24, left: 40 });\n\n /** Layout orientation (drives which axis holds the band scale). */\n readonly orientation = signal<ChartOrientation>('vertical');\n\n /** Band (categorical) scale. */\n readonly categoryScale = signal<CategoryScale | null>(null);\n\n /** Linear (numeric) scale. */\n readonly valueScale = signal<ValueScale | null>(null);\n\n /** Ordered category domain (e.g. x labels for vertical, y labels for horizontal). */\n readonly categories = signal<readonly string[]>([]);\n}\n\n/** Resolve the scale that maps to the X axis for a given orientation. */\nexport function xScale(\n ctx: Pick<CartesianContext, 'orientation' | 'categoryScale' | 'valueScale'>,\n): Signal<CategoryScale | ValueScale | null> {\n return ctx.orientation() === 'vertical' ? ctx.categoryScale : ctx.valueScale;\n}\n\n/** Resolve the scale that maps to the Y axis for a given orientation. */\nexport function yScale(\n ctx: Pick<CartesianContext, 'orientation' | 'categoryScale' | 'valueScale'>,\n): Signal<CategoryScale | ValueScale | null> {\n return ctx.orientation() === 'vertical' ? ctx.valueScale : ctx.categoryScale;\n}\n","import { Injectable, computed, signal } from '@angular/core';\nimport type { ChartIndexRange } from './viewport';\n\n@Injectable()\nexport class CategoricalViewportContext {\n readonly dataCount = signal<number>(0);\n readonly brushRange = signal<ChartIndexRange | null>(null);\n readonly zoomRange = signal<ChartIndexRange | null>(null);\n\n readonly hasZoom = computed(() => {\n const range = this.zoomRange();\n const count = this.dataCount();\n return !!range && count > 0 && (range.startIndex > 0 || range.endIndex < count - 1);\n });\n\n resetZoom(): void {\n this.brushRange.set(null);\n this.zoomRange.set(null);\n }\n}\n","import { Injectable, computed, signal } from '@angular/core';\nimport type { ScaleLinear } from 'd3-scale';\nimport type { NumericDomain } from './viewport';\n\n@Injectable()\nexport class ScatterViewportContext {\n readonly innerWidth = signal<number>(0);\n readonly innerHeight = signal<number>(0);\n readonly fullXDomain = signal<NumericDomain | null>(null);\n readonly fullYDomain = signal<NumericDomain | null>(null);\n readonly zoomXDomain = signal<NumericDomain | null>(null);\n readonly zoomYDomain = signal<NumericDomain | null>(null);\n readonly xScale = signal<ScaleLinear<number, number> | null>(null);\n readonly yScale = signal<ScaleLinear<number, number> | null>(null);\n\n readonly hasZoom = computed(() => this.zoomXDomain() !== null || this.zoomYDomain() !== null);\n\n resetZoom(): void {\n this.zoomXDomain.set(null);\n this.zoomYDomain.set(null);\n }\n}\n","import type { ScaleBand, ScaleLinear } from 'd3-scale';\n\n/** A tick descriptor for rendering axes. */\nexport interface ChartTick {\n readonly value: string | number;\n /** Offset (px) along the axis. For band scales this is the band center. */\n readonly offset: number;\n /** Display label. */\n readonly label: string;\n}\n\n/** Produce evenly-spaced ticks for a band (categorical) scale. */\nexport function bandTicks(scale: ScaleBand<string>): ChartTick[] {\n const half = scale.bandwidth() / 2;\n return scale.domain().map((value) => ({\n value,\n offset: (scale(value) ?? 0) + half,\n label: value,\n }));\n}\n\n/**\n * Produce ticks for a linear scale.\n *\n * @param scale The linear scale.\n * @param count Approximate number of ticks (hint, d3 may return fewer/more).\n * @param formatter Label formatter.\n */\nexport function linearTicks(\n scale: ScaleLinear<number, number>,\n count = 5,\n formatter: (value: number) => string = (v) => String(v),\n): ChartTick[] {\n return scale.ticks(count).map((value) => ({\n value,\n offset: scale(value),\n label: formatter(value),\n }));\n}\n","export interface ChartIndexRange {\n readonly startIndex: number;\n readonly endIndex: number;\n}\n\nexport type NumericDomain = readonly [number, number];\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value));\n}\n\nexport function normalizeIndexRange(start: number, end: number, maxCount: number): ChartIndexRange | null {\n if (maxCount <= 0) {\n return null;\n }\n const lo = clamp(Math.floor(Math.min(start, end)), 0, maxCount - 1);\n const hi = clamp(Math.floor(Math.max(start, end)), 0, maxCount - 1);\n return { startIndex: lo, endIndex: hi };\n}\n\nexport function effectiveIndexRange(range: ChartIndexRange | null, maxCount: number): ChartIndexRange | null {\n if (maxCount <= 0) {\n return null;\n }\n return range\n ? normalizeIndexRange(range.startIndex, range.endIndex, maxCount)\n : { startIndex: 0, endIndex: maxCount - 1 };\n}\n\nexport function indexRangeSize(range: ChartIndexRange | null, maxCount: number): number {\n const effective = effectiveIndexRange(range, maxCount);\n return effective ? effective.endIndex - effective.startIndex + 1 : 0;\n}\n\nexport function sliceByIndexRange<T>(data: readonly T[], range: ChartIndexRange | null): readonly T[] {\n if (!range) {\n return data;\n }\n return data.slice(range.startIndex, range.endIndex + 1);\n}\n\nexport function zoomIndexRange(\n current: ChartIndexRange | null,\n maxCount: number,\n anchorIndex: number,\n factor: number,\n): ChartIndexRange | null {\n const base = effectiveIndexRange(current, maxCount);\n if (!base) {\n return null;\n }\n\n const currentSize = base.endIndex - base.startIndex + 1;\n const nextSize = clamp(Math.round(currentSize * factor), 2, maxCount);\n if (nextSize >= maxCount) {\n return null;\n }\n\n const boundedAnchor = clamp(anchorIndex, base.startIndex, base.endIndex);\n const ratio = currentSize <= 1 ? 0.5 : (boundedAnchor - base.startIndex) / (currentSize - 1);\n\n let start = Math.round(boundedAnchor - ratio * (nextSize - 1));\n start = clamp(start, 0, maxCount - nextSize);\n return { startIndex: start, endIndex: start + nextSize - 1 };\n}\n\nexport function panIndexRange(\n current: ChartIndexRange | null,\n maxCount: number,\n deltaSteps: number,\n): ChartIndexRange | null {\n const base = effectiveIndexRange(current, maxCount);\n if (!base) {\n return null;\n }\n const size = base.endIndex - base.startIndex + 1;\n if (size >= maxCount) {\n return null;\n }\n\n const start = clamp(base.startIndex + deltaSteps, 0, maxCount - size);\n return { startIndex: start, endIndex: start + size - 1 };\n}\n\nexport function normalizeNumericDomain(a: number, b: number): NumericDomain {\n if (a === b) {\n return [a - 1, b + 1];\n }\n return a < b ? [a, b] : [b, a];\n}\n\nexport function zoomNumericDomain(\n current: NumericDomain,\n full: NumericDomain,\n anchor: number,\n factor: number,\n): NumericDomain {\n const currentWidth = current[1] - current[0];\n const fullWidth = full[1] - full[0];\n const nextWidth = clamp(currentWidth * factor, fullWidth / 50, fullWidth);\n if (nextWidth >= fullWidth) {\n return full;\n }\n\n const ratio = currentWidth === 0 ? 0.5 : (anchor - current[0]) / currentWidth;\n let start = anchor - ratio * nextWidth;\n start = clamp(start, full[0], full[1] - nextWidth);\n return [start, start + nextWidth];\n}\n\nexport function panNumericDomain(current: NumericDomain, full: NumericDomain, delta: number): NumericDomain {\n const width = current[1] - current[0];\n const start = clamp(current[0] + delta, full[0], full[1] - width);\n return [start, start + width];\n}\n","import type { CartesianContext } from './cartesian-context';\n\nexport interface ClientPoint {\n readonly clientX: number;\n readonly clientY: number;\n}\n\n/**\n * Given a pointer event's local (x, y) relative to the chart's inner group,\n * resolve the nearest category index along the categorical axis.\n *\n * @returns index into `ctx.categories()` (or −1 if no scale / no data).\n */\nexport function nearestCategoryIndex(\n ctx: Pick<CartesianContext, 'categoryScale' | 'categories' | 'orientation'>,\n localX: number,\n localY: number,\n): number {\n const scale = ctx.categoryScale();\n const categories = ctx.categories();\n if (!scale || categories.length === 0) return -1;\n\n const isVertical = ctx.orientation() === 'vertical';\n const pointerAlong = isVertical ? localX : localY;\n\n const bandwidth = scale.bandwidth();\n // scale.step() is only defined for band scales; fall back to bandwidth.\n const step = (scale as unknown as { step?: () => number }).step?.() ?? bandwidth;\n\n let bestIndex = -1;\n let bestDelta = Infinity;\n for (let i = 0; i < categories.length; i++) {\n const base = scale(categories[i]) ?? 0;\n const center = base + bandwidth / 2;\n const delta = Math.abs(pointerAlong - center);\n if (delta < bestDelta) {\n bestDelta = delta;\n bestIndex = i;\n }\n }\n\n // Ignore clicks far outside any band (> 1 step away).\n if (bestDelta > step) {\n return -1;\n }\n return bestIndex;\n}\n\n/** Resolve the client-space center point of a focused or clicked SVG/HTML element. */\nexport function elementClientCenter(target: EventTarget | null): ClientPoint | null {\n const el = target as Element | null;\n if (!el || typeof el.getBoundingClientRect !== 'function') {\n return null;\n }\n const rect = el.getBoundingClientRect();\n return {\n clientX: rect.left + rect.width / 2,\n clientY: rect.top + rect.height / 2,\n };\n}\n","import { scalePoint, scaleLinear } from 'd3-scale';\nimport { max as d3max } from 'd3-array';\nimport {\n line as d3line,\n area as d3area,\n stack as d3stack,\n stackOffsetExpand,\n curveMonotoneX,\n curveLinear,\n curveStep,\n type CurveFactory,\n} from 'd3-shape';\nimport type { ChartDatum, ChartOrientation } from './cartesian-context';\nimport { seriesColorVar } from './chart-config';\n\n/** Curve type shared by line & area charts. */\nexport type LineCurve = 'linear' | 'monotone' | 'step';\n\nfunction curveFor(curve: LineCurve): CurveFactory {\n switch (curve) {\n case 'monotone':\n return curveMonotoneX;\n case 'step':\n return curveStep;\n case 'linear':\n default:\n return curveLinear;\n }\n}\n\n/** A single series ready to render as either a line or an area. */\nexport interface LineSeriesPath {\n readonly seriesKey: string;\n readonly color: string;\n readonly linePath: string;\n /** Optional area path — only populated when `computeAreaLayout` is used. */\n readonly areaPath?: string;\n /** Raw points for dots / active markers. */\n readonly points: readonly LinePoint[];\n}\n\n/** One resolved (x, y) point for a series. */\nexport interface LinePoint {\n readonly seriesKey: string;\n readonly datumIndex: number;\n readonly category: string;\n readonly value: number;\n readonly x: number;\n readonly y: number;\n}\n\nexport interface CartesianBase {\n readonly data: readonly ChartDatum[];\n readonly xKey: string;\n readonly seriesKeys: readonly string[];\n readonly orientation: ChartOrientation;\n readonly innerWidth: number;\n readonly innerHeight: number;\n readonly curve: LineCurve;\n}\n\nexport interface LineLayoutResult {\n readonly series: readonly LineSeriesPath[];\n readonly points: readonly LinePoint[];\n readonly categoryScale: ReturnType<typeof scalePoint<string>>;\n readonly valueScale: ReturnType<typeof scaleLinear<number, number>>;\n readonly categories: readonly string[];\n}\n\nexport interface AreaLayoutResult extends LineLayoutResult {\n readonly stacked: boolean;\n}\n\nfunction readNumber(datum: ChartDatum, key: string): number {\n const raw = datum[key];\n if (typeof raw === 'number' && Number.isFinite(raw)) return raw;\n if (typeof raw === 'string') {\n const n = Number(raw);\n return Number.isFinite(n) ? n : 0;\n }\n return 0;\n}\n\n/** Build category + value scales for point-based charts (line / area). */\nexport function buildCartesianScales(input: CartesianBase): {\n categories: readonly string[];\n categoryScale: ReturnType<typeof scalePoint<string>>;\n valueScale: ReturnType<typeof scaleLinear<number, number>>;\n} {\n const { data, xKey, seriesKeys, orientation, innerWidth, innerHeight } = input;\n const isVertical = orientation === 'vertical';\n const categories = data.map((d) => String(d[xKey] ?? ''));\n\n const categoryScale = scalePoint<string>()\n .domain(categories)\n .range(isVertical ? [0, innerWidth] : [0, innerHeight])\n .padding(0);\n\n const maxValue = d3max(data, (d) => d3max(seriesKeys, (k) => readNumber(d, k)) ?? 0) ?? 0;\n\n const valueScale = scaleLinear<number, number>()\n .domain([0, maxValue === 0 ? 1 : maxValue])\n .nice()\n .range(isVertical ? [innerHeight, 0] : [0, innerWidth]);\n\n return { categories, categoryScale, valueScale };\n}\n\n/** Compute line-chart geometry. */\nexport function computeLineLayout(input: CartesianBase): LineLayoutResult {\n const { data, seriesKeys, orientation, curve } = input;\n const { categories, categoryScale, valueScale } = buildCartesianScales(input);\n const isVertical = orientation === 'vertical';\n\n const allPoints: LinePoint[] = [];\n const series: LineSeriesPath[] = [];\n\n for (const seriesKey of seriesKeys) {\n const points: LinePoint[] = data.map((d, datumIndex) => {\n const value = readNumber(d, seriesKey);\n const category = categories[datumIndex];\n const c = categoryScale(category) ?? 0;\n const v = valueScale(value);\n return {\n seriesKey,\n datumIndex,\n category,\n value,\n x: isVertical ? c : v,\n y: isVertical ? v : c,\n };\n });\n allPoints.push(...points);\n\n const generator = d3line<LinePoint>()\n .x((p) => p.x)\n .y((p) => p.y)\n .curve(curveFor(curve));\n\n series.push({\n seriesKey,\n color: seriesColorVar(seriesKey),\n linePath: generator(points) ?? '',\n points,\n });\n }\n\n return {\n series,\n points: allPoints,\n categoryScale,\n valueScale,\n categories,\n };\n}\n\nexport interface AreaLayoutInput extends CartesianBase {\n readonly stacked: boolean;\n readonly expanded?: boolean;\n}\n\n/** Compute area-chart geometry (single or stacked). */\nexport function computeAreaLayout(input: AreaLayoutInput): AreaLayoutResult {\n if (input.stacked && input.seriesKeys.length > 0) {\n return computeStackedArea(input);\n }\n return computeSingleArea(input);\n}\n\nfunction computeSingleArea(input: AreaLayoutInput): AreaLayoutResult {\n const { data, seriesKeys, orientation, curve } = input;\n const { categories, categoryScale, valueScale } = buildCartesianScales(input);\n const isVertical = orientation === 'vertical';\n const baseline = isVertical ? valueScale(0) : valueScale(0);\n\n const allPoints: LinePoint[] = [];\n const series: LineSeriesPath[] = [];\n\n for (const seriesKey of seriesKeys) {\n const points: LinePoint[] = data.map((d, datumIndex) => {\n const value = readNumber(d, seriesKey);\n const category = categories[datumIndex];\n const c = categoryScale(category) ?? 0;\n const v = valueScale(value);\n return {\n seriesKey,\n datumIndex,\n category,\n value,\n x: isVertical ? c : v,\n y: isVertical ? v : c,\n };\n });\n allPoints.push(...points);\n\n const lineGen = d3line<LinePoint>()\n .x((p) => p.x)\n .y((p) => p.y)\n .curve(curveFor(curve));\n\n const areaGen = isVertical\n ? d3area<LinePoint>()\n .x((p) => p.x)\n .y0(baseline)\n .y1((p) => p.y)\n .curve(curveFor(curve))\n : d3area<LinePoint>()\n .y((p) => p.y)\n .x0(baseline)\n .x1((p) => p.x)\n .curve(curveFor(curve));\n\n series.push({\n seriesKey,\n color: seriesColorVar(seriesKey),\n linePath: lineGen(points) ?? '',\n areaPath: areaGen(points) ?? '',\n points,\n });\n }\n\n return {\n series,\n points: allPoints,\n categoryScale,\n valueScale,\n categories,\n stacked: false,\n };\n}\n\nfunction computeStackedArea(input: AreaLayoutInput): AreaLayoutResult {\n const { data, seriesKeys, orientation, innerWidth, innerHeight, xKey, curve, expanded } = input;\n const isVertical = orientation === 'vertical';\n const categories = data.map((d) => String(d[xKey] ?? ''));\n\n const categoryScale = scalePoint<string>()\n .domain(categories)\n .range(isVertical ? [0, innerWidth] : [0, innerHeight])\n .padding(0);\n\n const normalized = data.map((d) => {\n const out: Record<string, number> = {};\n for (const k of seriesKeys) out[k] = readNumber(d, k);\n return out;\n });\n\n const stackGenerator = d3stack<Record<string, number>, string>().keys(seriesKeys as string[]);\n if (expanded) {\n stackGenerator.offset(stackOffsetExpand);\n }\n const stackSeries = stackGenerator(normalized);\n\n const maxTotal = expanded ? 1 : (d3max(stackSeries[stackSeries.length - 1] ?? [], (p) => p[1]) ?? 0);\n const valueScale = scaleLinear<number, number>()\n .domain([0, maxTotal === 0 ? 1 : maxTotal])\n .range(isVertical ? [innerHeight, 0] : [0, innerWidth]);\n\n if (!expanded) {\n valueScale.nice();\n }\n\n const allPoints: LinePoint[] = [];\n const series: LineSeriesPath[] = stackSeries.map((layer) => {\n const seriesKey = layer.key;\n const points: LinePoint[] = layer.map((p, datumIndex) => {\n const category = categories[datumIndex];\n const c = categoryScale(category) ?? 0;\n const upper = valueScale(p[1]);\n return {\n seriesKey,\n datumIndex,\n category,\n value: p[1] - p[0],\n x: isVertical ? c : upper,\n y: isVertical ? upper : c,\n };\n });\n allPoints.push(...points);\n\n const lineGen = d3line<[number, number, number]>()\n .x(([x]) => x)\n .y(([, y]) => y)\n .curve(curveFor(curve));\n\n const areaGen = isVertical\n ? d3area<[number, number, number]>()\n .x(([x]) => x)\n .y0(([, , y0]) => y0)\n .y1(([, y1]) => y1)\n .curve(curveFor(curve))\n : d3area<[number, number, number]>()\n .y(([x]) => x)\n .x0(([, , x0]) => x0)\n .x1(([, x1]) => x1)\n .curve(curveFor(curve));\n\n const tuples: [number, number, number][] = layer.map((p, i) => {\n const c = categoryScale(categories[i]) ?? 0;\n return [c, valueScale(p[1]), valueScale(p[0])];\n });\n\n return {\n seriesKey,\n color: seriesColorVar(seriesKey),\n linePath: lineGen(tuples) ?? '',\n areaPath: areaGen(tuples) ?? '',\n points,\n };\n });\n\n return {\n series,\n points: allPoints,\n categoryScale,\n valueScale,\n categories,\n stacked: true,\n };\n}\n","import { scaleLinear, scaleBand } from 'd3-scale';\nimport type { ScalePoint } from 'd3-scale';\nimport { CartesianContext } from './cartesian-context';\n\n/**\n * Publish a `scalePoint` from line/area layouts to the `CartesianContext`,\n * which expects a `scaleBand`. Line/area points sit on the range edges (the\n * point scale has zero padding, so the first point touches the y-axis and the\n * last touches the right edge). We extend the band range by half a step on\n * each side so band centers — used to position axis ticks — line up exactly\n * with those edge-touching points.\n *\n * This keeps axes/grid primitives agnostic to whether the underlying chart\n * uses `scaleBand` (bar) or `scalePoint` (line/area).\n */\nexport function pointToBandAdapter(\n pointScale: ScalePoint<string>,\n range: [number, number],\n): ReturnType<typeof scaleBand<string>> {\n const half = pointScale.step() / 2;\n const extended: [number, number] = [range[0] - half, range[1] + half];\n return scaleBand<string>().domain(pointScale.domain()).range(extended).padding(0);\n}\n\n/** Recreate a linear scale with the same domain/range (handy for effects). */\nexport function cloneLinear(\n scale: ReturnType<typeof scaleLinear<number, number>>,\n): ReturnType<typeof scaleLinear<number, number>> {\n return scaleLinear<number, number>().domain(scale.domain()).range(scale.range());\n}\n\nexport function provideCartesianFromLineLayout(\n ctx: CartesianContext,\n layout: {\n categoryScale: ScalePoint<string>;\n valueScale: ReturnType<typeof scaleLinear<number, number>>;\n categories: readonly string[];\n },\n orientation: 'vertical' | 'horizontal',\n innerWidth: number,\n innerHeight: number,\n): void {\n const range: [number, number] = orientation === 'vertical' ? [0, innerWidth] : [0, innerHeight];\n ctx.orientation.set(orientation);\n ctx.innerWidth.set(innerWidth);\n ctx.innerHeight.set(innerHeight);\n ctx.categoryScale.set(pointToBandAdapter(layout.categoryScale, range));\n ctx.valueScale.set(cloneLinear(layout.valueScale));\n ctx.categories.set(layout.categories);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["d3max","d3line","d3area","d3stack"],"mappings":"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"}
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { inject, input, output, computed, effect, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { ChartContext, CartesianContext, CategoricalViewportContext, sliceByIndexRange, computeLineLayout, provideCartesianFromLineLayout, elementClientCenter } from '@ojiepermana/angular-chart/core';
|
|
4
|
+
export { buildCartesianScales, cloneLinear, computeAreaLayout, computeLineLayout, pointToBandAdapter, provideCartesianFromLineLayout } from '@ojiepermana/angular-chart/core';
|
|
5
|
+
import { ChartPointerTracker } from '@ojiepermana/angular-chart/primitives';
|
|
6
|
+
|
|
7
|
+
const DEFAULT_MARGIN = { top: 8, right: 8, bottom: 24, left: 40 };
|
|
8
|
+
const defaultLineValueFormatter = (value) => `${value}`;
|
|
9
|
+
class LineChart {
|
|
10
|
+
root = inject(ChartContext);
|
|
11
|
+
cart = inject(CartesianContext);
|
|
12
|
+
viewport = inject(CategoricalViewportContext);
|
|
13
|
+
data = input.required(/* @ts-ignore */
|
|
14
|
+
...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
|
|
15
|
+
xKey = input.required(/* @ts-ignore */
|
|
16
|
+
...(ngDevMode ? [{ debugName: "xKey" }] : /* istanbul ignore next */ []));
|
|
17
|
+
orientation = input('vertical', /* @ts-ignore */
|
|
18
|
+
...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
|
|
19
|
+
styles = input('base', /* @ts-ignore */
|
|
20
|
+
...(ngDevMode ? [{ debugName: "styles" }] : /* istanbul ignore next */ []));
|
|
21
|
+
curve = input('monotone', /* @ts-ignore */
|
|
22
|
+
...(ngDevMode ? [{ debugName: "curve" }] : /* istanbul ignore next */ []));
|
|
23
|
+
margin = input(DEFAULT_MARGIN, /* @ts-ignore */
|
|
24
|
+
...(ngDevMode ? [{ debugName: "margin" }] : /* istanbul ignore next */ []));
|
|
25
|
+
strokeWidth = input(2, /* @ts-ignore */
|
|
26
|
+
...(ngDevMode ? [{ debugName: "strokeWidth" }] : /* istanbul ignore next */ []));
|
|
27
|
+
showDots = input(true, /* @ts-ignore */
|
|
28
|
+
...(ngDevMode ? [{ debugName: "showDots" }] : /* istanbul ignore next */ []));
|
|
29
|
+
dotRadius = input(3, /* @ts-ignore */
|
|
30
|
+
...(ngDevMode ? [{ debugName: "dotRadius" }] : /* istanbul ignore next */ []));
|
|
31
|
+
dotColorKey = input(undefined, /* @ts-ignore */
|
|
32
|
+
...(ngDevMode ? [{ debugName: "dotColorKey" }] : /* istanbul ignore next */ []));
|
|
33
|
+
dotStrokeColor = input(undefined, /* @ts-ignore */
|
|
34
|
+
...(ngDevMode ? [{ debugName: "dotStrokeColor" }] : /* istanbul ignore next */ []));
|
|
35
|
+
dotStrokeWidth = input(0, /* @ts-ignore */
|
|
36
|
+
...(ngDevMode ? [{ debugName: "dotStrokeWidth" }] : /* istanbul ignore next */ []));
|
|
37
|
+
showValueLabels = input(false, /* @ts-ignore */
|
|
38
|
+
...(ngDevMode ? [{ debugName: "showValueLabels" }] : /* istanbul ignore next */ []));
|
|
39
|
+
valueLabelFormat = input(defaultLineValueFormatter, /* @ts-ignore */
|
|
40
|
+
...(ngDevMode ? [{ debugName: "valueLabelFormat" }] : /* istanbul ignore next */ []));
|
|
41
|
+
pointClick = output();
|
|
42
|
+
innerWidth = computed(() => Math.max(0, this.root.dimensions().width - this.margin().left - this.margin().right), /* @ts-ignore */
|
|
43
|
+
...(ngDevMode ? [{ debugName: "innerWidth" }] : /* istanbul ignore next */ []));
|
|
44
|
+
innerHeight = computed(() => Math.max(0, this.root.dimensions().height - this.margin().top - this.margin().bottom), /* @ts-ignore */
|
|
45
|
+
...(ngDevMode ? [{ debugName: "innerHeight" }] : /* istanbul ignore next */ []));
|
|
46
|
+
visibleStartIndex = computed(() => this.viewport.zoomRange()?.startIndex ?? 0, /* @ts-ignore */
|
|
47
|
+
...(ngDevMode ? [{ debugName: "visibleStartIndex" }] : /* istanbul ignore next */ []));
|
|
48
|
+
visibleData = computed(() => sliceByIndexRange(this.data(), this.viewport.zoomRange()), /* @ts-ignore */
|
|
49
|
+
...(ngDevMode ? [{ debugName: "visibleData" }] : /* istanbul ignore next */ []));
|
|
50
|
+
layout = computed(() => computeLineLayout({
|
|
51
|
+
data: this.visibleData(),
|
|
52
|
+
xKey: this.xKey(),
|
|
53
|
+
seriesKeys: this.root.visibleSeriesKeys(),
|
|
54
|
+
orientation: this.orientation(),
|
|
55
|
+
innerWidth: this.innerWidth(),
|
|
56
|
+
innerHeight: this.innerHeight(),
|
|
57
|
+
curve: this.curve(),
|
|
58
|
+
}), /* @ts-ignore */
|
|
59
|
+
...(ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []));
|
|
60
|
+
series = computed(() => this.layout().series, /* @ts-ignore */
|
|
61
|
+
...(ngDevMode ? [{ debugName: "series" }] : /* istanbul ignore next */ []));
|
|
62
|
+
viewBox = computed(() => {
|
|
63
|
+
const { width, height } = this.root.dimensions();
|
|
64
|
+
return `0 0 ${Math.max(0, width)} ${Math.max(0, height)}`;
|
|
65
|
+
}, /* @ts-ignore */
|
|
66
|
+
...(ngDevMode ? [{ debugName: "viewBox" }] : /* istanbul ignore next */ []));
|
|
67
|
+
innerTransform = computed(() => `translate(${this.margin().left},${this.margin().top})`, /* @ts-ignore */
|
|
68
|
+
...(ngDevMode ? [{ debugName: "innerTransform" }] : /* istanbul ignore next */ []));
|
|
69
|
+
ariaSummary = computed(() => {
|
|
70
|
+
const keys = this.root.visibleSeriesKeys();
|
|
71
|
+
return `Line chart, ${this.visibleData().length} points, ${keys.length} series: ${keys.join(', ')}.`;
|
|
72
|
+
}, /* @ts-ignore */
|
|
73
|
+
...(ngDevMode ? [{ debugName: "ariaSummary" }] : /* istanbul ignore next */ []));
|
|
74
|
+
constructor() {
|
|
75
|
+
effect(() => {
|
|
76
|
+
const layout = this.layout();
|
|
77
|
+
this.viewport.dataCount.set(this.data().length);
|
|
78
|
+
provideCartesianFromLineLayout(this.cart, layout, this.orientation(), this.innerWidth(), this.innerHeight());
|
|
79
|
+
this.cart.margin.set(this.margin());
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
emitClick(p) {
|
|
83
|
+
const datumIndex = this.visibleStartIndex() + p.datumIndex;
|
|
84
|
+
this.pointClick.emit({
|
|
85
|
+
seriesKey: p.seriesKey,
|
|
86
|
+
datumIndex,
|
|
87
|
+
category: p.category,
|
|
88
|
+
value: p.value,
|
|
89
|
+
datum: this.data()[datumIndex],
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
setActivePoint(event, p) {
|
|
93
|
+
const center = elementClientCenter(event.currentTarget);
|
|
94
|
+
const datumIndex = this.visibleStartIndex() + p.datumIndex;
|
|
95
|
+
this.root.activePoint.set({
|
|
96
|
+
index: p.datumIndex,
|
|
97
|
+
datumIndex,
|
|
98
|
+
seriesKey: p.seriesKey,
|
|
99
|
+
clientX: center?.clientX,
|
|
100
|
+
clientY: center?.clientY,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
clearActivePoint() {
|
|
104
|
+
this.root.activePoint.set(null);
|
|
105
|
+
}
|
|
106
|
+
dotFill(point, fallbackColor) {
|
|
107
|
+
const colorKey = this.dotColorKey();
|
|
108
|
+
if (!colorKey) {
|
|
109
|
+
return fallbackColor;
|
|
110
|
+
}
|
|
111
|
+
const datum = this.visibleData()[point.datumIndex];
|
|
112
|
+
const raw = datum?.[colorKey];
|
|
113
|
+
if (typeof raw !== 'string' || raw.length === 0) {
|
|
114
|
+
return fallbackColor;
|
|
115
|
+
}
|
|
116
|
+
if (raw.startsWith('var(') ||
|
|
117
|
+
raw.startsWith('#') ||
|
|
118
|
+
raw.startsWith('rgb') ||
|
|
119
|
+
raw.startsWith('hsl') ||
|
|
120
|
+
raw.includes('(')) {
|
|
121
|
+
return raw;
|
|
122
|
+
}
|
|
123
|
+
return `var(--color-${raw.replace(/[^a-zA-Z0-9_-]/g, '_')})`;
|
|
124
|
+
}
|
|
125
|
+
formatValueLabel(point) {
|
|
126
|
+
return this.valueLabelFormat()(point.value);
|
|
127
|
+
}
|
|
128
|
+
labelX(point) {
|
|
129
|
+
return this.orientation() === 'vertical' ? point.x : point.x + this.dotRadius() + 6;
|
|
130
|
+
}
|
|
131
|
+
labelY(point) {
|
|
132
|
+
return this.orientation() === 'vertical' ? point.y - this.dotRadius() - 8 : point.y;
|
|
133
|
+
}
|
|
134
|
+
labelAnchor() {
|
|
135
|
+
return this.orientation() === 'vertical' ? 'middle' : 'start';
|
|
136
|
+
}
|
|
137
|
+
pointAriaLabel(p) {
|
|
138
|
+
const label = this.root.config()[p.seriesKey]?.label ?? p.seriesKey;
|
|
139
|
+
return `${label} at ${p.category}: ${p.value}`;
|
|
140
|
+
}
|
|
141
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: LineChart, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
142
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: LineChart, isStandalone: true, selector: "ChartLine", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, xKey: { classPropertyName: "xKey", publicName: "xKey", isSignal: true, isRequired: true, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, styles: { classPropertyName: "styles", publicName: "styles", isSignal: true, isRequired: false, transformFunction: null }, curve: { classPropertyName: "curve", publicName: "curve", isSignal: true, isRequired: false, transformFunction: null }, margin: { classPropertyName: "margin", publicName: "margin", isSignal: true, isRequired: false, transformFunction: null }, strokeWidth: { classPropertyName: "strokeWidth", publicName: "strokeWidth", isSignal: true, isRequired: false, transformFunction: null }, showDots: { classPropertyName: "showDots", publicName: "showDots", isSignal: true, isRequired: false, transformFunction: null }, dotRadius: { classPropertyName: "dotRadius", publicName: "dotRadius", isSignal: true, isRequired: false, transformFunction: null }, dotColorKey: { classPropertyName: "dotColorKey", publicName: "dotColorKey", isSignal: true, isRequired: false, transformFunction: null }, dotStrokeColor: { classPropertyName: "dotStrokeColor", publicName: "dotStrokeColor", isSignal: true, isRequired: false, transformFunction: null }, dotStrokeWidth: { classPropertyName: "dotStrokeWidth", publicName: "dotStrokeWidth", isSignal: true, isRequired: false, transformFunction: null }, showValueLabels: { classPropertyName: "showValueLabels", publicName: "showValueLabels", isSignal: true, isRequired: false, transformFunction: null }, valueLabelFormat: { classPropertyName: "valueLabelFormat", publicName: "valueLabelFormat", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pointClick: "pointClick" }, host: { properties: { "attr.data-style": "styles()" }, classAttribute: "relative block h-full w-full" }, providers: [CartesianContext, CategoricalViewportContext], ngImport: i0, template: `
|
|
143
|
+
<svg:svg
|
|
144
|
+
ChartPointerTracker
|
|
145
|
+
class="block h-full w-full overflow-visible"
|
|
146
|
+
[attr.viewBox]="viewBox()"
|
|
147
|
+
preserveAspectRatio="none"
|
|
148
|
+
role="img"
|
|
149
|
+
[attr.aria-label]="ariaSummary()">
|
|
150
|
+
<svg:g [attr.transform]="innerTransform()">
|
|
151
|
+
<ng-content select="svg\\:g[ChartGrid]" />
|
|
152
|
+
<svg:g class="chart-lines">
|
|
153
|
+
@for (s of series(); track s.seriesKey) {
|
|
154
|
+
<svg:path
|
|
155
|
+
class="chart-line"
|
|
156
|
+
fill="none"
|
|
157
|
+
stroke-linecap="round"
|
|
158
|
+
stroke-linejoin="round"
|
|
159
|
+
[attr.stroke]="s.color"
|
|
160
|
+
[attr.stroke-width]="strokeWidth()"
|
|
161
|
+
[attr.d]="s.linePath" />
|
|
162
|
+
@if (showDots()) {
|
|
163
|
+
@for (p of s.points; track p.datumIndex) {
|
|
164
|
+
<svg:circle
|
|
165
|
+
class="chart-dot cursor-pointer outline-none"
|
|
166
|
+
[attr.cx]="p.x"
|
|
167
|
+
[attr.cy]="p.y"
|
|
168
|
+
[attr.r]="dotRadius()"
|
|
169
|
+
[attr.fill]="dotFill(p, s.color)"
|
|
170
|
+
[attr.stroke]="dotStrokeColor()"
|
|
171
|
+
[attr.stroke-width]="dotStrokeWidth() || null"
|
|
172
|
+
[attr.aria-label]="pointAriaLabel(p)"
|
|
173
|
+
tabindex="0"
|
|
174
|
+
(focus)="setActivePoint($event, p)"
|
|
175
|
+
(blur)="clearActivePoint()"
|
|
176
|
+
(click)="emitClick(p)"
|
|
177
|
+
(keydown.enter)="emitClick(p)"
|
|
178
|
+
(keydown.space)="emitClick(p); $event.preventDefault()" />
|
|
179
|
+
@if (showValueLabels()) {
|
|
180
|
+
<svg:text
|
|
181
|
+
class="chart-line-value pointer-events-none fill-muted-foreground text-2xs"
|
|
182
|
+
[attr.x]="labelX(p)"
|
|
183
|
+
[attr.y]="labelY(p)"
|
|
184
|
+
[attr.text-anchor]="labelAnchor()"
|
|
185
|
+
dominant-baseline="middle">
|
|
186
|
+
{{ formatValueLabel(p) }}
|
|
187
|
+
</svg:text>
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
</svg:g>
|
|
193
|
+
<ng-content select="svg\\:g[ChartAxisX]" />
|
|
194
|
+
<ng-content select="svg\\:g[ChartAxisY]" />
|
|
195
|
+
<ng-content select="svg\\:g[ChartCrosshair]" />
|
|
196
|
+
<ng-content select="svg:g[ChartBrush]" />
|
|
197
|
+
</svg:g>
|
|
198
|
+
</svg:svg>
|
|
199
|
+
<ng-content select="ChartTooltip" />
|
|
200
|
+
<ng-content select="ChartLegend" />
|
|
201
|
+
<ng-content select="ChartZoomControls" />
|
|
202
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: ChartPointerTracker, selector: "svg:svg[ChartPointerTracker]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
203
|
+
}
|
|
204
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: LineChart, decorators: [{
|
|
205
|
+
type: Component,
|
|
206
|
+
args: [{
|
|
207
|
+
selector: 'ChartLine',
|
|
208
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
209
|
+
providers: [CartesianContext, CategoricalViewportContext],
|
|
210
|
+
imports: [ChartPointerTracker],
|
|
211
|
+
host: { class: 'relative block h-full w-full', '[attr.data-style]': 'styles()' },
|
|
212
|
+
template: `
|
|
213
|
+
<svg:svg
|
|
214
|
+
ChartPointerTracker
|
|
215
|
+
class="block h-full w-full overflow-visible"
|
|
216
|
+
[attr.viewBox]="viewBox()"
|
|
217
|
+
preserveAspectRatio="none"
|
|
218
|
+
role="img"
|
|
219
|
+
[attr.aria-label]="ariaSummary()">
|
|
220
|
+
<svg:g [attr.transform]="innerTransform()">
|
|
221
|
+
<ng-content select="svg\\:g[ChartGrid]" />
|
|
222
|
+
<svg:g class="chart-lines">
|
|
223
|
+
@for (s of series(); track s.seriesKey) {
|
|
224
|
+
<svg:path
|
|
225
|
+
class="chart-line"
|
|
226
|
+
fill="none"
|
|
227
|
+
stroke-linecap="round"
|
|
228
|
+
stroke-linejoin="round"
|
|
229
|
+
[attr.stroke]="s.color"
|
|
230
|
+
[attr.stroke-width]="strokeWidth()"
|
|
231
|
+
[attr.d]="s.linePath" />
|
|
232
|
+
@if (showDots()) {
|
|
233
|
+
@for (p of s.points; track p.datumIndex) {
|
|
234
|
+
<svg:circle
|
|
235
|
+
class="chart-dot cursor-pointer outline-none"
|
|
236
|
+
[attr.cx]="p.x"
|
|
237
|
+
[attr.cy]="p.y"
|
|
238
|
+
[attr.r]="dotRadius()"
|
|
239
|
+
[attr.fill]="dotFill(p, s.color)"
|
|
240
|
+
[attr.stroke]="dotStrokeColor()"
|
|
241
|
+
[attr.stroke-width]="dotStrokeWidth() || null"
|
|
242
|
+
[attr.aria-label]="pointAriaLabel(p)"
|
|
243
|
+
tabindex="0"
|
|
244
|
+
(focus)="setActivePoint($event, p)"
|
|
245
|
+
(blur)="clearActivePoint()"
|
|
246
|
+
(click)="emitClick(p)"
|
|
247
|
+
(keydown.enter)="emitClick(p)"
|
|
248
|
+
(keydown.space)="emitClick(p); $event.preventDefault()" />
|
|
249
|
+
@if (showValueLabels()) {
|
|
250
|
+
<svg:text
|
|
251
|
+
class="chart-line-value pointer-events-none fill-muted-foreground text-2xs"
|
|
252
|
+
[attr.x]="labelX(p)"
|
|
253
|
+
[attr.y]="labelY(p)"
|
|
254
|
+
[attr.text-anchor]="labelAnchor()"
|
|
255
|
+
dominant-baseline="middle">
|
|
256
|
+
{{ formatValueLabel(p) }}
|
|
257
|
+
</svg:text>
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
</svg:g>
|
|
263
|
+
<ng-content select="svg\\:g[ChartAxisX]" />
|
|
264
|
+
<ng-content select="svg\\:g[ChartAxisY]" />
|
|
265
|
+
<ng-content select="svg\\:g[ChartCrosshair]" />
|
|
266
|
+
<ng-content select="svg:g[ChartBrush]" />
|
|
267
|
+
</svg:g>
|
|
268
|
+
</svg:svg>
|
|
269
|
+
<ng-content select="ChartTooltip" />
|
|
270
|
+
<ng-content select="ChartLegend" />
|
|
271
|
+
<ng-content select="ChartZoomControls" />
|
|
272
|
+
`,
|
|
273
|
+
}]
|
|
274
|
+
}], ctorParameters: () => [], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }], xKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "xKey", required: true }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], styles: [{ type: i0.Input, args: [{ isSignal: true, alias: "styles", required: false }] }], curve: [{ type: i0.Input, args: [{ isSignal: true, alias: "curve", required: false }] }], margin: [{ type: i0.Input, args: [{ isSignal: true, alias: "margin", required: false }] }], strokeWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "strokeWidth", required: false }] }], showDots: [{ type: i0.Input, args: [{ isSignal: true, alias: "showDots", required: false }] }], dotRadius: [{ type: i0.Input, args: [{ isSignal: true, alias: "dotRadius", required: false }] }], dotColorKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "dotColorKey", required: false }] }], dotStrokeColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "dotStrokeColor", required: false }] }], dotStrokeWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "dotStrokeWidth", required: false }] }], showValueLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "showValueLabels", required: false }] }], valueLabelFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueLabelFormat", required: false }] }], pointClick: [{ type: i0.Output, args: ["pointClick"] }] } });
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Generated bundle index. Do not edit.
|
|
278
|
+
*/
|
|
279
|
+
|
|
280
|
+
export { LineChart };
|
|
281
|
+
//# sourceMappingURL=ojiepermana-angular-chart-line.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ojiepermana-angular-chart-line.mjs","sources":["../../../library/chart/line/line-chart.ts","../../../library/chart/line/ojiepermana-angular-chart-line.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, effect, inject, input, output } from '@angular/core';\nimport { ChartContext } from '@ojiepermana/angular-chart/core';\nimport {\n CartesianContext,\n type ChartDatum,\n type ChartMargin,\n type ChartOrientation,\n type ChartStyleVariant,\n} from '@ojiepermana/angular-chart/core';\nimport { CategoricalViewportContext } from '@ojiepermana/angular-chart/core';\nimport { computeLineLayout, type LineCurve, type LinePoint, type LineSeriesPath } from '@ojiepermana/angular-chart/core';\nimport { provideCartesianFromLineLayout } from '@ojiepermana/angular-chart/core';\nimport { ChartPointerTracker } from '@ojiepermana/angular-chart/primitives';\nimport { elementClientCenter } from '@ojiepermana/angular-chart/core';\nimport { sliceByIndexRange } from '@ojiepermana/angular-chart/core';\n\nconst DEFAULT_MARGIN: ChartMargin = { top: 8, right: 8, bottom: 24, left: 40 };\nconst defaultLineValueFormatter = (value: number): string => `${value}`;\n\n/** Emitted when a data point is activated (click or keyboard). */\nexport interface LinePointClickEvent {\n readonly seriesKey: string;\n readonly datumIndex: number;\n readonly category: string;\n readonly value: number;\n readonly datum: ChartDatum;\n}\n\n@Component({\n selector: 'ChartLine',\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [CartesianContext, CategoricalViewportContext],\n imports: [ChartPointerTracker],\n host: { class: 'relative block h-full w-full', '[attr.data-style]': 'styles()' },\n template: `\n <svg:svg\n ChartPointerTracker\n class=\"block h-full w-full overflow-visible\"\n [attr.viewBox]=\"viewBox()\"\n preserveAspectRatio=\"none\"\n role=\"img\"\n [attr.aria-label]=\"ariaSummary()\">\n <svg:g [attr.transform]=\"innerTransform()\">\n <ng-content select=\"svg\\\\:g[ChartGrid]\" />\n <svg:g class=\"chart-lines\">\n @for (s of series(); track s.seriesKey) {\n <svg:path\n class=\"chart-line\"\n fill=\"none\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n [attr.stroke]=\"s.color\"\n [attr.stroke-width]=\"strokeWidth()\"\n [attr.d]=\"s.linePath\" />\n @if (showDots()) {\n @for (p of s.points; track p.datumIndex) {\n <svg:circle\n class=\"chart-dot cursor-pointer outline-none\"\n [attr.cx]=\"p.x\"\n [attr.cy]=\"p.y\"\n [attr.r]=\"dotRadius()\"\n [attr.fill]=\"dotFill(p, s.color)\"\n [attr.stroke]=\"dotStrokeColor()\"\n [attr.stroke-width]=\"dotStrokeWidth() || null\"\n [attr.aria-label]=\"pointAriaLabel(p)\"\n tabindex=\"0\"\n (focus)=\"setActivePoint($event, p)\"\n (blur)=\"clearActivePoint()\"\n (click)=\"emitClick(p)\"\n (keydown.enter)=\"emitClick(p)\"\n (keydown.space)=\"emitClick(p); $event.preventDefault()\" />\n @if (showValueLabels()) {\n <svg:text\n class=\"chart-line-value pointer-events-none fill-muted-foreground text-2xs\"\n [attr.x]=\"labelX(p)\"\n [attr.y]=\"labelY(p)\"\n [attr.text-anchor]=\"labelAnchor()\"\n dominant-baseline=\"middle\">\n {{ formatValueLabel(p) }}\n </svg:text>\n }\n }\n }\n }\n </svg:g>\n <ng-content select=\"svg\\\\:g[ChartAxisX]\" />\n <ng-content select=\"svg\\\\:g[ChartAxisY]\" />\n <ng-content select=\"svg\\\\:g[ChartCrosshair]\" />\n <ng-content select=\"svg:g[ChartBrush]\" />\n </svg:g>\n </svg:svg>\n <ng-content select=\"ChartTooltip\" />\n <ng-content select=\"ChartLegend\" />\n <ng-content select=\"ChartZoomControls\" />\n `,\n})\nexport class LineChart {\n private readonly root = inject(ChartContext);\n private readonly cart = inject(CartesianContext);\n private readonly viewport = inject(CategoricalViewportContext);\n\n readonly data = input.required<readonly ChartDatum[]>();\n readonly xKey = input.required<string>();\n readonly orientation = input<ChartOrientation>('vertical');\n readonly styles = input<ChartStyleVariant>('base');\n readonly curve = input<LineCurve>('monotone');\n readonly margin = input<ChartMargin>(DEFAULT_MARGIN);\n readonly strokeWidth = input<number>(2);\n readonly showDots = input<boolean>(true);\n readonly dotRadius = input<number>(3);\n readonly dotColorKey = input<string | undefined>(undefined);\n readonly dotStrokeColor = input<string | undefined>(undefined);\n readonly dotStrokeWidth = input<number>(0);\n readonly showValueLabels = input<boolean>(false);\n readonly valueLabelFormat = input<(value: number) => string>(defaultLineValueFormatter);\n\n readonly pointClick = output<LinePointClickEvent>();\n\n protected readonly innerWidth = computed(() =>\n Math.max(0, this.root.dimensions().width - this.margin().left - this.margin().right),\n );\n protected readonly innerHeight = computed(() =>\n Math.max(0, this.root.dimensions().height - this.margin().top - this.margin().bottom),\n );\n\n protected readonly visibleStartIndex = computed(() => this.viewport.zoomRange()?.startIndex ?? 0);\n protected readonly visibleData = computed(() => sliceByIndexRange(this.data(), this.viewport.zoomRange()));\n\n protected readonly layout = computed(() =>\n computeLineLayout({\n data: this.visibleData(),\n xKey: this.xKey(),\n seriesKeys: this.root.visibleSeriesKeys(),\n orientation: this.orientation(),\n innerWidth: this.innerWidth(),\n innerHeight: this.innerHeight(),\n curve: this.curve(),\n }),\n );\n\n protected readonly series = computed<readonly LineSeriesPath[]>(() => this.layout().series);\n\n protected readonly viewBox = computed(() => {\n const { width, height } = this.root.dimensions();\n return `0 0 ${Math.max(0, width)} ${Math.max(0, height)}`;\n });\n\n protected readonly innerTransform = computed(() => `translate(${this.margin().left},${this.margin().top})`);\n\n protected readonly ariaSummary = computed(() => {\n const keys = this.root.visibleSeriesKeys();\n return `Line chart, ${this.visibleData().length} points, ${keys.length} series: ${keys.join(', ')}.`;\n });\n\n constructor() {\n effect(() => {\n const layout = this.layout();\n this.viewport.dataCount.set(this.data().length);\n provideCartesianFromLineLayout(this.cart, layout, this.orientation(), this.innerWidth(), this.innerHeight());\n this.cart.margin.set(this.margin());\n });\n }\n\n protected emitClick(p: LinePoint): void {\n const datumIndex = this.visibleStartIndex() + p.datumIndex;\n this.pointClick.emit({\n seriesKey: p.seriesKey,\n datumIndex,\n category: p.category,\n value: p.value,\n datum: this.data()[datumIndex],\n });\n }\n\n protected setActivePoint(event: FocusEvent, p: LinePoint): void {\n const center = elementClientCenter(event.currentTarget);\n const datumIndex = this.visibleStartIndex() + p.datumIndex;\n this.root.activePoint.set({\n index: p.datumIndex,\n datumIndex,\n seriesKey: p.seriesKey,\n clientX: center?.clientX,\n clientY: center?.clientY,\n });\n }\n\n protected clearActivePoint(): void {\n this.root.activePoint.set(null);\n }\n\n protected dotFill(point: LinePoint, fallbackColor: string): string {\n const colorKey = this.dotColorKey();\n if (!colorKey) {\n return fallbackColor;\n }\n\n const datum = this.visibleData()[point.datumIndex];\n const raw = datum?.[colorKey];\n if (typeof raw !== 'string' || raw.length === 0) {\n return fallbackColor;\n }\n\n if (\n raw.startsWith('var(') ||\n raw.startsWith('#') ||\n raw.startsWith('rgb') ||\n raw.startsWith('hsl') ||\n raw.includes('(')\n ) {\n return raw;\n }\n\n return `var(--color-${raw.replace(/[^a-zA-Z0-9_-]/g, '_')})`;\n }\n\n protected formatValueLabel(point: LinePoint): string {\n return this.valueLabelFormat()(point.value);\n }\n\n protected labelX(point: LinePoint): number {\n return this.orientation() === 'vertical' ? point.x : point.x + this.dotRadius() + 6;\n }\n\n protected labelY(point: LinePoint): number {\n return this.orientation() === 'vertical' ? point.y - this.dotRadius() - 8 : point.y;\n }\n\n protected labelAnchor(): 'middle' | 'start' {\n return this.orientation() === 'vertical' ? 'middle' : 'start';\n }\n\n protected pointAriaLabel(p: LinePoint): string {\n const label = this.root.config()[p.seriesKey]?.label ?? p.seriesKey;\n return `${label} at ${p.category}: ${p.value}`;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|