@oicl/openbridge-webcomponents 2.0.0-next.101 → 2.0.0-next.103
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/bundle/openbridge-webcomponents.bundle.js +580 -143
- package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
- package/custom-elements.json +629 -407
- package/dist/bars-graphs/donut-chart/donut-chart.d.ts +18 -16
- package/dist/bars-graphs/donut-chart/donut-chart.d.ts.map +1 -1
- package/dist/bars-graphs/donut-chart/donut-chart.js.map +1 -1
- package/dist/bars-graphs/pie-chart/pie-chart.d.ts +14 -12
- package/dist/bars-graphs/pie-chart/pie-chart.d.ts.map +1 -1
- package/dist/bars-graphs/pie-chart/pie-chart.js.map +1 -1
- package/dist/bars-graphs/polar-chart/polar-chart.d.ts +19 -16
- package/dist/bars-graphs/polar-chart/polar-chart.d.ts.map +1 -1
- package/dist/bars-graphs/polar-chart/polar-chart.js.map +1 -1
- package/dist/bars-graphs/radial-bar-chart/radial-bar-chart.d.ts +8 -8
- package/dist/bars-graphs/radial-bar-chart/radial-bar-chart.d.ts.map +1 -1
- package/dist/bars-graphs/radial-bar-chart/radial-bar-chart.js.map +1 -1
- package/dist/building-blocks/chart-line/chart-line-base.d.ts +8 -25
- package/dist/building-blocks/chart-line/chart-line-base.d.ts.map +1 -1
- package/dist/building-blocks/chart-line/chart-line-base.js.map +1 -1
- package/dist/building-blocks/instrument-radial/instrument-radial.d.ts +22 -2
- package/dist/building-blocks/instrument-radial/instrument-radial.d.ts.map +1 -1
- package/dist/building-blocks/instrument-radial/instrument-radial.js +61 -37
- package/dist/building-blocks/instrument-radial/instrument-radial.js.map +1 -1
- package/dist/integration-systems/integration-bar/integration-bar.d.ts +20 -24
- package/dist/integration-systems/integration-bar/integration-bar.d.ts.map +1 -1
- package/dist/integration-systems/integration-bar/integration-bar.js.map +1 -1
- package/dist/integration-systems/integration-button/integration-button.d.ts +15 -13
- package/dist/integration-systems/integration-button/integration-button.d.ts.map +1 -1
- package/dist/integration-systems/integration-button/integration-button.js.map +1 -1
- package/dist/navigation-instruments/azimuth-thruster/azimuth-thruster.d.ts +14 -0
- package/dist/navigation-instruments/azimuth-thruster/azimuth-thruster.d.ts.map +1 -1
- package/dist/navigation-instruments/azimuth-thruster/azimuth-thruster.js +30 -11
- package/dist/navigation-instruments/azimuth-thruster/azimuth-thruster.js.map +1 -1
- package/dist/navigation-instruments/compass/compass.d.ts +68 -31
- package/dist/navigation-instruments/compass/compass.d.ts.map +1 -1
- package/dist/navigation-instruments/compass/compass.js +36 -16
- package/dist/navigation-instruments/compass/compass.js.map +1 -1
- package/dist/navigation-instruments/compass-flat/compass-flat.d.ts +8 -9
- package/dist/navigation-instruments/compass-flat/compass-flat.d.ts.map +1 -1
- package/dist/navigation-instruments/compass-flat/compass-flat.js.map +1 -1
- package/dist/navigation-instruments/compass-sector/compass-sector.d.ts.map +1 -1
- package/dist/navigation-instruments/compass-sector/compass-sector.js.map +1 -1
- package/dist/navigation-instruments/gauge-radial/gauge-radial.css.js +34 -2
- package/dist/navigation-instruments/gauge-radial/gauge-radial.css.js.map +1 -1
- package/dist/navigation-instruments/gauge-radial/gauge-radial.d.ts +15 -0
- package/dist/navigation-instruments/gauge-radial/gauge-radial.d.ts.map +1 -1
- package/dist/navigation-instruments/gauge-radial/gauge-radial.js +35 -1
- package/dist/navigation-instruments/gauge-radial/gauge-radial.js.map +1 -1
- package/dist/navigation-instruments/gauge-trend/gauge-trend.d.ts +0 -5
- package/dist/navigation-instruments/gauge-trend/gauge-trend.d.ts.map +1 -1
- package/dist/navigation-instruments/gauge-trend/gauge-trend.js.map +1 -1
- package/dist/navigation-instruments/graph-mini/graph-mini.d.ts +1 -1
- package/dist/navigation-instruments/graph-mini/graph-mini.d.ts.map +1 -1
- package/dist/navigation-instruments/graph-mini/graph-mini.js.map +1 -1
- package/dist/navigation-instruments/heading/heading.d.ts +19 -1
- package/dist/navigation-instruments/heading/heading.d.ts.map +1 -1
- package/dist/navigation-instruments/heading/heading.js +34 -16
- package/dist/navigation-instruments/heading/heading.js.map +1 -1
- package/dist/navigation-instruments/indicator-graph/indicator-graph.d.ts +1 -1
- package/dist/navigation-instruments/indicator-graph/indicator-graph.d.ts.map +1 -1
- package/dist/navigation-instruments/indicator-graph/indicator-graph.js.map +1 -1
- package/dist/navigation-instruments/rudder/rudder.d.ts +15 -2
- package/dist/navigation-instruments/rudder/rudder.d.ts.map +1 -1
- package/dist/navigation-instruments/rudder/rudder.js +36 -26
- package/dist/navigation-instruments/rudder/rudder.js.map +1 -1
- package/dist/navigation-instruments/speed-gauge/speed-gauge.d.ts +15 -1
- package/dist/navigation-instruments/speed-gauge/speed-gauge.d.ts.map +1 -1
- package/dist/navigation-instruments/speed-gauge/speed-gauge.js +31 -3
- package/dist/navigation-instruments/speed-gauge/speed-gauge.js.map +1 -1
- package/dist/navigation-instruments/watch/watch.d.ts +45 -17
- package/dist/navigation-instruments/watch/watch.d.ts.map +1 -1
- package/dist/navigation-instruments/watch/watch.js +53 -38
- package/dist/navigation-instruments/watch/watch.js.map +1 -1
- package/dist/svghelpers/radial-frame.d.ts +122 -0
- package/dist/svghelpers/radial-frame.d.ts.map +1 -0
- package/dist/svghelpers/radial-frame.js +259 -0
- package/dist/svghelpers/radial-frame.js.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"polar-chart.d.ts","sourceRoot":"","sources":["../../../src/bars-graphs/polar-chart/polar-chart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,cAAc,EAAkB,MAAM,KAAK,CAAC;AAOhE,OAAO,EAAC,QAAQ,EAAC,MAAM,uCAAuC,CAAC;AAsE/D,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"polar-chart.d.ts","sourceRoot":"","sources":["../../../src/bars-graphs/polar-chart/polar-chart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,cAAc,EAAkB,MAAM,KAAK,CAAC;AAOhE,OAAO,EAAC,QAAQ,EAAC,MAAM,uCAAuC,CAAC;AAsE/D,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+EG;AACH,qBACa,aAAc,SAAQ,UAAU;IAC3C,+CAA+C;IAE/C,IAAI,EAAE,kBAAkB,EAAE,CAAM;IAEhC,gFAAgF;IACrC,MAAM,EAAE,MAAM,EAAE,CAAM;IAEjE,gBAAgB;IAChB,OAAO,CAAC,iBAAiB,CAAS;IAGlC,QAAQ,EAAE,QAAQ,CAAoB;IAEtC;;;OAGG;IACwB,UAAU,UAAS;IAC9C,wHAAwH;IAExH,kBAAkB,UAAS;IAC3B,qIAAqI;IAErI,gBAAgB,UAAS;IACzB,oEAAoE;IAEpE,QAAQ,UAAS;IACjB,wCAAwC;IAExC,eAAe,UAAS;IACxB,0DAA0D;IAE1D,cAAc,SAAO;IACrB;;;OAGG;IAEH,mBAAmB,SAAK;IACxB,qDAAqD;IAErD,uBAAuB,SAAK;IAE5B,4LAA4L;IAE5L,WAAW,SAAO;IAElB,oEAAoE;IAEpE,MAAM,UAAS;IAEf,yDAAyD;IAEzD,gBAAgB,UAAS;IAEzB,iEAAiE;IAEjE,OAAO,CAAC,eAAe,CAAgB;IAEvC,+DAA+D;IAC/D,OAAO,CAAC,uBAAuB,CAAwC;IAEvE,gBAAgB;IACC,OAAO,CAAC,QAAQ,CAAqB;IAEtD,gBAAgB;IACE,OAAO,CAAC,SAAS,CAAC,CAAiB;IAErD,gBAAgB;IAChB,OAAO,CAAC,KAAK,CAAC,CAAQ;IAEtB,gBAAgB;IAChB,OAAO,CAAC,aAAa,CAAC,CAAmB;IAEzC,yEAAyE;IACzE,OAAO,CAAC,cAAc,CAAC,CAAiB;IAExC,oEAAoE;IACpE,OAAO,CAAC,iBAAiB,CAAS;IAElC,OAAO,CAAC,aAAa;IAQZ,OAAO,CAAC,OAAO,EAAE,cAAc;IAoB/B,YAAY;IAMZ,oBAAoB;IAO7B;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IA0B3B,OAAO,CAAC,gBAAgB;IAuCxB,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,eAAe;IAkHvB,OAAO,CAAC,yBAAyB;IAoGjC,OAAO,CAAC,WAAW;IA2DnB,OAAO,CAAC,WAAW;IAuBnB;;OAEG;IACH,OAAO,CAAC,YAAY;IAoEX,MAAM;IASf,OAAgB,MAAM,4BAKpB;CACH;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,iBAAiB,EAAE,aAAa,CAAC;KAClC;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"polar-chart.js","sources":["../../../src/bars-graphs/polar-chart/polar-chart.ts"],"sourcesContent":["import {LitElement, PropertyValues, html, unsafeCSS} from 'lit';\nimport {property, query, state} from 'lit/decorators.js';\nimport componentStyle from './polar-chart.css?inline';\nimport chartCommonStyle from '../../charthelpers/chart-common.css?inline';\nimport chartDebugStyle from '../../charthelpers/chart-debug.css?inline';\nimport chartLegendStyle from '../../charthelpers/chart-legend.css?inline';\nimport {customElement} from '../../decorator.js';\nimport {Priority} from '../../navigation-instruments/types.js';\nimport {\n Chart,\n PolarAreaController,\n RadialLinearScale,\n ArcElement,\n Tooltip,\n} from 'chart.js';\nimport type {Plugin, ChartOptions, Chart as ChartInstance} from 'chart.js';\nimport type {RadialLinearScale as RadialLinearScaleType} from 'chart.js';\nimport {\n CHART_SECTOR_DEFAULT_COLORS,\n CHART_SECTOR_ENHANCED_COLORS,\n CHART_DIMENSIONS,\n getCssVariableValue,\n getChartColorsOrDefault,\n observeThemeChanges,\n createArcOuterLabelPlugin,\n calculateFixedHeightChartLayout,\n getChartTooltipOptions,\n formatNumericValue,\n generateLegendHTML,\n} from '../../charthelpers/index.js';\n\ntype PolarScale = RadialLinearScaleType & {\n xCenter: number;\n yCenter: number;\n drawingArea: number;\n};\n\n// Register Chart.js components\nChart.register(PolarAreaController, RadialLinearScale, ArcElement, Tooltip);\n\n// Polar-specific dimension constants\nconst POLAR_BAR_DIMENSIONS = {\n ...CHART_DIMENSIONS,\n GAP_AND_BORDER_COLOR: '--instrument-frame-tertiary-color',\n} as const;\n\n// Properties that require chart recreation (destroy and create)\nconst POLAR_RECREATE_PROP_NAMES = [\n 'showOuterLabels',\n 'outerLabelUnit',\n 'outerLabelMaxLength',\n 'outerLabelDecimalPlaces',\n 'showSectorLabels',\n 'discreteColorStops',\n 'showDebugOverlay',\n 'fixedHeight',\n 'showUnit',\n] as const;\n\n// All properties that trigger chart updates\nconst POLAR_WATCHED_PROP_NAMES = [\n 'legend',\n 'data',\n 'colors',\n 'priority',\n 'monochrome',\n 'discreteColorStops',\n 'showSectorLabels',\n 'showOuterLabels',\n 'outerLabelUnit',\n 'outerLabelMaxLength',\n 'outerLabelDecimalPlaces',\n 'showDebugOverlay',\n 'fixedHeight',\n 'showUnit',\n] as const;\n\nexport type PolarChartDataItem = {\n label: string;\n value: number;\n};\n\n/**\n * `<obc-polar-chart>` – A customizable polar area chart component for visualizing proportional data as sectors, with optional outer labels, angle display, and discrete color bands.\n *\n * This component renders an interactive polar area chart powered by Chart.js, displaying data segments as radial sectors with optional outer labels, angle display, and discrete color bands. It supports customizable colors, monochrome mode, and adapts its layout based on available space. Labels are hidden when the chart is too small (< 192px height), ensuring clarity at all sizes.\n *\n * ## Features\n * - **Fixed Height ⇒ Fixed Circumference:** The chart's circumference is determined by the `fixedHeight` property (default: 320px). This ensures the chart's circumference remains consistent and matches other radial instruments, regardless of the available browser or container width. The chart does not scale to fill the width; instead, it always uses the specified fixed height to define its size and circumference.\n * - **Layout:**\n * - Full 360° polar area chart layout.\n * - **Outer Labels:**\n * - Optional labels positioned outside the chart showing sector names or angles.\n * - Supports percentage or custom units (e.g., \"kW\", \"kg\", \"MB\").\n * - Configurable decimal places and maximum label length (with trimming).\n * - Option to display angles (0°, 30°, etc.) instead of sector names.\n * - **Discrete Color Bands:**\n * - Draw sectors as radial color bands from center outward using the colors array as threshold steps.\n * - Option to trim sectors to the nearest color band boundary or show exact values with partial band fills.\n * - **Customization:**\n * - Custom segment colors (with automatic fallback to theme palette).\n * - Monochrome mode for single-color charts.\n * - Adjustable outer label formatting and units.\n * - **Color Priority:** Set `priority` to `Priority.enhanced` to use the blue/enhanced\n * color palette instead of the default gray/regular palette (default: `Priority.regular`).\n * - **Responsive Behavior:**\n * - Automatically hides labels when height < 192px.\n * - Maintains aspect ratio and adjusts padding for optimal label positioning.\n * - **Theme Integration:**\n * - Colors update automatically when the `data-obc-theme` attribute changes on the `<html>` element.\n * - Example:\n * ```html\n * <html lang=\"en\" data-obc-theme=\"day\"></html>\n * ```\n *\n * ## Example\n *\n * **Basic Usage**\n * ```html\n * <obc-polar-chart></obc-polar-chart>\n * <script>\n * document.querySelector('obc-polar-chart').data = [\n * {label: 'Sector A', value: 33},\n * {label: 'Sector B', value: 22},\n * {label: 'Sector C', value: 45}\n * ];\n * </script>\n * ```\n *\n * **With Discrete Color Bands**\n * ```html\n * <obc-polar-chart></obc-polar-chart>\n * <script>\n * const chart = document.querySelector('obc-polar-chart');\n * chart.discreteColorStops = true;\n * chart.data = [\n * {label: 'A', value: 50},\n * {label: 'B', value: 30},\n * {label: 'C', value: 20}\n * ];\n * </script>\n * ```\n *\n * **Custom Colors and Angle Labels**\n * ```html\n * <obc-polar-chart></obc-polar-chart>\n * <script>\n * const chart = document.querySelector('obc-polar-chart');\n * chart.showSectorLabels = true;\n * chart.outerLabelUnit = '°';\n * chart.outerLabelDecimalPlaces = 0;\n * chart.data = [\n * {label: 'A', value: 20},\n * {label: 'B', value: 35},\n * {label: 'C', value: 45}\n * ];\n * chart.colors = ['#e74c3c', '#f39c12', '#2ecc71'];\n * </script>\n * ```\n *\n * @property {Array<{label: string, value: number}>} data - Chart data segments (set via JavaScript)\n * @property {string[]} colors - Custom segment colors (set via JavaScript) with fallback to theme palette\n * @property {boolean} monochrome - Use single color for all sectors (uses first color from array, default: false)\n * @property {boolean} discreteColorStops - Draw sectors as radial color bands from center outward using the colors array as threshold steps (default: false)\n * @property {boolean} trimToDiscreteStops - When true, visually trim sectors to the nearest discrete color band boundary. When false, show exact values with partial band fills (default: true)\n * @property {boolean} showSectorLabels - When true, display sector labels from data (e.g. \"Sector A\"). When false, display angle values (0°, 30°, etc.). Default: false\n * @property {boolean} showUnit - Whether to show unit in angle or outer labels, default: false\n * @property {boolean} showOuterLabels - Show outer labels, default: false\n * @property {string} outerLabelUnit - Unit string to append to outer labels, default: \"\"\n * @property {number} outerLabelMaxLength - Maximum character length for labels before trim (0 = no limit), default: 0\n * @property {number} outerLabelDecimalPlaces - Number of decimal places in labels, default: 0\n * @property {boolean} showDebugOverlay - Show debug overlay for development, default: false\n * @property {number} fixedHeight - Fixed height of the chart in pixels (mandatory, determines chart circumference), default: 320. The chart's circumference is always based on this fixed height to match other radial instruments.\n * @property {boolean} legend - Whether to display the legend below the chart, default: false\n * @beta\n */\n@customElement('obc-polar-chart')\nexport class ObcPolarChart extends LitElement {\n @property({type: Array, attribute: false})\n data: PolarChartDataItem[] = [];\n\n @property({type: Array, attribute: false}) colors: string[] = [];\n\n /** @internal */\n private centerFirstSector = false; // When false, first sector is centered at 12 o'clock position\n\n @property({type: String})\n priority: Priority = Priority.regular;\n\n /** @availableWhen discreteColorStops==false */\n @property({type: Boolean}) monochrome = false;\n @property({type: Boolean})\n discreteColorStops = false;\n @property({type: Boolean})\n showSectorLabels = false; // Default: false (angles shown by default)\n @property({type: Boolean})\n showUnit = false;\n @property({type: Boolean})\n showOuterLabels = false;\n @property({type: String})\n outerLabelUnit = '°';\n /** @availableWhen showOuterLabels==true */\n @property({type: Number})\n outerLabelMaxLength = 0;\n @property({type: Number})\n outerLabelDecimalPlaces = 0;\n\n @property({type: Number, reflect: true})\n fixedHeight = 320;\n\n @property({type: Boolean, reflect: true})\n legend = false;\n\n @property({type: Boolean, reflect: true})\n showDebugOverlay = false;\n\n /** @internal - Pre-formatted labels for outer label rendering */\n @state()\n private formattedLabels: string[] = [];\n\n /** @internal - Calculated chart diameter from layout helper */\n private calculatedChartDiameter: number = CHART_DIMENSIONS.CHART_WIDTH;\n\n /** @internal */\n @query('canvas') private canvasEl!: HTMLCanvasElement;\n\n /** @internal */\n @query('.legend') private legendDiv?: HTMLDivElement;\n\n /** @internal */\n private chart?: Chart;\n\n /** @internal */\n private themeObserver?: MutationObserver;\n\n /** @internal - ResizeObserver for tracking height threshold crossings */\n private resizeObserver?: ResizeObserver;\n\n /** @internal - Track previous state to detect threshold crossing */\n private wasAboveThreshold = false;\n\n private hasAnyChanged(\n changed: PropertyValues,\n props: readonly (keyof ObcPolarChart)[]\n ): boolean {\n return props.some((prop) => changed.has(prop));\n }\n\n // Update external library AFTER render\n override updated(changed: PropertyValues) {\n super.updated(changed);\n\n if (this.hasAnyChanged(changed, POLAR_WATCHED_PROP_NAMES)) {\n // Recreate chart when major layout properties change or when plugin configuration changes\n // These properties affect aspect ratio calculation, plugin registration, or outer label rendering\n const needsRecreation = this.hasAnyChanged(\n changed,\n POLAR_RECREATE_PROP_NAMES\n );\n\n if (needsRecreation) {\n this.chart?.destroy();\n this.createChart();\n } else {\n this.updateChart();\n }\n }\n }\n\n override firstUpdated() {\n this.createChart();\n this.themeObserver = observeThemeChanges(() => this.updateChart());\n this.setupResizeObserver();\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n this.chart?.destroy();\n this.themeObserver?.disconnect();\n this.resizeObserver?.disconnect();\n }\n\n /**\n * Setup resize observer to detect height threshold crossings\n * Recreates chart when crossing MIN_HEIGHT_WITH_LABELS (192px) to show/hide labels\n */\n private setupResizeObserver() {\n if (!this.canvasEl) return;\n\n this.resizeObserver = new ResizeObserver(() => {\n const height = this.canvasEl?.clientHeight ?? 0;\n const isAboveThreshold =\n height >= CHART_DIMENSIONS.MIN_HEIGHT_WITH_LABELS;\n\n // Only recreate chart if we crossed the threshold (need to add/remove plugins)\n if (isAboveThreshold !== this.wasAboveThreshold) {\n this.wasAboveThreshold = isAboveThreshold;\n this.chart?.destroy();\n this.createChart();\n } else {\n // Height changed but didn't cross threshold - just update\n this.updateChart();\n }\n });\n\n this.resizeObserver.observe(this.canvasEl);\n\n // Initialize threshold state\n const height = this.canvasEl.clientHeight;\n this.wasAboveThreshold = height >= CHART_DIMENSIONS.MIN_HEIGHT_WITH_LABELS;\n }\n\n private prepareChartData() {\n const values = this.data.map((d) => d.value);\n const labels = this.data.map((d) => d.label);\n const chartColors = getChartColorsOrDefault(\n this,\n this.colors,\n this.priority === Priority.enhanced\n ? CHART_SECTOR_ENHANCED_COLORS\n : CHART_SECTOR_DEFAULT_COLORS\n );\n\n // When using discrete color stops, sectors will be drawn by the plugin\n // so we can use transparent colors for the main dataset\n const segmentColors = this.discreteColorStops\n ? values.map(() => 'transparent')\n : values.map((_, index) =>\n this.monochrome\n ? chartColors[0]\n : chartColors[index % chartColors.length]\n );\n\n // Generate labels based on showSectorLabels property\n const numSectors = this.data.length;\n const displayLabels = this.showSectorLabels\n ? labels\n : Array.from({length: numSectors}, (_, i) => {\n const angle = (i * 360) / numSectors;\n return `${angle}`;\n });\n\n return {\n values,\n labels,\n colors: segmentColors,\n chartColors, // Pass resolved colors for use in plugin\n displayLabels,\n };\n }\n\n private getLayoutConfig() {\n // For polar, use actual data labels and values when showSectorLabels is true, otherwise use angle values\n return {\n unit: this.outerLabelUnit,\n showUnit: this.showUnit,\n outerLabelMaxLength: this.outerLabelMaxLength,\n decimalPlaces: this.outerLabelDecimalPlaces,\n data: this.showSectorLabels\n ? this.data\n : Array.from({length: this.data.length}, (_, i) => ({\n label: '',\n value: (i * 360) / this.data.length,\n })),\n denominator: this.showSectorLabels ? 1 : 360,\n };\n }\n\n private getChartOptions(): ChartOptions<'polarArea'> {\n // Use centralized layout calculation helper for all dimensions and label measurement\n const dimensions = calculateFixedHeightChartLayout({\n fixedHeight: this.fixedHeight,\n isHalfMode: false,\n showOuterLabels: this.showOuterLabels,\n canvasEl: this.canvasEl,\n layoutConfig: this.getLayoutConfig(),\n host: this,\n });\n\n // Store chart diameter for plugin use\n this.calculatedChartDiameter = dimensions.chartDiameter;\n this.formattedLabels = dimensions.formattedLabels;\n\n // Set CSS variables for chart dimensions\n this.style.setProperty('--chart-width', `${dimensions.calculatedWidth}px`);\n this.style.setProperty('--chart-height', `${dimensions.actualHeight}px`);\n\n // Calculate dynamic padding for Chart.js layout\n const dynamicPadding = dimensions.isTooSmall\n ? {top: 0, right: 0, bottom: 0, left: 0}\n : {\n top: dimensions.topPadding,\n right: dimensions.rightPadding,\n bottom: dimensions.bottomPadding,\n left: dimensions.leftPadding,\n };\n\n // Set number of ticks to match color bands when discrete stops enabled\n const chartColors = getChartColorsOrDefault(\n this,\n this.colors,\n CHART_SECTOR_DEFAULT_COLORS\n );\n const numTicks = this.discreteColorStops ? chartColors.length + 1 : 6;\n\n // Find max value for scaling\n const maxValue = Math.max(...this.data.map((d) => d.value), 100);\n\n // Calculate rotation to center first label at 12 o'clock if enabled\n const numSectors = this.data.length;\n const anglePerSector = 360 / numSectors;\n const startAngle = this.centerFirstSector ? 0 : -anglePerSector / 2;\n\n return {\n responsive: true,\n maintainAspectRatio: true,\n aspectRatio: dimensions.aspectRatio,\n layout: {\n padding: dynamicPadding ?? POLAR_BAR_DIMENSIONS.CANVAS_PADDING,\n },\n scales: {\n r: {\n startAngle: startAngle,\n angleLines: {\n display: true,\n color: getCssVariableValue(\n this,\n POLAR_BAR_DIMENSIONS.GAP_AND_BORDER_COLOR\n ),\n lineWidth: 1,\n },\n grid: {\n display: true,\n color: getCssVariableValue(\n this,\n POLAR_BAR_DIMENSIONS.GAP_AND_BORDER_COLOR\n ),\n lineWidth: 1,\n },\n pointLabels: {\n // Always disable Chart.js built-in labels - we use our own outer label plugin\n display: false,\n },\n ticks: {\n display: false,\n stepSize: maxValue / (numTicks - 1),\n count: numTicks,\n },\n max: maxValue,\n },\n },\n plugins: {\n legend: {\n display: false,\n labels: {\n generateLabels: () => [], // Prevent Chart.js from generating labels internally\n },\n onClick: () => {}, // Disable legend click handler\n },\n tooltip: {\n ...getChartTooltipOptions(this),\n enabled: !dimensions.isTooSmall,\n callbacks: {\n title: () => '', // No title line\n label: (context) => {\n // Always show the data label and value, no unit\n const dataIndex = context.dataIndex;\n const data = this.data?.[dataIndex];\n const label = data?.label ?? '';\n const value =\n typeof data?.value === 'number'\n ? data.value\n : Number(data?.value);\n return `${label} ${value}`;\n },\n },\n },\n },\n animation: false,\n };\n }\n\n private createDiscreteColorPlugin(): Plugin<'polarArea'> {\n return {\n id: 'discreteColors',\n beforeDatasetsDraw: (chart: ChartInstance<'polarArea'>) => {\n if (!this.discreteColorStops) return;\n\n const {ctx, scales} = chart;\n const scale = scales.r as PolarScale | undefined;\n if (!scale) return;\n\n const centerX = scale.xCenter;\n const centerY = scale.yCenter;\n // Use calculated chart diameter to ensure consistency with layout\n const maxRadius = this.calculatedChartDiameter / 2;\n const numSectors = this.data.length;\n const anglePerSector = (Math.PI * 2) / numSectors;\n const rotationOffset = this.centerFirstSector ? 0 : -anglePerSector / 2;\n\n // Get resolved colors for creating discrete bands\n const chartColors = getChartColorsOrDefault(\n this,\n this.colors,\n this.priority === Priority.enhanced\n ? CHART_SECTOR_ENHANCED_COLORS\n : CHART_SECTOR_DEFAULT_COLORS\n );\n const numBands = chartColors.length;\n\n // Find max value for scaling\n const maxValue = Math.max(...this.data.map((d) => d.value), 100);\n\n // Generate threshold stops from the colors array (reversed)\n // Divide maxValue into equal bands based on number of colors\n const colorStops = chartColors.reverse().map((color, index) => ({\n threshold: ((index + 1) / numBands) * maxValue,\n color,\n }));\n\n ctx.save();\n\n // Draw each sector with discrete color bands\n this.data.forEach((dataPoint, sectorIndex) => {\n const sectorValue = dataPoint.value;\n const startAngle =\n sectorIndex * anglePerSector + rotationOffset - Math.PI / 2;\n const endAngle = startAngle + anglePerSector;\n\n // Draw color bands from center outward\n let previousRadius = 0;\n\n colorStops.forEach((stop) => {\n // Calculate radius for this threshold\n const thresholdRadius = (stop.threshold / maxValue) * maxRadius;\n const sectorRadiusLimit = (sectorValue / maxValue) * maxRadius;\n\n // Determine the outer radius for this band\n let drawRadius;\n if (sectorRadiusLimit <= thresholdRadius) {\n // Sector value is within or below this band - draw up to sector value\n drawRadius = sectorRadiusLimit;\n } else {\n // Sector value exceeds this band - fill band completely to threshold\n drawRadius = thresholdRadius;\n }\n\n // Draw the arc segment for this color band\n if (drawRadius > previousRadius) {\n ctx.fillStyle = stop.color;\n ctx.beginPath();\n ctx.arc(centerX, centerY, drawRadius, startAngle, endAngle);\n if (previousRadius > 0) {\n ctx.arc(\n centerX,\n centerY,\n previousRadius,\n endAngle,\n startAngle,\n true\n );\n } else {\n ctx.lineTo(centerX, centerY);\n }\n ctx.closePath();\n ctx.fill();\n }\n\n previousRadius = drawRadius;\n\n // Stop if we've reached the sector's value limit\n if (sectorRadiusLimit <= thresholdRadius) {\n return;\n }\n });\n });\n\n ctx.restore();\n },\n };\n }\n\n private createChart() {\n // Guard: Verify canvas exists and is connected to DOM\n if (!this.canvasEl || !this.canvasEl.isConnected) return;\n\n const ctx = this.canvasEl.getContext('2d');\n if (!ctx) return;\n\n const {values, colors, displayLabels} = this.prepareChartData();\n\n const plugins: Plugin<'polarArea'>[] = [];\n\n // Add discrete color plugin if enabled\n if (this.discreteColorStops) {\n plugins.push(this.createDiscreteColorPlugin());\n }\n\n // Get chart options (this will populate formattedLabels and check dimensions)\n const chartOptions = this.getChartOptions();\n\n // Only add outer labels plugin if enabled AND canvas is large enough\n // formattedLabels will be empty if too small or outer labels disabled\n if (this.showOuterLabels && this.formattedLabels.length > 0) {\n const numSectors = values.length;\n const anglePerSector = (Math.PI * 2) / (numSectors || 1);\n const rotationOffset = this.centerFirstSector ? 0 : -anglePerSector / 2;\n plugins.push(\n createArcOuterLabelPlugin(this, {\n formattedLabels: this.formattedLabels.slice(0, numSectors),\n rotationOffset,\n chartDiameter: this.calculatedChartDiameter,\n type: 'polar',\n })\n );\n }\n\n this.chart = new Chart(ctx, {\n type: 'polarArea',\n data: {\n labels: displayLabels, // Use angle labels or sector labels based on showSectorLabels\n datasets: [\n {\n data: values,\n backgroundColor: colors,\n borderWidth: 1,\n borderColor: getCssVariableValue(\n this,\n POLAR_BAR_DIMENSIONS.GAP_AND_BORDER_COLOR\n ),\n },\n ],\n },\n options: chartOptions,\n plugins,\n });\n\n // Defer legend update to next tick to ensure Chart.js metadata is initialized\n requestAnimationFrame(() => this.updateLegend());\n }\n\n private updateChart() {\n // Guard: Verify chart and canvas still exist and are connected\n if (!this.chart || !this.canvasEl || !this.canvasEl.isConnected) return;\n\n const {values, colors, displayLabels} = this.prepareChartData();\n\n this.chart.data.labels = displayLabels;\n if (this.chart.data.datasets[0]) {\n this.chart.data.datasets[0].data = values;\n this.chart.data.datasets[0].backgroundColor = colors;\n }\n\n const latestOptions = this.getChartOptions();\n if (this.chart.options) {\n Object.assign(this.chart.options, latestOptions);\n }\n\n this.chart.update();\n\n // Update legend after chart update completes to ensure metadata is ready\n requestAnimationFrame(() => this.updateLegend());\n }\n\n /**\n * Update the legend HTML content\n */\n private updateLegend() {\n // Guard: Check if legend should be shown and chart is ready\n if (!this.legend || !this.legendDiv || !this.chart) return;\n\n // Guard: Check if chart metadata is available\n const meta = this.chart.getDatasetMeta(0);\n if (!meta || !meta.controller) {\n // console.debug('[obc-polar-chart] updateLegend: skipped - chart metadata not yet initialized');\n return;\n }\n\n // Guard: Check if dataset has data\n if (!this.data || this.data.length === 0) {\n // console.debug('[obc-polar-chart] updateLegend: skipped - no data available');\n this.legendDiv.innerHTML = '';\n return;\n }\n\n // Denominator: use max if set, otherwise total, with minimum of 1\n const denominator = this.showSectorLabels ? 1 : 360;\n const isPercentage = this.outerLabelUnit === '%';\n\n try {\n const legendItems = this.data.map((item, i) => {\n const style = meta.controller.getStyle(i, false);\n\n let label: string;\n let valueToFormat: number;\n\n if (this.showSectorLabels) {\n label = item.label;\n valueToFormat = item.value;\n } else {\n const angle = (i * 360) / this.data.length;\n label = `${angle}${this.outerLabelUnit}`;\n valueToFormat = item.value;\n }\n\n const numericValue = formatNumericValue(\n valueToFormat,\n denominator,\n isPercentage,\n this.outerLabelDecimalPlaces\n );\n const showUnit = this.showUnit && this.outerLabelUnit;\n const value = `${numericValue}`;\n const unit =\n showUnit && this.showSectorLabels ? `${this.outerLabelUnit}` : '';\n\n return {\n fillStyle: style.backgroundColor as string,\n label,\n value,\n unit,\n };\n });\n\n const legendHTML = generateLegendHTML(legendItems);\n this.legendDiv.innerHTML = legendHTML;\n } catch (error) {\n console.debug(\n '[obc-polar-chart] updateLegend: error generating legend HTML',\n error\n );\n // Silent failure - don't throw, just skip legend update this time\n }\n }\n\n override render() {\n return html`\n <div class=\"wrapper\">\n <canvas></canvas>\n ${this.legend ? html`<div class=\"legend\"></div>` : ''}\n </div>\n `;\n }\n\n static override styles = [\n unsafeCSS(componentStyle),\n unsafeCSS(chartCommonStyle),\n unsafeCSS(chartLegendStyle),\n unsafeCSS(chartDebugStyle),\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-polar-chart': ObcPolarChart;\n }\n}\n"],"names":["height"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"polar-chart.js","sources":["../../../src/bars-graphs/polar-chart/polar-chart.ts"],"sourcesContent":["import {LitElement, PropertyValues, html, unsafeCSS} from 'lit';\nimport {property, query, state} from 'lit/decorators.js';\nimport componentStyle from './polar-chart.css?inline';\nimport chartCommonStyle from '../../charthelpers/chart-common.css?inline';\nimport chartDebugStyle from '../../charthelpers/chart-debug.css?inline';\nimport chartLegendStyle from '../../charthelpers/chart-legend.css?inline';\nimport {customElement} from '../../decorator.js';\nimport {Priority} from '../../navigation-instruments/types.js';\nimport {\n Chart,\n PolarAreaController,\n RadialLinearScale,\n ArcElement,\n Tooltip,\n} from 'chart.js';\nimport type {Plugin, ChartOptions, Chart as ChartInstance} from 'chart.js';\nimport type {RadialLinearScale as RadialLinearScaleType} from 'chart.js';\nimport {\n CHART_SECTOR_DEFAULT_COLORS,\n CHART_SECTOR_ENHANCED_COLORS,\n CHART_DIMENSIONS,\n getCssVariableValue,\n getChartColorsOrDefault,\n observeThemeChanges,\n createArcOuterLabelPlugin,\n calculateFixedHeightChartLayout,\n getChartTooltipOptions,\n formatNumericValue,\n generateLegendHTML,\n} from '../../charthelpers/index.js';\n\ntype PolarScale = RadialLinearScaleType & {\n xCenter: number;\n yCenter: number;\n drawingArea: number;\n};\n\n// Register Chart.js components\nChart.register(PolarAreaController, RadialLinearScale, ArcElement, Tooltip);\n\n// Polar-specific dimension constants\nconst POLAR_BAR_DIMENSIONS = {\n ...CHART_DIMENSIONS,\n GAP_AND_BORDER_COLOR: '--instrument-frame-tertiary-color',\n} as const;\n\n// Properties that require chart recreation (destroy and create)\nconst POLAR_RECREATE_PROP_NAMES = [\n 'showOuterLabels',\n 'outerLabelUnit',\n 'outerLabelMaxLength',\n 'outerLabelDecimalPlaces',\n 'showSectorLabels',\n 'discreteColorStops',\n 'showDebugOverlay',\n 'fixedHeight',\n 'showUnit',\n] as const;\n\n// All properties that trigger chart updates\nconst POLAR_WATCHED_PROP_NAMES = [\n 'legend',\n 'data',\n 'colors',\n 'priority',\n 'monochrome',\n 'discreteColorStops',\n 'showSectorLabels',\n 'showOuterLabels',\n 'outerLabelUnit',\n 'outerLabelMaxLength',\n 'outerLabelDecimalPlaces',\n 'showDebugOverlay',\n 'fixedHeight',\n 'showUnit',\n] as const;\n\nexport type PolarChartDataItem = {\n label: string;\n value: number;\n};\n\n/**\n * `<obc-polar-chart>` – A customizable polar area chart component for visualizing proportional data as sectors, with optional outer labels, angle display, and discrete color bands.\n *\n * This component renders an interactive polar area chart powered by Chart.js, displaying data segments as radial sectors with optional outer labels, angle display, and discrete color bands. It supports customizable colors, monochrome mode, and adapts its layout based on available space. Labels are hidden when the chart is too small (< 192px height), ensuring clarity at all sizes.\n *\n * ## Features\n * - **Fixed Height ⇒ Fixed Circumference:** The chart's circumference is determined by the `fixedHeight` property (default: 320px). This ensures the chart's circumference remains consistent and matches other radial instruments, regardless of the available browser or container width. The chart does not scale to fill the width; instead, it always uses the specified fixed height to define its size and circumference.\n * - **Layout:**\n * - Full 360° polar area chart layout.\n * - **Outer Labels:**\n * - Optional labels positioned outside the chart showing sector names or angles.\n * - Supports percentage or custom units (e.g., \"kW\", \"kg\", \"MB\").\n * - Configurable decimal places and maximum label length (with trimming).\n * - Option to display angles (0°, 30°, etc.) instead of sector names.\n * - **Discrete Color Bands:**\n * - Draw sectors as radial color bands from center outward using the colors array as threshold steps.\n * - Option to trim sectors to the nearest color band boundary or show exact values with partial band fills.\n * - **Customization:**\n * - Custom segment colors (with automatic fallback to theme palette).\n * - Monochrome mode for single-color charts.\n * - Adjustable outer label formatting and units.\n * - **Color Priority:** Set `priority` to `Priority.enhanced` to use the blue/enhanced\n * color palette instead of the default gray/regular palette (default: `Priority.regular`).\n * - **Responsive Behavior:**\n * - Automatically hides labels when height < 192px.\n * - Maintains aspect ratio and adjusts padding for optimal label positioning.\n * - **Theme Integration:**\n * - Colors update automatically when the `data-obc-theme` attribute changes on the `<html>` element.\n * - Example:\n * ```html\n * <html lang=\"en\" data-obc-theme=\"day\"></html>\n * ```\n *\n * ## Example\n *\n * **Basic Usage**\n * ```html\n * <obc-polar-chart></obc-polar-chart>\n * <script>\n * document.querySelector('obc-polar-chart').data = [\n * {label: 'Sector A', value: 33},\n * {label: 'Sector B', value: 22},\n * {label: 'Sector C', value: 45}\n * ];\n * </script>\n * ```\n *\n * **With Discrete Color Bands**\n * ```html\n * <obc-polar-chart></obc-polar-chart>\n * <script>\n * const chart = document.querySelector('obc-polar-chart');\n * chart.discreteColorStops = true;\n * chart.data = [\n * {label: 'A', value: 50},\n * {label: 'B', value: 30},\n * {label: 'C', value: 20}\n * ];\n * </script>\n * ```\n *\n * **Custom Colors and Angle Labels**\n * ```html\n * <obc-polar-chart></obc-polar-chart>\n * <script>\n * const chart = document.querySelector('obc-polar-chart');\n * chart.showSectorLabels = true;\n * chart.outerLabelUnit = '°';\n * chart.outerLabelDecimalPlaces = 0;\n * chart.data = [\n * {label: 'A', value: 20},\n * {label: 'B', value: 35},\n * {label: 'C', value: 45}\n * ];\n * chart.colors = ['#e74c3c', '#f39c12', '#2ecc71'];\n * </script>\n * ```\n *\n * @beta\n */\n@customElement('obc-polar-chart')\nexport class ObcPolarChart extends LitElement {\n /** Chart data segments (set via JavaScript) */\n @property({type: Array, attribute: false})\n data: PolarChartDataItem[] = [];\n\n /** Custom segment colors (set via JavaScript) with fallback to theme palette */\n @property({type: Array, attribute: false}) colors: string[] = [];\n\n /** @internal */\n private centerFirstSector = false; // When false, first sector is centered at 12 o'clock position\n\n @property({type: String})\n priority: Priority = Priority.regular;\n\n /**\n * Use single color for all sectors (uses first color from array, default: false)\n * @availableWhen discreteColorStops==false\n */\n @property({type: Boolean}) monochrome = false;\n /** Draw sectors as radial color bands from center outward using the colors array as threshold steps (default: false) */\n @property({type: Boolean})\n discreteColorStops = false;\n /** When true, display sector labels from data (e.g. \"Sector A\"). When false, display angle values (0°, 30°, etc.). Default: false */\n @property({type: Boolean})\n showSectorLabels = false; // Default: false (angles shown by default)\n /** Whether to show unit in angle or outer labels, default: false */\n @property({type: Boolean})\n showUnit = false;\n /** Show outer labels, default: false */\n @property({type: Boolean})\n showOuterLabels = false;\n /** Unit string to append to outer labels, default: \"°\" */\n @property({type: String})\n outerLabelUnit = '°';\n /**\n * Maximum character length for labels before trim (0 = no limit), default: 0\n * @availableWhen showOuterLabels==true\n */\n @property({type: Number})\n outerLabelMaxLength = 0;\n /** Number of decimal places in labels, default: 0 */\n @property({type: Number})\n outerLabelDecimalPlaces = 0;\n\n /** Fixed height of the chart in pixels (determines chart circumference), default: 320. The chart's circumference is always based on this fixed height to match other radial instruments. */\n @property({type: Number, reflect: true})\n fixedHeight = 320;\n\n /** Whether to display the legend below the chart, default: false */\n @property({type: Boolean, reflect: true})\n legend = false;\n\n /** Show debug overlay for development, default: false */\n @property({type: Boolean, reflect: true})\n showDebugOverlay = false;\n\n /** @internal - Pre-formatted labels for outer label rendering */\n @state()\n private formattedLabels: string[] = [];\n\n /** @internal - Calculated chart diameter from layout helper */\n private calculatedChartDiameter: number = CHART_DIMENSIONS.CHART_WIDTH;\n\n /** @internal */\n @query('canvas') private canvasEl!: HTMLCanvasElement;\n\n /** @internal */\n @query('.legend') private legendDiv?: HTMLDivElement;\n\n /** @internal */\n private chart?: Chart;\n\n /** @internal */\n private themeObserver?: MutationObserver;\n\n /** @internal - ResizeObserver for tracking height threshold crossings */\n private resizeObserver?: ResizeObserver;\n\n /** @internal - Track previous state to detect threshold crossing */\n private wasAboveThreshold = false;\n\n private hasAnyChanged(\n changed: PropertyValues,\n props: readonly (keyof ObcPolarChart)[]\n ): boolean {\n return props.some((prop) => changed.has(prop));\n }\n\n // Update external library AFTER render\n override updated(changed: PropertyValues) {\n super.updated(changed);\n\n if (this.hasAnyChanged(changed, POLAR_WATCHED_PROP_NAMES)) {\n // Recreate chart when major layout properties change or when plugin configuration changes\n // These properties affect aspect ratio calculation, plugin registration, or outer label rendering\n const needsRecreation = this.hasAnyChanged(\n changed,\n POLAR_RECREATE_PROP_NAMES\n );\n\n if (needsRecreation) {\n this.chart?.destroy();\n this.createChart();\n } else {\n this.updateChart();\n }\n }\n }\n\n override firstUpdated() {\n this.createChart();\n this.themeObserver = observeThemeChanges(() => this.updateChart());\n this.setupResizeObserver();\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n this.chart?.destroy();\n this.themeObserver?.disconnect();\n this.resizeObserver?.disconnect();\n }\n\n /**\n * Setup resize observer to detect height threshold crossings\n * Recreates chart when crossing MIN_HEIGHT_WITH_LABELS (192px) to show/hide labels\n */\n private setupResizeObserver() {\n if (!this.canvasEl) return;\n\n this.resizeObserver = new ResizeObserver(() => {\n const height = this.canvasEl?.clientHeight ?? 0;\n const isAboveThreshold =\n height >= CHART_DIMENSIONS.MIN_HEIGHT_WITH_LABELS;\n\n // Only recreate chart if we crossed the threshold (need to add/remove plugins)\n if (isAboveThreshold !== this.wasAboveThreshold) {\n this.wasAboveThreshold = isAboveThreshold;\n this.chart?.destroy();\n this.createChart();\n } else {\n // Height changed but didn't cross threshold - just update\n this.updateChart();\n }\n });\n\n this.resizeObserver.observe(this.canvasEl);\n\n // Initialize threshold state\n const height = this.canvasEl.clientHeight;\n this.wasAboveThreshold = height >= CHART_DIMENSIONS.MIN_HEIGHT_WITH_LABELS;\n }\n\n private prepareChartData() {\n const values = this.data.map((d) => d.value);\n const labels = this.data.map((d) => d.label);\n const chartColors = getChartColorsOrDefault(\n this,\n this.colors,\n this.priority === Priority.enhanced\n ? CHART_SECTOR_ENHANCED_COLORS\n : CHART_SECTOR_DEFAULT_COLORS\n );\n\n // When using discrete color stops, sectors will be drawn by the plugin\n // so we can use transparent colors for the main dataset\n const segmentColors = this.discreteColorStops\n ? values.map(() => 'transparent')\n : values.map((_, index) =>\n this.monochrome\n ? chartColors[0]\n : chartColors[index % chartColors.length]\n );\n\n // Generate labels based on showSectorLabels property\n const numSectors = this.data.length;\n const displayLabels = this.showSectorLabels\n ? labels\n : Array.from({length: numSectors}, (_, i) => {\n const angle = (i * 360) / numSectors;\n return `${angle}`;\n });\n\n return {\n values,\n labels,\n colors: segmentColors,\n chartColors, // Pass resolved colors for use in plugin\n displayLabels,\n };\n }\n\n private getLayoutConfig() {\n // For polar, use actual data labels and values when showSectorLabels is true, otherwise use angle values\n return {\n unit: this.outerLabelUnit,\n showUnit: this.showUnit,\n outerLabelMaxLength: this.outerLabelMaxLength,\n decimalPlaces: this.outerLabelDecimalPlaces,\n data: this.showSectorLabels\n ? this.data\n : Array.from({length: this.data.length}, (_, i) => ({\n label: '',\n value: (i * 360) / this.data.length,\n })),\n denominator: this.showSectorLabels ? 1 : 360,\n };\n }\n\n private getChartOptions(): ChartOptions<'polarArea'> {\n // Use centralized layout calculation helper for all dimensions and label measurement\n const dimensions = calculateFixedHeightChartLayout({\n fixedHeight: this.fixedHeight,\n isHalfMode: false,\n showOuterLabels: this.showOuterLabels,\n canvasEl: this.canvasEl,\n layoutConfig: this.getLayoutConfig(),\n host: this,\n });\n\n // Store chart diameter for plugin use\n this.calculatedChartDiameter = dimensions.chartDiameter;\n this.formattedLabels = dimensions.formattedLabels;\n\n // Set CSS variables for chart dimensions\n this.style.setProperty('--chart-width', `${dimensions.calculatedWidth}px`);\n this.style.setProperty('--chart-height', `${dimensions.actualHeight}px`);\n\n // Calculate dynamic padding for Chart.js layout\n const dynamicPadding = dimensions.isTooSmall\n ? {top: 0, right: 0, bottom: 0, left: 0}\n : {\n top: dimensions.topPadding,\n right: dimensions.rightPadding,\n bottom: dimensions.bottomPadding,\n left: dimensions.leftPadding,\n };\n\n // Set number of ticks to match color bands when discrete stops enabled\n const chartColors = getChartColorsOrDefault(\n this,\n this.colors,\n CHART_SECTOR_DEFAULT_COLORS\n );\n const numTicks = this.discreteColorStops ? chartColors.length + 1 : 6;\n\n // Find max value for scaling\n const maxValue = Math.max(...this.data.map((d) => d.value), 100);\n\n // Calculate rotation to center first label at 12 o'clock if enabled\n const numSectors = this.data.length;\n const anglePerSector = 360 / numSectors;\n const startAngle = this.centerFirstSector ? 0 : -anglePerSector / 2;\n\n return {\n responsive: true,\n maintainAspectRatio: true,\n aspectRatio: dimensions.aspectRatio,\n layout: {\n padding: dynamicPadding ?? POLAR_BAR_DIMENSIONS.CANVAS_PADDING,\n },\n scales: {\n r: {\n startAngle: startAngle,\n angleLines: {\n display: true,\n color: getCssVariableValue(\n this,\n POLAR_BAR_DIMENSIONS.GAP_AND_BORDER_COLOR\n ),\n lineWidth: 1,\n },\n grid: {\n display: true,\n color: getCssVariableValue(\n this,\n POLAR_BAR_DIMENSIONS.GAP_AND_BORDER_COLOR\n ),\n lineWidth: 1,\n },\n pointLabels: {\n // Always disable Chart.js built-in labels - we use our own outer label plugin\n display: false,\n },\n ticks: {\n display: false,\n stepSize: maxValue / (numTicks - 1),\n count: numTicks,\n },\n max: maxValue,\n },\n },\n plugins: {\n legend: {\n display: false,\n labels: {\n generateLabels: () => [], // Prevent Chart.js from generating labels internally\n },\n onClick: () => {}, // Disable legend click handler\n },\n tooltip: {\n ...getChartTooltipOptions(this),\n enabled: !dimensions.isTooSmall,\n callbacks: {\n title: () => '', // No title line\n label: (context) => {\n // Always show the data label and value, no unit\n const dataIndex = context.dataIndex;\n const data = this.data?.[dataIndex];\n const label = data?.label ?? '';\n const value =\n typeof data?.value === 'number'\n ? data.value\n : Number(data?.value);\n return `${label} ${value}`;\n },\n },\n },\n },\n animation: false,\n };\n }\n\n private createDiscreteColorPlugin(): Plugin<'polarArea'> {\n return {\n id: 'discreteColors',\n beforeDatasetsDraw: (chart: ChartInstance<'polarArea'>) => {\n if (!this.discreteColorStops) return;\n\n const {ctx, scales} = chart;\n const scale = scales.r as PolarScale | undefined;\n if (!scale) return;\n\n const centerX = scale.xCenter;\n const centerY = scale.yCenter;\n // Use calculated chart diameter to ensure consistency with layout\n const maxRadius = this.calculatedChartDiameter / 2;\n const numSectors = this.data.length;\n const anglePerSector = (Math.PI * 2) / numSectors;\n const rotationOffset = this.centerFirstSector ? 0 : -anglePerSector / 2;\n\n // Get resolved colors for creating discrete bands\n const chartColors = getChartColorsOrDefault(\n this,\n this.colors,\n this.priority === Priority.enhanced\n ? CHART_SECTOR_ENHANCED_COLORS\n : CHART_SECTOR_DEFAULT_COLORS\n );\n const numBands = chartColors.length;\n\n // Find max value for scaling\n const maxValue = Math.max(...this.data.map((d) => d.value), 100);\n\n // Generate threshold stops from the colors array (reversed)\n // Divide maxValue into equal bands based on number of colors\n const colorStops = chartColors.reverse().map((color, index) => ({\n threshold: ((index + 1) / numBands) * maxValue,\n color,\n }));\n\n ctx.save();\n\n // Draw each sector with discrete color bands\n this.data.forEach((dataPoint, sectorIndex) => {\n const sectorValue = dataPoint.value;\n const startAngle =\n sectorIndex * anglePerSector + rotationOffset - Math.PI / 2;\n const endAngle = startAngle + anglePerSector;\n\n // Draw color bands from center outward\n let previousRadius = 0;\n\n colorStops.forEach((stop) => {\n // Calculate radius for this threshold\n const thresholdRadius = (stop.threshold / maxValue) * maxRadius;\n const sectorRadiusLimit = (sectorValue / maxValue) * maxRadius;\n\n // Determine the outer radius for this band\n let drawRadius;\n if (sectorRadiusLimit <= thresholdRadius) {\n // Sector value is within or below this band - draw up to sector value\n drawRadius = sectorRadiusLimit;\n } else {\n // Sector value exceeds this band - fill band completely to threshold\n drawRadius = thresholdRadius;\n }\n\n // Draw the arc segment for this color band\n if (drawRadius > previousRadius) {\n ctx.fillStyle = stop.color;\n ctx.beginPath();\n ctx.arc(centerX, centerY, drawRadius, startAngle, endAngle);\n if (previousRadius > 0) {\n ctx.arc(\n centerX,\n centerY,\n previousRadius,\n endAngle,\n startAngle,\n true\n );\n } else {\n ctx.lineTo(centerX, centerY);\n }\n ctx.closePath();\n ctx.fill();\n }\n\n previousRadius = drawRadius;\n\n // Stop if we've reached the sector's value limit\n if (sectorRadiusLimit <= thresholdRadius) {\n return;\n }\n });\n });\n\n ctx.restore();\n },\n };\n }\n\n private createChart() {\n // Guard: Verify canvas exists and is connected to DOM\n if (!this.canvasEl || !this.canvasEl.isConnected) return;\n\n const ctx = this.canvasEl.getContext('2d');\n if (!ctx) return;\n\n const {values, colors, displayLabels} = this.prepareChartData();\n\n const plugins: Plugin<'polarArea'>[] = [];\n\n // Add discrete color plugin if enabled\n if (this.discreteColorStops) {\n plugins.push(this.createDiscreteColorPlugin());\n }\n\n // Get chart options (this will populate formattedLabels and check dimensions)\n const chartOptions = this.getChartOptions();\n\n // Only add outer labels plugin if enabled AND canvas is large enough\n // formattedLabels will be empty if too small or outer labels disabled\n if (this.showOuterLabels && this.formattedLabels.length > 0) {\n const numSectors = values.length;\n const anglePerSector = (Math.PI * 2) / (numSectors || 1);\n const rotationOffset = this.centerFirstSector ? 0 : -anglePerSector / 2;\n plugins.push(\n createArcOuterLabelPlugin(this, {\n formattedLabels: this.formattedLabels.slice(0, numSectors),\n rotationOffset,\n chartDiameter: this.calculatedChartDiameter,\n type: 'polar',\n })\n );\n }\n\n this.chart = new Chart(ctx, {\n type: 'polarArea',\n data: {\n labels: displayLabels, // Use angle labels or sector labels based on showSectorLabels\n datasets: [\n {\n data: values,\n backgroundColor: colors,\n borderWidth: 1,\n borderColor: getCssVariableValue(\n this,\n POLAR_BAR_DIMENSIONS.GAP_AND_BORDER_COLOR\n ),\n },\n ],\n },\n options: chartOptions,\n plugins,\n });\n\n // Defer legend update to next tick to ensure Chart.js metadata is initialized\n requestAnimationFrame(() => this.updateLegend());\n }\n\n private updateChart() {\n // Guard: Verify chart and canvas still exist and are connected\n if (!this.chart || !this.canvasEl || !this.canvasEl.isConnected) return;\n\n const {values, colors, displayLabels} = this.prepareChartData();\n\n this.chart.data.labels = displayLabels;\n if (this.chart.data.datasets[0]) {\n this.chart.data.datasets[0].data = values;\n this.chart.data.datasets[0].backgroundColor = colors;\n }\n\n const latestOptions = this.getChartOptions();\n if (this.chart.options) {\n Object.assign(this.chart.options, latestOptions);\n }\n\n this.chart.update();\n\n // Update legend after chart update completes to ensure metadata is ready\n requestAnimationFrame(() => this.updateLegend());\n }\n\n /**\n * Update the legend HTML content\n */\n private updateLegend() {\n // Guard: Check if legend should be shown and chart is ready\n if (!this.legend || !this.legendDiv || !this.chart) return;\n\n // Guard: Check if chart metadata is available\n const meta = this.chart.getDatasetMeta(0);\n if (!meta || !meta.controller) {\n // console.debug('[obc-polar-chart] updateLegend: skipped - chart metadata not yet initialized');\n return;\n }\n\n // Guard: Check if dataset has data\n if (!this.data || this.data.length === 0) {\n // console.debug('[obc-polar-chart] updateLegend: skipped - no data available');\n this.legendDiv.innerHTML = '';\n return;\n }\n\n // Denominator: use max if set, otherwise total, with minimum of 1\n const denominator = this.showSectorLabels ? 1 : 360;\n const isPercentage = this.outerLabelUnit === '%';\n\n try {\n const legendItems = this.data.map((item, i) => {\n const style = meta.controller.getStyle(i, false);\n\n let label: string;\n let valueToFormat: number;\n\n if (this.showSectorLabels) {\n label = item.label;\n valueToFormat = item.value;\n } else {\n const angle = (i * 360) / this.data.length;\n label = `${angle}${this.outerLabelUnit}`;\n valueToFormat = item.value;\n }\n\n const numericValue = formatNumericValue(\n valueToFormat,\n denominator,\n isPercentage,\n this.outerLabelDecimalPlaces\n );\n const showUnit = this.showUnit && this.outerLabelUnit;\n const value = `${numericValue}`;\n const unit =\n showUnit && this.showSectorLabels ? `${this.outerLabelUnit}` : '';\n\n return {\n fillStyle: style.backgroundColor as string,\n label,\n value,\n unit,\n };\n });\n\n const legendHTML = generateLegendHTML(legendItems);\n this.legendDiv.innerHTML = legendHTML;\n } catch (error) {\n console.debug(\n '[obc-polar-chart] updateLegend: error generating legend HTML',\n error\n );\n // Silent failure - don't throw, just skip legend update this time\n }\n }\n\n override render() {\n return html`\n <div class=\"wrapper\">\n <canvas></canvas>\n ${this.legend ? html`<div class=\"legend\"></div>` : ''}\n </div>\n `;\n }\n\n static override styles = [\n unsafeCSS(componentStyle),\n unsafeCSS(chartCommonStyle),\n unsafeCSS(chartLegendStyle),\n unsafeCSS(chartDebugStyle),\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-polar-chart': ObcPolarChart;\n }\n}\n"],"names":["height"],"mappings":"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"}
|
|
@@ -66,25 +66,25 @@ import { Priority } from '../../navigation-instruments/types.js';
|
|
|
66
66
|
* </script>
|
|
67
67
|
* ```
|
|
68
68
|
*
|
|
69
|
-
* @property {number[]} data - Array of values for each ring (set via JavaScript)
|
|
70
|
-
* @property {string[]} colors - Custom ring colors (set via JavaScript) with fallback to theme palette
|
|
71
|
-
* @property {number} max - Maximum value for calculating remaining empty area, default: 100
|
|
72
|
-
* @property {number} circumference - Arc span in degrees: 360 for full circle, 270 for 3/4 circle, default: 270
|
|
73
|
-
* @property {boolean} showDebugOverlay - Show debug overlay for development, default: false
|
|
74
|
-
* @property {number} fixedHeight - Fixed height of the chart in pixels (mandatory, determines chart circumference), default: 320. The chart's circumference is always based on this fixed height to match other radial instruments.
|
|
75
|
-
* @property {number} minRingThickness - Minimum thickness of each ring in pixels, excluding borders, default: 16
|
|
76
|
-
* @property {boolean} legend - Whether to display the legend below the chart, default: false
|
|
77
69
|
* @beta
|
|
78
70
|
*/
|
|
79
71
|
export declare class ObcRadialBarChart extends LitElement {
|
|
72
|
+
/** Array of values for each ring (set via JavaScript) */
|
|
80
73
|
data: number[];
|
|
74
|
+
/** Custom ring colors (set via JavaScript) with fallback to theme palette */
|
|
81
75
|
colors: string[];
|
|
82
76
|
priority: Priority;
|
|
77
|
+
/** Maximum value for calculating remaining empty area, default: 100 */
|
|
83
78
|
max: number;
|
|
79
|
+
/** Arc span in degrees: 360 for full circle, 270 for 3/4 circle, default: 270 */
|
|
84
80
|
circumference: number;
|
|
81
|
+
/** Whether to display the legend below the chart, default: false */
|
|
85
82
|
legend: boolean;
|
|
83
|
+
/** Show debug overlay for development, default: false */
|
|
86
84
|
showDebugOverlay: boolean;
|
|
85
|
+
/** Fixed height of the chart in pixels (determines chart circumference), default: 320. The chart's circumference is always based on this fixed height to match other radial instruments. */
|
|
87
86
|
fixedHeight: number;
|
|
87
|
+
/** Minimum thickness of each ring in pixels, excluding borders, default: 16 */
|
|
88
88
|
minRingThickness: number;
|
|
89
89
|
/** @internal */
|
|
90
90
|
private canvasEl?;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"radial-bar-chart.d.ts","sourceRoot":"","sources":["../../../src/bars-graphs/radial-bar-chart/radial-bar-chart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,cAAc,EAAkB,MAAM,KAAK,CAAC;AAQhE,OAAO,EAAC,QAAQ,EAAC,MAAM,uCAAuC,CAAC;AAqD/D
|
|
1
|
+
{"version":3,"file":"radial-bar-chart.d.ts","sourceRoot":"","sources":["../../../src/bars-graphs/radial-bar-chart/radial-bar-chart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,cAAc,EAAkB,MAAM,KAAK,CAAC;AAQhE,OAAO,EAAC,QAAQ,EAAC,MAAM,uCAAuC,CAAC;AAqD/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AACH,qBACa,iBAAkB,SAAQ,UAAU;IAC/C,yDAAyD;IACd,IAAI,EAAE,MAAM,EAAE,CAAM;IAC/D,6EAA6E;IAClC,MAAM,EAAE,MAAM,EAAE,CAAM;IAEjE,QAAQ,EAAE,QAAQ,CAAoB;IACtC,uEAAuE;IAEvE,GAAG,SAAO;IACV,iFAAiF;IAEjF,aAAa,SAAO;IACpB,oEAAoE;IAEpE,MAAM,UAAS;IACf,yDAAyD;IAEzD,gBAAgB,UAAS;IACzB,4LAA4L;IAE5L,WAAW,SAAO;IAClB,+EAA+E;IAI/E,gBAAgB,SAAM;IAEtB,gBAAgB;IACC,OAAO,CAAC,QAAQ,CAAC,CAAoB;IAEtD,gBAAgB;IACE,OAAO,CAAC,SAAS,CAAC,CAAiB;IAErD,gBAAgB;IAChB,OAAO,CAAC,KAAK,CAAC,CAAQ;IAEtB,gBAAgB;IAChB,OAAO,CAAC,aAAa,CAAC,CAAmB;IAEzC,yEAAyE;IACzE,OAAO,CAAC,cAAc,CAAC,CAAiB;IAExC,oEAAoE;IACpE,OAAO,CAAC,iBAAiB,CAAS;IAElC,OAAO,CAAC,aAAa;IAOrB;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,sBAAsB;IAoErB,OAAO,CAAC,OAAO,EAAE,cAAc;IAoB/B,YAAY;IAMZ,oBAAoB;IAO7B;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IA2B3B,OAAO,CAAC,gBAAgB;IA6CxB,OAAO,CAAC,eAAe;IA8FvB,OAAO,CAAC,WAAW;IAsBnB,OAAO,CAAC,WAAW;IAuBnB;;OAEG;IACH,OAAO,CAAC,YAAY;IA6CX,MAAM;IAcf,OAAgB,MAAM,4BAKpB;CACH;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,sBAAsB,EAAE,iBAAiB,CAAC;KAC3C;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"radial-bar-chart.js","sources":["../../../src/bars-graphs/radial-bar-chart/radial-bar-chart.ts"],"sourcesContent":["import {LitElement, PropertyValues, html, unsafeCSS} from 'lit';\nimport {property, query} from 'lit/decorators.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport componentStyle from './radial-bar-chart.css?inline';\nimport chartCommonStyle from '../../charthelpers/chart-common.css?inline';\nimport chartDebugStyle from '../../charthelpers/chart-debug.css?inline';\nimport chartLegendStyle from '../../charthelpers/chart-legend.css?inline';\nimport {customElement} from '../../decorator.js';\nimport {Priority} from '../../navigation-instruments/types.js';\nimport {Chart, DoughnutController, ArcElement, Tooltip} from 'chart.js';\nimport type {ChartOptions} from 'chart.js';\nimport {\n CHART_SECTOR_DEFAULT_COLORS,\n CHART_SECTOR_ENHANCED_COLORS,\n CHART_DIMENSIONS,\n getCssVariableValue,\n getChartColorsOrDefault,\n observeThemeChanges,\n calculateFixedHeightChartLayout,\n getChartTooltipOptions,\n generateLegendHTML,\n} from '../../charthelpers/index.js';\n\n// Register Chart.js components\nChart.register(DoughnutController, ArcElement, Tooltip);\n\n// Radial-bar-specific dimension constants\nconst RADIAL_BAR_DIMENSIONS = {\n ...CHART_DIMENSIONS,\n CHART_WIDTH: 258, // Override: 256 + 2px to compensate for outer border visual appearance\n CANVAS_PADDING: 30, // Recude by the above 2px to keep chart area consistent\n GAP_AND_BORDER_COLOR: '--container-background-color',\n REMAINING_COLOR: '--border-outline-color',\n BORDER_RADIUS: 4,\n SPACING: 4, // Gap between rings in pixels (2px border on each side)\n MIN_RING_THICKNESS: 16, // Minimum visible arc thickness in pixels (excluding borders)\n MIN_CUTOUT_PERCENT: 20, // Minimum cutout percentage to maintain empty center\n DEFAULT_MAX_CUTOUT_PERCENT: 60, // Default/maximum cutout percentage when space allows\n} as const;\n\n// Properties that require chart recreation (destroy and create)\nconst RADIAL_BAR_RECREATE_PROP_NAMES = [\n 'circumference',\n 'showDebugOverlay',\n 'fixedHeight',\n 'minRingThickness',\n] as const;\n\n// All properties that trigger chart updates\nconst RADIAL_BAR_WATCHED_PROP_NAMES = [\n 'legend',\n 'data',\n 'colors',\n 'priority',\n 'max',\n 'circumference',\n 'showDebugOverlay',\n 'fixedHeight',\n 'minRingThickness',\n] as const;\n\n/**\n * `<obc-radial-bar-chart>` – A customizable radial bar chart for visualizing multiple metrics as concentric rings, with dynamic ring thickness and cutout calculation.\n *\n * This component renders multiple data values as concentric arcs (rings), each representing a different metric. It supports full circle (360°) or three-quarter circle (270°) layouts, dynamic ring thickness, and automatic cutout calculation to ensure all rings fit within the available space. The chart adapts its layout based on the number of rings and available space, and hides labels when the chart is too small (< 192px height) for clarity.\n *\n * ## Features\n * - **Fixed Height ⇒ Fixed Circumference:** The chart's circumference is determined by the `fixedHeight` property (default: 320px). This ensures the chart's circumference remains consistent and matches other radial instruments, regardless of the available browser or container width. The chart does not scale to fill the width; instead, it always uses the specified fixed height to define its size and circumference.\n * - **Layout:**\n * - Full 360° or 270° (three-quarter) circle layout, controlled by the `circumference` property.\n * - Multiple concentric rings, each representing a data value.\n * - **Dynamic Ring Thickness:**\n * - All rings maintain equal thickness when possible.\n * - The `cutout` value serves as the maximum/preferred cutout percentage.\n * - When many rings are present, cutout is automatically reduced to fit rings at `minRingThickness`.\n * - Cutout will not go below 20% (minimum to maintain visible center).\n * - If rings still don't fit with 20% cutout, ring thickness is reduced proportionally.\n * - **Customization:**\n * - Custom ring colors (with automatic fallback to theme palette).\n * - Adjustable minimum ring thickness (`minRingThickness`).\n * - Adjustable arc span (`circumference`).\n * - **Color Priority:** Set `priority` to `Priority.enhanced` to use the blue/enhanced\n * color palette instead of the default gray/regular palette (default: `Priority.regular`).\n * - **Capacity Visualization:**\n * - Each ring shows a filled and remaining segment based on the `max` value.\n * - **Responsive Behavior:**\n * - Automatically hides labels and reduces spacing when height < 192px.\n * - Maintains aspect ratio and adjusts padding for optimal ring positioning.\n * - **Theme Integration:**\n * - Colors update automatically when the `data-obc-theme` attribute changes on the `<html>` element.\n * - Example:\n * ```html\n * <html lang=\"en\" data-obc-theme=\"day\"></html>\n * ```\n *\n * ## Example\n *\n * **Basic Usage**\n * ```html\n * <obc-radial-bar-chart></obc-radial-bar-chart>\n * <script>\n * document.querySelector('obc-radial-bar-chart').data = [70, 50, 30];\n * </script>\n * ```\n *\n * **Three-Quarter Circle with Custom Colors**\n * ```html\n * <obc-radial-bar-chart></obc-radial-bar-chart>\n * <script>\n * const chart = document.querySelector('obc-radial-bar-chart');\n * chart.circumference = 270;\n * chart.data = [80, 60, 40, 20];\n * chart.colors = ['#e74c3c', '#f39c12', '#2ecc71', '#3498db'];\n * </script>\n * ```\n *\n * **Custom Minimum Ring Thickness and Max Value**\n * ```html\n * <obc-radial-bar-chart></obc-radial-bar-chart>\n * <script>\n * const chart = document.querySelector('obc-radial-bar-chart');\n * chart.minRingThickness = 20;\n * chart.max = 200;\n * chart.data = [120, 80, 40];\n * </script>\n * ```\n *\n * @property {number[]} data - Array of values for each ring (set via JavaScript)\n * @property {string[]} colors - Custom ring colors (set via JavaScript) with fallback to theme palette\n * @property {number} max - Maximum value for calculating remaining empty area, default: 100\n * @property {number} circumference - Arc span in degrees: 360 for full circle, 270 for 3/4 circle, default: 270\n * @property {boolean} showDebugOverlay - Show debug overlay for development, default: false\n * @property {number} fixedHeight - Fixed height of the chart in pixels (mandatory, determines chart circumference), default: 320. The chart's circumference is always based on this fixed height to match other radial instruments.\n * @property {number} minRingThickness - Minimum thickness of each ring in pixels, excluding borders, default: 16\n * @property {boolean} legend - Whether to display the legend below the chart, default: false\n * @beta\n */\n@customElement('obc-radial-bar-chart')\nexport class ObcRadialBarChart extends LitElement {\n @property({type: Array, attribute: false}) data: number[] = [];\n @property({type: Array, attribute: false}) colors: string[] = [];\n @property({type: String})\n priority: Priority = Priority.regular;\n @property({type: Number})\n max = 100;\n @property({type: Number})\n circumference = 270;\n @property({type: Boolean, reflect: true})\n legend = false;\n @property({type: Boolean, reflect: true})\n showDebugOverlay = false;\n @property({type: Number, reflect: true})\n fixedHeight = 320;\n @property({\n type: Number,\n })\n minRingThickness = 16;\n\n /** @internal */\n @query('canvas') private canvasEl?: HTMLCanvasElement;\n\n /** @internal */\n @query('.legend') private legendDiv?: HTMLDivElement;\n\n /** @internal */\n private chart?: Chart;\n\n /** @internal */\n private themeObserver?: MutationObserver;\n\n /** @internal - ResizeObserver for tracking height threshold crossings */\n private resizeObserver?: ResizeObserver;\n\n /** @internal - Track previous state to detect threshold crossing */\n private wasAboveThreshold = false;\n\n private hasAnyChanged(\n changed: PropertyValues,\n props: readonly (keyof ObcRadialBarChart)[]\n ): boolean {\n return props.some((prop) => changed.has(prop));\n }\n\n /**\n * Calculate optimal cutout percentage and whether rings should use minimum thickness\n * based on available chart space and number of rings.\n *\n * Algorithm:\n * 1. Calculate total space needed for all rings at minRingThickness\n * 2. If enough space: use equal thickness and adjust cutout\n * 3. If not enough space with minCutout: reduce cutout to minimum\n * 4. If still not enough: rings must be thinner than minimum\n *\n * @param chartDiameter - Available chart diameter in pixels\n * @param isTooSmall - Whether chart is below MIN_HEIGHT_WITH_LABELS (affects border width)\n * @returns Object with calculated cutout percentage and flag for using minimum thickness\n */\n private calculateOptimalLayout(\n chartDiameter: number,\n isTooSmall: boolean\n ): {\n cutout: number;\n useMinThickness: boolean;\n } {\n const numRings = this.data.length;\n if (numRings === 0) {\n return {\n cutout: RADIAL_BAR_DIMENSIONS.DEFAULT_MAX_CUTOUT_PERCENT,\n useMinThickness: false,\n };\n }\n\n // Calculate total space per ring: minRingThickness + borders (spacing applied as borderWidth)\n // Border is applied on both sides, so total border = spacing (or spacing/2 for small charts)\n const effectiveSpacing = isTooSmall\n ? RADIAL_BAR_DIMENSIONS.SPACING / 2\n : RADIAL_BAR_DIMENSIONS.SPACING;\n const totalSpacePerRing = this.minRingThickness + effectiveSpacing;\n\n // Calculate radius (half of diameter)\n const radius = chartDiameter / 2;\n\n // Calculate total space needed for all rings\n const totalRingsSpace = numRings * totalSpacePerRing;\n\n // Calculate remaining space for cutout\n const remainingSpace = radius - totalRingsSpace;\n\n // Convert remaining space to cutout percentage\n const calculatedCutoutPercent = (remainingSpace / radius) * 100;\n\n // Check if we can fit all rings with minimum thickness\n if (calculatedCutoutPercent >= RADIAL_BAR_DIMENSIONS.MIN_CUTOUT_PERCENT) {\n // We have enough space - use minimum thickness and calculated cutout\n return {\n cutout: Math.min(\n calculatedCutoutPercent,\n RADIAL_BAR_DIMENSIONS.DEFAULT_MAX_CUTOUT_PERCENT\n ),\n useMinThickness: true,\n };\n } else {\n // Not enough space - try with minimum cutout\n const minCutoutSpace =\n (radius * RADIAL_BAR_DIMENSIONS.MIN_CUTOUT_PERCENT) / 100;\n const availableRingSpace = radius - minCutoutSpace;\n const spacePerRingWithMinCutout = availableRingSpace / numRings;\n\n if (spacePerRingWithMinCutout >= totalSpacePerRing) {\n // We can fit with minimum cutout\n return {\n cutout: RADIAL_BAR_DIMENSIONS.MIN_CUTOUT_PERCENT,\n useMinThickness: true,\n };\n } else {\n // Can't fit even with minimum cutout - rings must be thinner\n return {\n cutout: RADIAL_BAR_DIMENSIONS.MIN_CUTOUT_PERCENT,\n useMinThickness: false,\n };\n }\n }\n }\n\n // Update external library AFTER render\n override updated(changed: PropertyValues) {\n super.updated(changed);\n\n if (this.hasAnyChanged(changed, RADIAL_BAR_WATCHED_PROP_NAMES)) {\n // Recreate chart when major layout properties change\n // These properties affect aspect ratio calculation or require plugin reconfiguration\n const needsRecreation = this.hasAnyChanged(\n changed,\n RADIAL_BAR_RECREATE_PROP_NAMES\n );\n\n if (needsRecreation) {\n this.chart?.destroy();\n this.createChart();\n } else {\n this.updateChart();\n }\n }\n }\n\n override firstUpdated() {\n this.createChart();\n this.themeObserver = observeThemeChanges(() => this.updateChart());\n this.setupResizeObserver();\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n this.chart?.destroy();\n this.themeObserver?.disconnect();\n this.resizeObserver?.disconnect();\n }\n\n /**\n * Setup resize observer to detect height threshold crossings\n * Recreates chart when crossing MIN_HEIGHT_WITH_LABELS (192px) to show/hide labels\n */\n private setupResizeObserver() {\n if (!this.canvasEl) return;\n\n this.resizeObserver = new ResizeObserver(() => {\n const height = this.canvasEl?.clientHeight ?? 0;\n const isAboveThreshold =\n height >= RADIAL_BAR_DIMENSIONS.MIN_HEIGHT_WITH_LABELS;\n\n // Only recreate chart if we crossed the threshold\n if (isAboveThreshold !== this.wasAboveThreshold) {\n this.wasAboveThreshold = isAboveThreshold;\n this.chart?.destroy();\n this.createChart();\n } else {\n // Height changed but didn't cross threshold - just update\n this.updateChart();\n }\n });\n\n this.resizeObserver.observe(this.canvasEl);\n\n // Initialize threshold state\n const height = this.canvasEl.clientHeight;\n this.wasAboveThreshold =\n height >= RADIAL_BAR_DIMENSIONS.MIN_HEIGHT_WITH_LABELS;\n }\n\n private prepareChartData() {\n const chartColors = getChartColorsOrDefault(\n this,\n this.colors,\n this.priority === Priority.enhanced\n ? CHART_SECTOR_ENHANCED_COLORS\n : CHART_SECTOR_DEFAULT_COLORS\n );\n const remainingColor = getCssVariableValue(\n this,\n RADIAL_BAR_DIMENSIONS.REMAINING_COLOR\n );\n const borderColor = getCssVariableValue(\n this,\n RADIAL_BAR_DIMENSIONS.GAP_AND_BORDER_COLOR\n );\n\n // Reduce spacing for small charts to save space\n // Border is 2px on each side (top + bottom), so 4px total becomes 2px total\n const height = this.canvasEl?.clientHeight ?? 0;\n const isTooSmall = height < RADIAL_BAR_DIMENSIONS.MIN_HEIGHT_WITH_LABELS;\n const effectiveSpacing = isTooSmall\n ? RADIAL_BAR_DIMENSIONS.SPACING / 2\n : RADIAL_BAR_DIMENSIONS.SPACING;\n\n const datasets = this.data.map((value, index) => {\n const remaining = Math.max(0, this.max - value);\n const color =\n chartColors[index % chartColors.length] ??\n CHART_SECTOR_DEFAULT_COLORS[0];\n\n return {\n data: [value, remaining],\n backgroundColor: [color, remainingColor],\n borderWidth: effectiveSpacing, // Use reduced spacing for small charts (1px + 1px borders)\n borderColor: borderColor, // Use container section color for gaps\n borderRadius: RADIAL_BAR_DIMENSIONS.BORDER_RADIUS,\n spacing: 0, // Spacing between colored and remaining segments\n weight: 1, // Equal weight for all rings\n };\n });\n\n return {datasets};\n }\n\n private getChartOptions(): ChartOptions<'doughnut'> {\n // Always start at 12 o'clock (top) and move clockwise\n const rotation = 0;\n\n // Use centralized layout calculation helper\n // Note: Radial bar charts don't have outer labels\n // Important: Always use full circle mode (isHalfMode = false) regardless of circumference (half is for donut chart only)\n // The circumference property only affects what portion of the circle is shown,\n // not the dimensions/layout calculation\n const dimensions = calculateFixedHeightChartLayout({\n fixedHeight: this.fixedHeight,\n isHalfMode: false, // Always full circle dimensions, circumference only controls what's shown\n showOuterLabels: false, // Radial bar charts don't have outer labels\n canvasEl: this.canvasEl,\n layoutConfig: {\n data: [], // No data labels for radial bars\n denominator: 100,\n },\n host: this,\n });\n\n // Set CSS variables for wrapper and canvas sizing\n this.style.setProperty('--chart-width', `${dimensions.calculatedWidth}px`);\n this.style.setProperty('--chart-height', `${dimensions.actualHeight}px`);\n\n // Calculate dynamic padding for Chart.js layout\n // Reduce padding by 1px to compensate for 2px wider chart diameter (258px vs 256px)\n const dynamicPadding = dimensions.isTooSmall\n ? 0 // No padding when too small\n : RADIAL_BAR_DIMENSIONS.CANVAS_PADDING;\n\n // Calculate chart diameter from dimensions\n // The chart area is inside the padding, so subtract padding from both sides\n // For larger charts (>= 192px), use RADIAL_BAR_DIMENSIONS.CHART_WIDTH (258px) to compensate for outer border\n // For small charts, calculate based on actual height\n const chartDiameter = dimensions.isTooSmall\n ? dimensions.actualHeight - dynamicPadding * 2\n : RADIAL_BAR_DIMENSIONS.CHART_WIDTH; // 258px: adds 2px to compensate for outer border visual appearance\n\n // Calculate optimal cutout based on number of rings and available space\n const {cutout: optimalCutout} = this.calculateOptimalLayout(\n chartDiameter,\n dimensions.isTooSmall\n );\n\n return {\n responsive: true,\n maintainAspectRatio: true,\n aspectRatio: dimensions.aspectRatio,\n rotation,\n circumference: this.circumference,\n cutout: `${optimalCutout}%`,\n layout: {\n padding: {\n top: dynamicPadding,\n right: dynamicPadding,\n bottom: dynamicPadding,\n left: dynamicPadding,\n },\n },\n plugins: {\n legend: {\n display: false,\n labels: {\n generateLabels: () => [], // Prevent Chart.js from generating labels internally\n },\n onClick: () => {}, // Disable legend click handler\n },\n tooltip: {\n ...getChartTooltipOptions(this),\n enabled: !dimensions.isTooSmall,\n filter: (tooltipItem) => tooltipItem.label !== 'Remaining',\n callbacks: {\n title: () => '',\n label: (context) => {\n // Show correct ring label and value for each dataset\n const datasetIndex = context.datasetIndex;\n const valueIndex = context.dataIndex;\n // Only show tooltip for the filled segment (index 0)\n if (valueIndex !== 0) return '';\n const ringLabel = `Ring ${datasetIndex + 1}`;\n const value = context.parsed;\n return `${ringLabel} ${value}`;\n },\n },\n },\n },\n animation: {\n animateRotate: false,\n animateScale: false,\n },\n };\n }\n\n private createChart() {\n // Guard: Verify canvas exists and is connected to DOM\n if (!this.canvasEl || !this.canvasEl.isConnected) return;\n\n const ctx = this.canvasEl.getContext('2d');\n if (!ctx) return;\n\n const {datasets} = this.prepareChartData();\n\n this.chart = new Chart(ctx, {\n type: 'doughnut',\n data: {\n labels: this.data.map((_, i) => `Ring ${i + 1}`),\n datasets,\n },\n options: this.getChartOptions(),\n });\n\n // Defer legend update to next tick to ensure Chart.js metadata is initialized\n requestAnimationFrame(() => this.updateLegend());\n }\n\n private updateChart() {\n // Guard: Verify chart and canvas still exist and are connected\n if (!this.chart || !this.canvasEl || !this.canvasEl.isConnected) return;\n\n const {datasets} = this.prepareChartData();\n\n this.chart.data.labels = this.data.map((_, i) => `Ring ${i + 1}`);\n this.chart.data.datasets = datasets;\n\n // Recalculate options with current dimensions\n const newOptions = this.getChartOptions();\n\n if (this.chart.options) {\n // Update all dynamic options\n Object.assign(this.chart.options, newOptions);\n }\n\n this.chart.update();\n\n // Update legend after chart update completes to ensure metadata is ready\n requestAnimationFrame(() => this.updateLegend());\n }\n\n /**\n * Update the legend HTML content\n */\n private updateLegend() {\n // Guard: Check if legend should be shown and chart is ready\n if (!this.legend || !this.legendDiv || !this.chart) return;\n\n // Guard: Check if dataset has data\n if (!this.data || this.data.length === 0) {\n // console.debug('[obc-radial-bar-chart] updateLegend: skipped - no data available');\n this.legendDiv.innerHTML = '';\n return;\n }\n\n try {\n const chartColors = getChartColorsOrDefault(\n this,\n this.colors,\n this.priority === Priority.enhanced\n ? CHART_SECTOR_ENHANCED_COLORS\n : CHART_SECTOR_DEFAULT_COLORS\n );\n\n const legendItems = this.data.map((value, i) => {\n const color =\n chartColors[i % chartColors.length] ??\n (this.priority === Priority.enhanced\n ? CHART_SECTOR_ENHANCED_COLORS[0]\n : CHART_SECTOR_DEFAULT_COLORS[0]);\n\n return {\n fillStyle: color,\n label: `Ring ${i + 1}`,\n value: value.toString(),\n unit: '',\n };\n });\n\n const legendHTML = generateLegendHTML(legendItems);\n this.legendDiv.innerHTML = legendHTML;\n } catch (error) {\n console.debug(\n '[obc-radial-bar-chart] updateLegend: error generating legend HTML',\n error\n );\n // Silent failure - don't throw, just skip legend update this time\n }\n }\n override render() {\n const wrapperClasses = {\n wrapper: true,\n debug: this.showDebugOverlay,\n };\n\n return html`\n <div class=${classMap(wrapperClasses)}>\n <canvas></canvas>\n ${this.legend ? html`<div class=\"legend\"></div>` : ''}\n </div>\n `;\n }\n\n static override styles = [\n unsafeCSS(componentStyle),\n unsafeCSS(chartCommonStyle),\n unsafeCSS(chartLegendStyle),\n unsafeCSS(chartDebugStyle),\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-radial-bar-chart': ObcRadialBarChart;\n }\n}\n"],"names":["height"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"radial-bar-chart.js","sources":["../../../src/bars-graphs/radial-bar-chart/radial-bar-chart.ts"],"sourcesContent":["import {LitElement, PropertyValues, html, unsafeCSS} from 'lit';\nimport {property, query} from 'lit/decorators.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport componentStyle from './radial-bar-chart.css?inline';\nimport chartCommonStyle from '../../charthelpers/chart-common.css?inline';\nimport chartDebugStyle from '../../charthelpers/chart-debug.css?inline';\nimport chartLegendStyle from '../../charthelpers/chart-legend.css?inline';\nimport {customElement} from '../../decorator.js';\nimport {Priority} from '../../navigation-instruments/types.js';\nimport {Chart, DoughnutController, ArcElement, Tooltip} from 'chart.js';\nimport type {ChartOptions} from 'chart.js';\nimport {\n CHART_SECTOR_DEFAULT_COLORS,\n CHART_SECTOR_ENHANCED_COLORS,\n CHART_DIMENSIONS,\n getCssVariableValue,\n getChartColorsOrDefault,\n observeThemeChanges,\n calculateFixedHeightChartLayout,\n getChartTooltipOptions,\n generateLegendHTML,\n} from '../../charthelpers/index.js';\n\n// Register Chart.js components\nChart.register(DoughnutController, ArcElement, Tooltip);\n\n// Radial-bar-specific dimension constants\nconst RADIAL_BAR_DIMENSIONS = {\n ...CHART_DIMENSIONS,\n CHART_WIDTH: 258, // Override: 256 + 2px to compensate for outer border visual appearance\n CANVAS_PADDING: 30, // Recude by the above 2px to keep chart area consistent\n GAP_AND_BORDER_COLOR: '--container-background-color',\n REMAINING_COLOR: '--border-outline-color',\n BORDER_RADIUS: 4,\n SPACING: 4, // Gap between rings in pixels (2px border on each side)\n MIN_RING_THICKNESS: 16, // Minimum visible arc thickness in pixels (excluding borders)\n MIN_CUTOUT_PERCENT: 20, // Minimum cutout percentage to maintain empty center\n DEFAULT_MAX_CUTOUT_PERCENT: 60, // Default/maximum cutout percentage when space allows\n} as const;\n\n// Properties that require chart recreation (destroy and create)\nconst RADIAL_BAR_RECREATE_PROP_NAMES = [\n 'circumference',\n 'showDebugOverlay',\n 'fixedHeight',\n 'minRingThickness',\n] as const;\n\n// All properties that trigger chart updates\nconst RADIAL_BAR_WATCHED_PROP_NAMES = [\n 'legend',\n 'data',\n 'colors',\n 'priority',\n 'max',\n 'circumference',\n 'showDebugOverlay',\n 'fixedHeight',\n 'minRingThickness',\n] as const;\n\n/**\n * `<obc-radial-bar-chart>` – A customizable radial bar chart for visualizing multiple metrics as concentric rings, with dynamic ring thickness and cutout calculation.\n *\n * This component renders multiple data values as concentric arcs (rings), each representing a different metric. It supports full circle (360°) or three-quarter circle (270°) layouts, dynamic ring thickness, and automatic cutout calculation to ensure all rings fit within the available space. The chart adapts its layout based on the number of rings and available space, and hides labels when the chart is too small (< 192px height) for clarity.\n *\n * ## Features\n * - **Fixed Height ⇒ Fixed Circumference:** The chart's circumference is determined by the `fixedHeight` property (default: 320px). This ensures the chart's circumference remains consistent and matches other radial instruments, regardless of the available browser or container width. The chart does not scale to fill the width; instead, it always uses the specified fixed height to define its size and circumference.\n * - **Layout:**\n * - Full 360° or 270° (three-quarter) circle layout, controlled by the `circumference` property.\n * - Multiple concentric rings, each representing a data value.\n * - **Dynamic Ring Thickness:**\n * - All rings maintain equal thickness when possible.\n * - The `cutout` value serves as the maximum/preferred cutout percentage.\n * - When many rings are present, cutout is automatically reduced to fit rings at `minRingThickness`.\n * - Cutout will not go below 20% (minimum to maintain visible center).\n * - If rings still don't fit with 20% cutout, ring thickness is reduced proportionally.\n * - **Customization:**\n * - Custom ring colors (with automatic fallback to theme palette).\n * - Adjustable minimum ring thickness (`minRingThickness`).\n * - Adjustable arc span (`circumference`).\n * - **Color Priority:** Set `priority` to `Priority.enhanced` to use the blue/enhanced\n * color palette instead of the default gray/regular palette (default: `Priority.regular`).\n * - **Capacity Visualization:**\n * - Each ring shows a filled and remaining segment based on the `max` value.\n * - **Responsive Behavior:**\n * - Automatically hides labels and reduces spacing when height < 192px.\n * - Maintains aspect ratio and adjusts padding for optimal ring positioning.\n * - **Theme Integration:**\n * - Colors update automatically when the `data-obc-theme` attribute changes on the `<html>` element.\n * - Example:\n * ```html\n * <html lang=\"en\" data-obc-theme=\"day\"></html>\n * ```\n *\n * ## Example\n *\n * **Basic Usage**\n * ```html\n * <obc-radial-bar-chart></obc-radial-bar-chart>\n * <script>\n * document.querySelector('obc-radial-bar-chart').data = [70, 50, 30];\n * </script>\n * ```\n *\n * **Three-Quarter Circle with Custom Colors**\n * ```html\n * <obc-radial-bar-chart></obc-radial-bar-chart>\n * <script>\n * const chart = document.querySelector('obc-radial-bar-chart');\n * chart.circumference = 270;\n * chart.data = [80, 60, 40, 20];\n * chart.colors = ['#e74c3c', '#f39c12', '#2ecc71', '#3498db'];\n * </script>\n * ```\n *\n * **Custom Minimum Ring Thickness and Max Value**\n * ```html\n * <obc-radial-bar-chart></obc-radial-bar-chart>\n * <script>\n * const chart = document.querySelector('obc-radial-bar-chart');\n * chart.minRingThickness = 20;\n * chart.max = 200;\n * chart.data = [120, 80, 40];\n * </script>\n * ```\n *\n * @beta\n */\n@customElement('obc-radial-bar-chart')\nexport class ObcRadialBarChart extends LitElement {\n /** Array of values for each ring (set via JavaScript) */\n @property({type: Array, attribute: false}) data: number[] = [];\n /** Custom ring colors (set via JavaScript) with fallback to theme palette */\n @property({type: Array, attribute: false}) colors: string[] = [];\n @property({type: String})\n priority: Priority = Priority.regular;\n /** Maximum value for calculating remaining empty area, default: 100 */\n @property({type: Number})\n max = 100;\n /** Arc span in degrees: 360 for full circle, 270 for 3/4 circle, default: 270 */\n @property({type: Number})\n circumference = 270;\n /** Whether to display the legend below the chart, default: false */\n @property({type: Boolean, reflect: true})\n legend = false;\n /** Show debug overlay for development, default: false */\n @property({type: Boolean, reflect: true})\n showDebugOverlay = false;\n /** Fixed height of the chart in pixels (determines chart circumference), default: 320. The chart's circumference is always based on this fixed height to match other radial instruments. */\n @property({type: Number, reflect: true})\n fixedHeight = 320;\n /** Minimum thickness of each ring in pixels, excluding borders, default: 16 */\n @property({\n type: Number,\n })\n minRingThickness = 16;\n\n /** @internal */\n @query('canvas') private canvasEl?: HTMLCanvasElement;\n\n /** @internal */\n @query('.legend') private legendDiv?: HTMLDivElement;\n\n /** @internal */\n private chart?: Chart;\n\n /** @internal */\n private themeObserver?: MutationObserver;\n\n /** @internal - ResizeObserver for tracking height threshold crossings */\n private resizeObserver?: ResizeObserver;\n\n /** @internal - Track previous state to detect threshold crossing */\n private wasAboveThreshold = false;\n\n private hasAnyChanged(\n changed: PropertyValues,\n props: readonly (keyof ObcRadialBarChart)[]\n ): boolean {\n return props.some((prop) => changed.has(prop));\n }\n\n /**\n * Calculate optimal cutout percentage and whether rings should use minimum thickness\n * based on available chart space and number of rings.\n *\n * Algorithm:\n * 1. Calculate total space needed for all rings at minRingThickness\n * 2. If enough space: use equal thickness and adjust cutout\n * 3. If not enough space with minCutout: reduce cutout to minimum\n * 4. If still not enough: rings must be thinner than minimum\n *\n * @param chartDiameter - Available chart diameter in pixels\n * @param isTooSmall - Whether chart is below MIN_HEIGHT_WITH_LABELS (affects border width)\n * @returns Object with calculated cutout percentage and flag for using minimum thickness\n */\n private calculateOptimalLayout(\n chartDiameter: number,\n isTooSmall: boolean\n ): {\n cutout: number;\n useMinThickness: boolean;\n } {\n const numRings = this.data.length;\n if (numRings === 0) {\n return {\n cutout: RADIAL_BAR_DIMENSIONS.DEFAULT_MAX_CUTOUT_PERCENT,\n useMinThickness: false,\n };\n }\n\n // Calculate total space per ring: minRingThickness + borders (spacing applied as borderWidth)\n // Border is applied on both sides, so total border = spacing (or spacing/2 for small charts)\n const effectiveSpacing = isTooSmall\n ? RADIAL_BAR_DIMENSIONS.SPACING / 2\n : RADIAL_BAR_DIMENSIONS.SPACING;\n const totalSpacePerRing = this.minRingThickness + effectiveSpacing;\n\n // Calculate radius (half of diameter)\n const radius = chartDiameter / 2;\n\n // Calculate total space needed for all rings\n const totalRingsSpace = numRings * totalSpacePerRing;\n\n // Calculate remaining space for cutout\n const remainingSpace = radius - totalRingsSpace;\n\n // Convert remaining space to cutout percentage\n const calculatedCutoutPercent = (remainingSpace / radius) * 100;\n\n // Check if we can fit all rings with minimum thickness\n if (calculatedCutoutPercent >= RADIAL_BAR_DIMENSIONS.MIN_CUTOUT_PERCENT) {\n // We have enough space - use minimum thickness and calculated cutout\n return {\n cutout: Math.min(\n calculatedCutoutPercent,\n RADIAL_BAR_DIMENSIONS.DEFAULT_MAX_CUTOUT_PERCENT\n ),\n useMinThickness: true,\n };\n } else {\n // Not enough space - try with minimum cutout\n const minCutoutSpace =\n (radius * RADIAL_BAR_DIMENSIONS.MIN_CUTOUT_PERCENT) / 100;\n const availableRingSpace = radius - minCutoutSpace;\n const spacePerRingWithMinCutout = availableRingSpace / numRings;\n\n if (spacePerRingWithMinCutout >= totalSpacePerRing) {\n // We can fit with minimum cutout\n return {\n cutout: RADIAL_BAR_DIMENSIONS.MIN_CUTOUT_PERCENT,\n useMinThickness: true,\n };\n } else {\n // Can't fit even with minimum cutout - rings must be thinner\n return {\n cutout: RADIAL_BAR_DIMENSIONS.MIN_CUTOUT_PERCENT,\n useMinThickness: false,\n };\n }\n }\n }\n\n // Update external library AFTER render\n override updated(changed: PropertyValues) {\n super.updated(changed);\n\n if (this.hasAnyChanged(changed, RADIAL_BAR_WATCHED_PROP_NAMES)) {\n // Recreate chart when major layout properties change\n // These properties affect aspect ratio calculation or require plugin reconfiguration\n const needsRecreation = this.hasAnyChanged(\n changed,\n RADIAL_BAR_RECREATE_PROP_NAMES\n );\n\n if (needsRecreation) {\n this.chart?.destroy();\n this.createChart();\n } else {\n this.updateChart();\n }\n }\n }\n\n override firstUpdated() {\n this.createChart();\n this.themeObserver = observeThemeChanges(() => this.updateChart());\n this.setupResizeObserver();\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n this.chart?.destroy();\n this.themeObserver?.disconnect();\n this.resizeObserver?.disconnect();\n }\n\n /**\n * Setup resize observer to detect height threshold crossings\n * Recreates chart when crossing MIN_HEIGHT_WITH_LABELS (192px) to show/hide labels\n */\n private setupResizeObserver() {\n if (!this.canvasEl) return;\n\n this.resizeObserver = new ResizeObserver(() => {\n const height = this.canvasEl?.clientHeight ?? 0;\n const isAboveThreshold =\n height >= RADIAL_BAR_DIMENSIONS.MIN_HEIGHT_WITH_LABELS;\n\n // Only recreate chart if we crossed the threshold\n if (isAboveThreshold !== this.wasAboveThreshold) {\n this.wasAboveThreshold = isAboveThreshold;\n this.chart?.destroy();\n this.createChart();\n } else {\n // Height changed but didn't cross threshold - just update\n this.updateChart();\n }\n });\n\n this.resizeObserver.observe(this.canvasEl);\n\n // Initialize threshold state\n const height = this.canvasEl.clientHeight;\n this.wasAboveThreshold =\n height >= RADIAL_BAR_DIMENSIONS.MIN_HEIGHT_WITH_LABELS;\n }\n\n private prepareChartData() {\n const chartColors = getChartColorsOrDefault(\n this,\n this.colors,\n this.priority === Priority.enhanced\n ? CHART_SECTOR_ENHANCED_COLORS\n : CHART_SECTOR_DEFAULT_COLORS\n );\n const remainingColor = getCssVariableValue(\n this,\n RADIAL_BAR_DIMENSIONS.REMAINING_COLOR\n );\n const borderColor = getCssVariableValue(\n this,\n RADIAL_BAR_DIMENSIONS.GAP_AND_BORDER_COLOR\n );\n\n // Reduce spacing for small charts to save space\n // Border is 2px on each side (top + bottom), so 4px total becomes 2px total\n const height = this.canvasEl?.clientHeight ?? 0;\n const isTooSmall = height < RADIAL_BAR_DIMENSIONS.MIN_HEIGHT_WITH_LABELS;\n const effectiveSpacing = isTooSmall\n ? RADIAL_BAR_DIMENSIONS.SPACING / 2\n : RADIAL_BAR_DIMENSIONS.SPACING;\n\n const datasets = this.data.map((value, index) => {\n const remaining = Math.max(0, this.max - value);\n const color =\n chartColors[index % chartColors.length] ??\n CHART_SECTOR_DEFAULT_COLORS[0];\n\n return {\n data: [value, remaining],\n backgroundColor: [color, remainingColor],\n borderWidth: effectiveSpacing, // Use reduced spacing for small charts (1px + 1px borders)\n borderColor: borderColor, // Use container section color for gaps\n borderRadius: RADIAL_BAR_DIMENSIONS.BORDER_RADIUS,\n spacing: 0, // Spacing between colored and remaining segments\n weight: 1, // Equal weight for all rings\n };\n });\n\n return {datasets};\n }\n\n private getChartOptions(): ChartOptions<'doughnut'> {\n // Always start at 12 o'clock (top) and move clockwise\n const rotation = 0;\n\n // Use centralized layout calculation helper\n // Note: Radial bar charts don't have outer labels\n // Important: Always use full circle mode (isHalfMode = false) regardless of circumference (half is for donut chart only)\n // The circumference property only affects what portion of the circle is shown,\n // not the dimensions/layout calculation\n const dimensions = calculateFixedHeightChartLayout({\n fixedHeight: this.fixedHeight,\n isHalfMode: false, // Always full circle dimensions, circumference only controls what's shown\n showOuterLabels: false, // Radial bar charts don't have outer labels\n canvasEl: this.canvasEl,\n layoutConfig: {\n data: [], // No data labels for radial bars\n denominator: 100,\n },\n host: this,\n });\n\n // Set CSS variables for wrapper and canvas sizing\n this.style.setProperty('--chart-width', `${dimensions.calculatedWidth}px`);\n this.style.setProperty('--chart-height', `${dimensions.actualHeight}px`);\n\n // Calculate dynamic padding for Chart.js layout\n // Reduce padding by 1px to compensate for 2px wider chart diameter (258px vs 256px)\n const dynamicPadding = dimensions.isTooSmall\n ? 0 // No padding when too small\n : RADIAL_BAR_DIMENSIONS.CANVAS_PADDING;\n\n // Calculate chart diameter from dimensions\n // The chart area is inside the padding, so subtract padding from both sides\n // For larger charts (>= 192px), use RADIAL_BAR_DIMENSIONS.CHART_WIDTH (258px) to compensate for outer border\n // For small charts, calculate based on actual height\n const chartDiameter = dimensions.isTooSmall\n ? dimensions.actualHeight - dynamicPadding * 2\n : RADIAL_BAR_DIMENSIONS.CHART_WIDTH; // 258px: adds 2px to compensate for outer border visual appearance\n\n // Calculate optimal cutout based on number of rings and available space\n const {cutout: optimalCutout} = this.calculateOptimalLayout(\n chartDiameter,\n dimensions.isTooSmall\n );\n\n return {\n responsive: true,\n maintainAspectRatio: true,\n aspectRatio: dimensions.aspectRatio,\n rotation,\n circumference: this.circumference,\n cutout: `${optimalCutout}%`,\n layout: {\n padding: {\n top: dynamicPadding,\n right: dynamicPadding,\n bottom: dynamicPadding,\n left: dynamicPadding,\n },\n },\n plugins: {\n legend: {\n display: false,\n labels: {\n generateLabels: () => [], // Prevent Chart.js from generating labels internally\n },\n onClick: () => {}, // Disable legend click handler\n },\n tooltip: {\n ...getChartTooltipOptions(this),\n enabled: !dimensions.isTooSmall,\n filter: (tooltipItem) => tooltipItem.label !== 'Remaining',\n callbacks: {\n title: () => '',\n label: (context) => {\n // Show correct ring label and value for each dataset\n const datasetIndex = context.datasetIndex;\n const valueIndex = context.dataIndex;\n // Only show tooltip for the filled segment (index 0)\n if (valueIndex !== 0) return '';\n const ringLabel = `Ring ${datasetIndex + 1}`;\n const value = context.parsed;\n return `${ringLabel} ${value}`;\n },\n },\n },\n },\n animation: {\n animateRotate: false,\n animateScale: false,\n },\n };\n }\n\n private createChart() {\n // Guard: Verify canvas exists and is connected to DOM\n if (!this.canvasEl || !this.canvasEl.isConnected) return;\n\n const ctx = this.canvasEl.getContext('2d');\n if (!ctx) return;\n\n const {datasets} = this.prepareChartData();\n\n this.chart = new Chart(ctx, {\n type: 'doughnut',\n data: {\n labels: this.data.map((_, i) => `Ring ${i + 1}`),\n datasets,\n },\n options: this.getChartOptions(),\n });\n\n // Defer legend update to next tick to ensure Chart.js metadata is initialized\n requestAnimationFrame(() => this.updateLegend());\n }\n\n private updateChart() {\n // Guard: Verify chart and canvas still exist and are connected\n if (!this.chart || !this.canvasEl || !this.canvasEl.isConnected) return;\n\n const {datasets} = this.prepareChartData();\n\n this.chart.data.labels = this.data.map((_, i) => `Ring ${i + 1}`);\n this.chart.data.datasets = datasets;\n\n // Recalculate options with current dimensions\n const newOptions = this.getChartOptions();\n\n if (this.chart.options) {\n // Update all dynamic options\n Object.assign(this.chart.options, newOptions);\n }\n\n this.chart.update();\n\n // Update legend after chart update completes to ensure metadata is ready\n requestAnimationFrame(() => this.updateLegend());\n }\n\n /**\n * Update the legend HTML content\n */\n private updateLegend() {\n // Guard: Check if legend should be shown and chart is ready\n if (!this.legend || !this.legendDiv || !this.chart) return;\n\n // Guard: Check if dataset has data\n if (!this.data || this.data.length === 0) {\n // console.debug('[obc-radial-bar-chart] updateLegend: skipped - no data available');\n this.legendDiv.innerHTML = '';\n return;\n }\n\n try {\n const chartColors = getChartColorsOrDefault(\n this,\n this.colors,\n this.priority === Priority.enhanced\n ? CHART_SECTOR_ENHANCED_COLORS\n : CHART_SECTOR_DEFAULT_COLORS\n );\n\n const legendItems = this.data.map((value, i) => {\n const color =\n chartColors[i % chartColors.length] ??\n (this.priority === Priority.enhanced\n ? CHART_SECTOR_ENHANCED_COLORS[0]\n : CHART_SECTOR_DEFAULT_COLORS[0]);\n\n return {\n fillStyle: color,\n label: `Ring ${i + 1}`,\n value: value.toString(),\n unit: '',\n };\n });\n\n const legendHTML = generateLegendHTML(legendItems);\n this.legendDiv.innerHTML = legendHTML;\n } catch (error) {\n console.debug(\n '[obc-radial-bar-chart] updateLegend: error generating legend HTML',\n error\n );\n // Silent failure - don't throw, just skip legend update this time\n }\n }\n override render() {\n const wrapperClasses = {\n wrapper: true,\n debug: this.showDebugOverlay,\n };\n\n return html`\n <div class=${classMap(wrapperClasses)}>\n <canvas></canvas>\n ${this.legend ? html`<div class=\"legend\"></div>` : ''}\n </div>\n `;\n }\n\n static override styles = [\n unsafeCSS(componentStyle),\n unsafeCSS(chartCommonStyle),\n unsafeCSS(chartLegendStyle),\n unsafeCSS(chartDebugStyle),\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-radial-bar-chart': ObcRadialBarChart;\n }\n}\n"],"names":["height"],"mappings":"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"}
|
|
@@ -184,32 +184,15 @@ export type ChartLineYAxisConfig = {
|
|
|
184
184
|
* </script>
|
|
185
185
|
* ```
|
|
186
186
|
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
* @property {Array<{id?: string; position?: 'left'|'right'; min?: number; max?: number; grid?: boolean}>} yAxes - Multiple y-axis definitions for complex charts. Each axis can specify `id` (referenced by dataset `yAxisID`), `position`, `min`/`max` range, and `grid` visibility.
|
|
195
|
-
* @property {boolean} showGrid - Show vertical grid lines (x-axis). When combined with `showGridX` and `showGridY`, controls full grid visibility. Default: `false`.
|
|
196
|
-
* @property {boolean} showGridX - Show vertical grid lines (x-axis). Set to `false` to hide only vertical lines while keeping horizontal lines. Default: `false`.
|
|
197
|
-
* @property {boolean} showGridY - Show horizontal grid lines (y-axis). Set to `false` to hide only horizontal lines while keeping vertical lines. Default: `false`.
|
|
198
|
-
* @property {boolean} showTickMarks - Show axis tick marks and labels. Automatically hidden below 192px height threshold. Default: `false`.
|
|
199
|
-
* @property {boolean} showPoints - Show point markers on data points. Default: `false`.
|
|
200
|
-
* @property {boolean} fill - Enable area fill under/between lines. Use with `fillMode` to control fill style. Default: `false`.
|
|
201
|
-
* @property {'semitransparent'|'solid'|'threshold'} fillMode - Fill rendering mode. `'semitransparent'` uses 50% alpha, `'solid'` uses opaque fill, `'threshold'` (single-series only) fills above/below midpoint with red/blue gradient. Default: `'semitransparent'`.
|
|
202
|
-
* @property {'smooth'|'straight'|'stepped'} lineMode - Line drawing style. `'smooth'` applies bezier curve tension, `'straight'` draws straight lines, `'stepped'` creates step-like lines. Default: `'smooth'`.
|
|
203
|
-
* @property {boolean} stacked - Stack multi-series datasets vertically on y-axis. Ignored for single-series and threshold fill mode. Default: `false`.
|
|
204
|
-
* @property {string} unit - Unit label displayed in tooltips (e.g., 'kW', 'kg', '%'). Default: empty string.
|
|
205
|
-
* @property {number} xTicksLimit - Maximum number of x-axis ticks/grid lines. Useful for matching external axes. Optional.
|
|
206
|
-
* @property {number} xStepSize - Force specific interval between x-axis ticks (e.g., 1, 2, 5). Useful for matching external axes. Optional.
|
|
207
|
-
* @property {number} yTicksLimit - Maximum number of y-axis ticks/grid lines. Useful for matching external axes. Optional.
|
|
208
|
-
* @property {number} yStepSize - Force specific interval between y-axis ticks (e.g., 2, 5, 10). Useful for matching external axes. Optional.
|
|
209
|
-
* @property {boolean} legend - Show HTML legend below chart with series labels and colors. Default: `false`.
|
|
210
|
-
* @property {number} height - Chart height in pixels. Determines chart size with 1.5:1 aspect ratio (width = height × 1.5). Default: `320`.
|
|
211
|
-
* @property {boolean} showDebugOverlay - Development mode: show visual debug overlay with dimension guides. Shows blue border around canvas (axis area) and red border around chart grid (data area). Default: `false`.
|
|
187
|
+
* TODO(maintainer): `fill` is documented here as a class-level `@property` tag
|
|
188
|
+
* only because tooling (the manifest, lit-analyzer, story controls) still
|
|
189
|
+
* depends on it, yet no `@property`-decorated field backs it and no render path
|
|
190
|
+
* reads `this.fill` (fill is decided by the abstract `shouldApplyFill()`). Decide
|
|
191
|
+
* whether `fill` is a real public property (add a decorated field) or obsolete
|
|
192
|
+
* (remove this tag and the `.fill=` usages in the stories/wrappers). Kept as-is
|
|
193
|
+
* here to avoid changing the public API surface in a docs-only cleanup.
|
|
212
194
|
*
|
|
195
|
+
* @property {boolean} fill - Enable area fill under/between lines. Use with `fillMode` to control fill style. Default: `false`.
|
|
213
196
|
* @ignore This is an abstract base class. Use concrete implementations like ObcLineGraph or ObcAreaGraph instead.
|
|
214
197
|
* @experimental
|
|
215
198
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-line-base.d.ts","sourceRoot":"","sources":["../../../src/building-blocks/chart-line/chart-line-base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,cAAc,EAAkB,MAAM,KAAK,CAAC;AAkBhE,OAAO,KAAK,EAAC,YAAY,EAAE,YAAY,EAAqB,MAAM,UAAU,CAAC;AAC7E,OAAO,EACL,eAAe,EACf,UAAU,EACV,oBAAoB,EACpB,QAAQ,EACT,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAiBL,UAAU,EACX,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,+BAA+B,CAAC;AAqB/D;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC,6CAA6C;IAC7C,IAAI,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;IAC1C,8EAA8E;IAC9E,SAAS,EAAE,MAAM,CAAC;CACnB;AA0BD,YAAY,EAAC,WAAW,EAAE,YAAY,EAAC,MAAM,+BAA+B,CAAC;AAE7E,oBAAY,SAAS;IACnB,QAAQ,aAAa;IACrB,IAAI,SAAS;IACb,MAAM,WAAW;CAClB;AAED,oBAAY,aAAa;IACvB,IAAI,SAAS;IACb,KAAK,UAAU;CAChB;AAED,oBAAY,QAAQ;IAClB,MAAM,WAAW;IACjB,QAAQ,aAAa;IACrB,OAAO,YAAY;CACpB;AAED,oBAAY,WAAW;IACrB,OAAO,YAAY;IACnB,IAAI,SAAS;CACd;AAED,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG;IAAC,CAAC,EAAE,WAAW,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAC,CAAC;AAElE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,CAAC,CAAC,EAAE,WAAW,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAuCF
|
|
1
|
+
{"version":3,"file":"chart-line-base.d.ts","sourceRoot":"","sources":["../../../src/building-blocks/chart-line/chart-line-base.ts"],"names":[],"mappings":"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"}
|