@aceshooting/lyra-ui 25.3.0 → 25.4.0
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/CHANGELOG.md +28 -0
- package/custom-elements.json +1 -1
- package/dist/cli/migration-contract.json +1 -1
- package/dist/components/agent-tools/browser-frame/browser-frame.styles.js +1 -1
- package/dist/components/charts/chart/chart-sync.d.ts +4 -0
- package/dist/components/charts/chart/chart-sync.js +1 -0
- package/dist/components/charts/chart/chart-sync.styles.d.ts +1 -0
- package/dist/components/charts/chart/chart-sync.styles.js +1 -0
- package/dist/components/charts/chart/chart.class.d.ts +12 -2
- package/dist/components/charts/chart/chart.class.js +5 -4
- package/dist/components/charts/chart/histogram.class.js +1 -1
- package/dist/components/charts/chart/lite-chart.class.d.ts +18 -5
- package/dist/components/charts/chart/lite-chart.class.js +11 -11
- package/dist/components/data/heatmap/heatmap-grid-navigation.d.ts +2 -2
- package/dist/components/data/heatmap/heatmap-grid-navigation.js +1 -1
- package/dist/components/data/heatmap/heatmap.class.d.ts +24 -9
- package/dist/components/data/heatmap/heatmap.class.js +3 -3
- package/dist/components/forms/button/button.styles.js +1 -1
- package/dist/components/forms/locale-picker/locale-picker.styles.js +1 -1
- package/dist/components/layout/app-rail/app-rail.class.d.ts +1 -1
- package/dist/components/layout/app-rail/app-rail.class.js +1 -1
- package/dist/components/layout/card/card.styles.js +1 -1
- package/dist/components/layout/details/accordion-item.styles.js +1 -1
- package/dist/components/layout/details/details.styles.js +1 -1
- package/dist/components/layout/menu/menu.class.js +1 -1
- package/dist/components/layout/reorder-list/reorder-item.class.js +2 -0
- package/dist/components/media/avatar/avatar.class.d.ts +3 -0
- package/dist/components/media/avatar/avatar.styles.js +1 -1
- package/dist/components/media/pan-zoom/pan-zoom.styles.js +1 -1
- package/dist/framework-types.d.ts +1 -1
- package/dist/internal/glass-surface.styles.js +1 -1
- package/dist/internal/opaque-content-border.styles.d.ts +3 -0
- package/dist/internal/opaque-content-border.styles.js +1 -0
- package/dist/internal/package-metadata.d.ts +1 -1
- package/dist/internal/package-metadata.js +1 -1
- package/dist/internal/tokens.styles.js +1 -1
- package/dist/surfaces/glass.css +1 -1
- package/dist/theme.css +1 -1
- package/llms/components/lr-avatar.md +9 -3
- package/llms/components/lr-bar-chart.md +1 -1
- package/llms/components/lr-bubble-chart.md +1 -1
- package/llms/components/lr-chart.md +11 -2
- package/llms/components/lr-doughnut-chart.md +1 -1
- package/llms/components/lr-heatmap.md +16 -3
- package/llms/components/lr-histogram.md +9 -1
- package/llms/components/lr-line-chart.md +11 -1
- package/llms/components/lr-lite-chart.md +14 -4
- package/llms/components/lr-locale-picker.md +5 -5
- package/llms/components/lr-menu.md +4 -0
- package/llms/components/lr-pie-chart.md +1 -1
- package/llms/components/lr-polar-area-chart.md +1 -1
- package/llms/components/lr-radar-chart.md +1 -1
- package/llms/components/lr-reorder-list.md +5 -0
- package/llms/components/lr-scatter-chart.md +1 -1
- package/llms/peers.md +2 -2
- package/llms/shared/styles-and-tokens.md +31 -14
- package/llms/shared.md +31 -14
- package/llms/tokens.md +7 -4
- package/package.json +5 -5
- package/vscode-css-data.json +1 -1
- package/vscode-html-data.json +1 -1
- package/web-types.json +1 -1
|
@@ -26,7 +26,7 @@ export type LyraLiteChartTableCellFormatter=(value:number,context:LyraLiteChartT
|
|
|
26
26
|
* `chart.js`). For a project whose architecture forbids a charting
|
|
27
27
|
* dependency outright, this covers the common bar/line case: grouped or
|
|
28
28
|
* stacked bars, multi-series lines, per-point click, and hover tooltips
|
|
29
|
-
* (native SVG `<title
|
|
29
|
+
* (native SVG `<title>` by default; positioned text tooltip with `sync-group`) — not a full `lr-chart`
|
|
30
30
|
* replacement (no zoom/pan, no pie/doughnut/radar/scatter/bubble types, no
|
|
31
31
|
* horizontal/dual-y-axis, no raw-config passthrough, no interactive legend
|
|
32
32
|
* toggle — unlike `lr-chart`/`lr-box-plot`, clicking a `legend-item` here does
|
|
@@ -83,7 +83,7 @@ export type LyraLiteChartTableCellFormatter=(value:number,context:LyraLiteChartT
|
|
|
83
83
|
* unstacked overlay on a second axis" has no equivalent shape, and `stacked` already sums the
|
|
84
84
|
* whole category into one segmented bar; a per-series stack-group id would need the bar-geometry
|
|
85
85
|
* pass below to track independent running offsets per group instead of one per category. Tooltip
|
|
86
|
-
* title/footer formatters are likewise absent: the hover tooltip
|
|
86
|
+
* title/footer formatters are likewise absent: the default hover tooltip is a native SVG `<title>`
|
|
87
87
|
* per mark (`pointText`), not a multi-item tooltip with separate regions for several datasets
|
|
88
88
|
* sharing a hovered category.
|
|
89
89
|
*
|
|
@@ -131,6 +131,8 @@ export type LyraLiteChartTableCellFormatter=(value:number,context:LyraLiteChartT
|
|
|
131
131
|
* @slot data-table - An optional consumer-provided complete/paginated accessible data alternative.
|
|
132
132
|
* @cssprop [--lr-chart-height=var(--lr-size-280px)] - Consumer-owned chart height. The `height`
|
|
133
133
|
* property supplies only a private fallback, so this public token always wins when set.
|
|
134
|
+
* @cssprop [--lr-chart-tooltip-bg=var(--lr-color-surface)] - Synchronized tooltip background.
|
|
135
|
+
* @cssprop [--lr-chart-tooltip-color=var(--lr-color-text)] - Synchronized tooltip text color.
|
|
134
136
|
* @cssprop [--lr-chart-grid-color=var(--lr-color-border-subtle)] - Grid-line color.
|
|
135
137
|
* @cssprop [--lr-chart-tick-color=var(--lr-color-text-quiet)] - Axis and legend-detail color.
|
|
136
138
|
* @cssprop [--lr-chart-tick-font-size=var(--lr-font-size-2xs)] - Axis tick-label font size. Same
|
|
@@ -153,6 +155,10 @@ export type LyraLiteChartTableCellFormatter=(value:number,context:LyraLiteChartT
|
|
|
153
155
|
* keeping series apart. Declared on the swatch part rather than the host; the stripe width within
|
|
154
156
|
* a tile stays `--lr-border-width-thin`, so a larger step spaces the stripes further apart.
|
|
155
157
|
* Shared verbatim with `<lr-chart>` and `<lr-box-plot>`.
|
|
158
|
+
* @csspart sync-crosshair - Decorative category crosshair shown while a sync group is active.
|
|
159
|
+
* @csspart sync-tooltip - Noninteractive text tooltip showing this chart's matched category values.
|
|
160
|
+
* @cssprop [--lr-chart-sync-crosshair-color=var(--lr-color-text)] - Shared category crosshair color.
|
|
161
|
+
* @cssprop [--lr-chart-sync-crosshair-width=var(--lr-border-width-thin)] - Shared category crosshair width.
|
|
156
162
|
* @status stable
|
|
157
163
|
* @since 4.0.0
|
|
158
164
|
*/
|
|
@@ -352,7 +358,7 @@ private forcedColorPatternId;private descriptionId;private plotWidth;private plo
|
|
|
352
358
|
* stays structurally identical during hydration. */
|
|
353
359
|
private fitMeasurementAvailable;
|
|
354
360
|
/** One roving tab stop across all bar/point marks. */
|
|
355
|
-
private activeMarkIndex;private svgEl?;private liveRegion?;private resizeObserver?;private resizeObserverDocument?;private resizeObserverTarget?;private resizeObserverGeneration;private axisTitleTargets;private axisTitleFrame?;private axisTitleFits;private categoryLabelFits;private forcedColorsQuery?;private forcedColorsWindow?;private refocusMarkAfterUpdate;private refocusChartAfterUpdate;private politeAnnouncementSink?;private lastDataTruncationAnnouncement;
|
|
361
|
+
private activeMarkIndex;private syncPlot;private syncCategoryPositions;private svgEl?;private liveRegion?;private resizeObserver?;private resizeObserverDocument?;private resizeObserverTarget?;private resizeObserverGeneration;private axisTitleTargets;private axisTitleFrame?;private axisTitleFits;private categoryLabelFits;private forcedColorsQuery?;private forcedColorsWindow?;private refocusMarkAfterUpdate;private refocusChartAfterUpdate;private politeAnnouncementSink?;private lastDataTruncationAnnouncement;
|
|
356
362
|
/** Gates the sampling notice so an initially supplied large dataset is described, not announced. */
|
|
357
363
|
private isMounting;
|
|
358
364
|
/**
|
|
@@ -367,7 +373,14 @@ appendData(label:string,values:(number|null)[],maxPoints?:number):void;
|
|
|
367
373
|
* greatest of the label count and every series' data count. Missing labels and values become
|
|
368
374
|
* empty aligned cells, so a longer or ragged series is never truncated or shifted.
|
|
369
375
|
*/
|
|
370
|
-
exportData(format:LyraLiteChartExportFormat):string;attributeChangedCallback(name:string,oldValue:string|null,value:string|null):void;
|
|
376
|
+
exportData(format:LyraLiteChartExportFormat):string;attributeChangedCallback(name:string,oldValue:string|null,value:string|null):void;
|
|
377
|
+
/**
|
|
378
|
+
* Synchronizes the visible active category with categorical vertical bar/line charts in the
|
|
379
|
+
* same owner document. Trimmed, case-sensitive groups match exact nonempty category labels.
|
|
380
|
+
* Duplicate labels choose the first eligible recipient category; unique labels are recommended.
|
|
381
|
+
* Peer updates are visual only and never move focus, announce, activate or select data.
|
|
382
|
+
*/
|
|
383
|
+
syncGroup:string;private readonly chartSync;connectedCallback():void;private armResizeObserver;disconnectedCallback():void;adoptedCallback():void;private readonly onForcedColorsChange;private armForcedColorsWatcher;private disarmForcedColorsWatcher;private syncAnnouncementSink;private releaseAnnouncementSink;private resetResizeObserver;protected firstUpdated(changed:PropertyValues):void;protected willUpdate(changed:PropertyValues):void;protected updated(changed:PropertyValues):void;
|
|
371
384
|
/** Fit using the rendered font after hydration, preserving Lit's text part anchors. */
|
|
372
385
|
private fitAxisTitles;
|
|
373
386
|
/** Truncate one category-axis tick to a real measured `extent`, the same binary-search shape
|
|
@@ -492,7 +505,7 @@ private effectiveMinBarHeight;
|
|
|
492
505
|
* full height (a thin/short bar degrades to a plain rectangle path rather
|
|
493
506
|
* than self-intersecting).
|
|
494
507
|
*/
|
|
495
|
-
private roundedBarPath;private domain;private emitPoint;private emitNearestLinePoint;private onPointKeyDown;private formatValueAxisTick;private renderGrid;
|
|
508
|
+
private roundedBarPath;private domain;private emitPoint;private emitNearestLinePoint;private publishSyncMark;private syncPresentation;private onPointKeyDown;private formatValueAxisTick;private renderGrid;
|
|
496
509
|
/**
|
|
497
510
|
* `slot` is the per-category width to lay bars out against — either the
|
|
498
511
|
* measured-width-derived `plotW / n` (`layout="fit"`) or the fixed
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{__decorate}from"tslib";import{collectionSupport}from"../../../internal/collection-snapshot.js";import{nativeSvgTitle}from"../../../internal/svg-title.js";import{html,svg,nothing}from"lit";import{property,state,query}from"lit/decorators.js";import{styleMap}from"lit/directives/style-map.js";import{LyraElement}from"../../../internal/lyra-element.js";import{specialistTokens}from"../../../internal/specialist-tokens.styles.js";import{nextId,srOnly}from"../../../internal/a11y.js";import{getListFormat,getNumberFormat}from"../../../internal/intl-cache.js";import{finiteAdd,finiteCount,finiteNumber,finiteRange}from"../../../internal/numbers.js";import{escapeCsvField}from"../../utility/export-button/csv.js";import"../../utility/live-region/live-region.class.js";import{styles}from"./lite-chart.styles.js";import{bidiStyles,isolateHtml,isolatedMessage}from"./chart-bidi.js";import{forcedColorEncoding,forcedColorsActive}from"./chart-forced-colors.js";import{literalSetConverter}from"../../../internal/converters.js";import{sanitizeCssColor,sanitizeCssLength}from"../../../internal/safe-css.js";import{activeElementIn}from"../../../internal/active-element.js";import{acquireAnnouncementSink}from"../../../internal/announcer.js";import{MAX_RENDERED_CHART_RECORDS,sampleChartTableIndexes}from"./chart-table-sampling.js";import{chartChromeLegendPlacement,normalizeChartChromeLegendPosition}from"./chart-chrome.js";import{categoryLabelGrowth,hasCategoryLabelText,sparseCategoryLabelExtent,visibleCategoryLabelIndexes,widestEstimatedCategoryLabel}from"./lite-chart-axis-layout.js";import{LYRA_DEFAULT_chart,LYRA_DEFAULT_chartCategory,LYRA_DEFAULT_chartData,LYRA_DEFAULT_chartDataSampled,LYRA_DEFAULT_chartSeriesLabel,LYRA_DEFAULT_chartTotal,LYRA_DEFAULT_liteChartBarLabel,LYRA_DEFAULT_liteChartCustomMarkSummary,LYRA_DEFAULT_liteChartMarkSummary}from"../../../internal/default-strings.generated.js";function isLiteChartSeries(value){try{return typeof value=="object"&&value!==null&&!Array.isArray(value)&&Array.isArray(value.data)}catch{return!1}}function normalizeLiteChartSeries(value){try{return Object.freeze(Array.isArray(value)?value.filter(isLiteChartSeries):[])}catch{return Object.freeze([])}}function normalizeLiteChartType(value){return value==="line"||value==="bar"?value:"bar"}const LITE_CHART_LAYOUT=literalSetConverter(["fit","scroll"],"fit"),autoNumberConverter={fromAttribute:value=>{if(value===null)return;const trimmed=value.trim();return trimmed.toLowerCase()==="auto"?"auto":Number(trimmed)}},DEFAULT_PALETTE=["var(--lr-chart-color-1, var(--lr-color-chart-1))","var(--lr-chart-color-2, var(--lr-color-chart-2))","var(--lr-chart-color-3, var(--lr-color-chart-3))","var(--lr-chart-color-4, var(--lr-color-chart-4))","var(--lr-chart-color-5, var(--lr-color-chart-5))","var(--lr-chart-color-6, var(--lr-color-chart-6))","var(--lr-chart-color-7, var(--lr-color-chart-7))","var(--lr-chart-color-8, var(--lr-color-chart-8))"],PAD_LEFT=36,PAD_RIGHT=8,PAD_TOP=8,PAD_BOTTOM=30,CATEGORY_LABEL_OFFSET=24,AXIS_TITLE_SPACE=14,TICK_COUNT=4,BAR_GROUP_GAP=.2,BAR_GAP=.08,BAR_CORNER_RADIUS=4,APPROX_LABEL_CHARACTER_WIDTH=7,AUTO_CATEGORY_LABEL_INSET=10,VALUE_AXIS_TICK_OFFSET=6,AUTO_VALUE_AXIS_SAFETY_INSET=8,MAX_AUTO_VALUE_AXIS_GUTTER=240,MAX_AUTO_VALUE_AXIS_GUTTER_FRACTION=.4,MAX_SCROLL_CONTENT_WIDTH=1e6,CATEGORY_LABEL_SELECTION_BOUNDS=Object.freeze({characterWidth:APPROX_LABEL_CHARACTER_WIDTH,laneInset:AUTO_CATEGORY_LABEL_INSET,maxContentWidth:MAX_SCROLL_CONTENT_WIDTH,maxRenderedRecords:MAX_RENDERED_CHART_RECORDS});function niceStep(span,count){const rough=span/Math.max(1,count),magnitude=10**Math.floor(Math.log10(rough)),residual=rough/magnitude;return(residual<1.5?1:residual<3?2:residual<7?5:10)*magnitude}function logDomainFraction(value,lo,hi){const top=Math.max(hi,0);if(!Number.isFinite(top)||top<=0)return domainFraction(value,lo,hi);const bottom=lo>0?lo:top/10;if(!Number.isFinite(bottom)||bottom<=0||bottom>=top)return domainFraction(value,lo,hi);if(!Number.isFinite(value)||value<=bottom)return 0;if(value>=top)return 1;const fraction=(Math.log10(value)-Math.log10(bottom))/(Math.log10(top)-Math.log10(bottom));return Number.isFinite(fraction)?Math.min(1,Math.max(0,fraction)):0}function domainFraction(value,lo,hi){const span=hi-lo;if(Number.isFinite(span)&&span>0)return Math.min(1,Math.max(0,(value-lo)/span));const scale=Math.max(Math.abs(value),Math.abs(lo),Math.abs(hi),1),scaledSpan=hi/scale-lo/scale;if(!Number.isFinite(scaledSpan)||scaledSpan<=0)return 0;const fraction=(value/scale-lo/scale)/scaledSpan;return Number.isFinite(fraction)?Math.min(1,Math.max(0,fraction)):0}function safeDomainTicks(lo,hi,count){return Array.from({length:Math.max(1,count)+1},(_,index)=>{if(index===0)return lo;if(index===count)return hi;const ratio=index/count;return lo*(1-ratio)+hi*ratio}).filter(Number.isFinite)}function logarithmicTicks(lo,hi,count){if(!(lo>0&&hi>lo)||!Number.isFinite(lo)||!Number.isFinite(hi))return;const start=Math.log10(lo),end=Math.log10(hi),span=end-start;if(!(span>0))return;const decades=span>=1,step=decades?Math.ceil(span/count):niceStep(hi-lo,count);if(!Number.isFinite(step)||step<=0)return[...new Set(safeDomainTicks(lo,hi,count))];const ticks=[lo],minimumGap=decades?step/2:span/(count*2),first=Math.ceil((decades?start:lo)/step);for(let index=0;index<=count+1;index++){const value=decades?10**((first+index)*step):(first+index)*step;if(!Number.isFinite(value)||value>=hi)break;if(value<=ticks.at(-1))continue;const logarithm=Math.log10(value);logarithm-Math.log10(ticks.at(-1))>=minimumGap&&end-logarithm>=minimumGap&&ticks.push(value)}return ticks.push(hi),ticks}function niceDomain(dataLo,dataHi,beginAtZero,count){let lo=beginAtZero?Math.min(0,dataLo):dataLo,hi=beginAtZero?Math.max(0,dataHi):dataHi;lo===hi&&(Math.abs(lo)>Number.MAX_VALUE/2?(lo=lo>0?lo/2:lo,hi=hi<0?hi/2:hi):(lo-=1,hi+=1));const span=hi-lo;if(!Number.isFinite(span))return{lo,hi,ticks:safeDomainTicks(lo,hi,count)};const step=niceStep(span,count);if(!Number.isFinite(step)||step<=0)return{lo,hi,ticks:safeDomainTicks(lo,hi,count)};const roundedLo=Math.floor(lo/step)*step,roundedHi=Math.ceil(hi/step)*step;Number.isFinite(roundedLo)&&(lo=roundedLo),Number.isFinite(roundedHi)&&(hi=roundedHi);const slots=Math.floor((hi-lo)/step);if(!Number.isFinite(slots)||slots<0||slots>100)return{lo,hi,ticks:safeDomainTicks(lo,hi,count)};const ticks=[];for(let index=0;index<=slots;index++){const value=lo+index*step;Number.isFinite(value)&&ticks.push(value)}return ticks.at(-1)!==hi&&ticks.push(hi),{lo,hi,ticks}}class LyraLiteChart extends LyraElement{constructor(){super(...arguments),this.type="bar",this.labels=[],this._datasets=Object.freeze([]),this.withLegend=!1,this.legendPosition="bottom",this.height="280px",this.xLabel="",this.yLabel="",this.withoutZeroBaseline=!1,this.stacked=!1,this.tableTotals=!1,this.withDataTable=!1,this.dataTableToggle=!1,this.dataTableExpandedOverride=null,this.dataTableId=nextId("lite-chart-data-table"),this._layout="fit",this.barWidth=32,this.roundedBars=!1,this.skipZero=!1,this.scale="linear",this.withoutValueAxis=!1,this.selectedIndices=[],this.hostAccessibleLabel=null,this.label=null,this.description=null,this.forcedColorPatternId=nextId("lite-chart-pattern"),this.descriptionId=nextId("lite-chart-description"),this.plotWidth=0,this.plotHeight=0,this.fitMeasurementAvailable=!1,this.activeMarkIndex=0,this.resizeObserverGeneration=0,this.axisTitleTargets=new Set,this.axisTitleFits=new WeakMap,this.categoryLabelFits=new WeakMap,this.refocusMarkAfterUpdate=!1,this.refocusChartAfterUpdate=!1,this.lastDataTruncationAnnouncement="",this.isMounting=!0,this.onForcedColorsChange=()=>{!this.isConnected||this.ownerDocument.defaultView!==this.forcedColorsWindow||this.requestUpdate()}}static{this.defaultStrings={...super.defaultStrings,chart:LYRA_DEFAULT_chart,chartCategory:LYRA_DEFAULT_chartCategory,chartData:LYRA_DEFAULT_chartData,chartDataSampled:LYRA_DEFAULT_chartDataSampled,chartSeriesLabel:LYRA_DEFAULT_chartSeriesLabel,chartTotal:LYRA_DEFAULT_chartTotal,liteChartBarLabel:LYRA_DEFAULT_liteChartBarLabel,liteChartCustomMarkSummary:LYRA_DEFAULT_liteChartCustomMarkSummary,liteChartMarkSummary:LYRA_DEFAULT_liteChartMarkSummary}}static{this.collectionSupport=collectionSupport}static{this.ownedCollectionProperties=Object.freeze(["labels","datasets","selectedIndices"])}static{this.styles=[LyraElement.styles,specialistTokens,styles,srOnly,bidiStyles]}get datasets(){return this._datasets}set datasets(value){const previous=this._datasets;this._datasets=normalizeLiteChartSeries(value),this.requestUpdate("datasets",previous)}get dataTableVisible(){return this.dataTableToggle?this.dataTableExpandedOverride??this.withDataTable:this.withDataTable}toggleDataTable(){this.dataTableExpandedOverride=!this.dataTableVisible}get layout(){return this._layout}set layout(next){const normalized=LITE_CHART_LAYOUT.normalizeReflected(this,"layout",next),old=this._layout;old!==normalized&&(this._layout=normalized,this.requestUpdate("layout",old))}appendData(label,values,maxPoints=0){const limit=Math.max(0,finiteCount(maxPoints,0));let domainLength=this.labels.length;for(const series of this.datasets)domainLength=Math.max(domainLength,series.data.length);const labels=[...this.labels,...Array.from({length:Math.max(0,domainLength-this.labels.length)},()=>""),label],datasets=this.datasets.map((series,index)=>({...series,data:[...series.data,...Array.from({length:Math.max(0,domainLength-series.data.length)},()=>null),values[index]??null]}));this.labels=limit>0?labels.slice(-limit):labels,this.datasets=limit>0?datasets.map(series=>({...series,data:series.data.slice(-limit)})):datasets}exportData(format){if(format==="svg"){const XMLSerializerCtor=this.ownerDocument.defaultView?.XMLSerializer;return!this.svgEl||typeof XMLSerializerCtor!="function"?"":new XMLSerializerCtor().serializeToString(this.svgEl)}const header=["label",...this.datasets.map(series=>series.label)].map(escapeCsvField).join(","),rows=Array.from({length:this.recordCount()},(_,index)=>{const label=this.labels[index]??"";return[label,...this.datasets.map((series,datasetIndex)=>{const value=series.data[index];return typeof value=="number"&&Number.isFinite(value)?this.formatter?.({value,surface:"export",datasetIndex,index,label,seriesLabel:series.label,axis:"y"})??value:""})].map(escapeCsvField).join(",")});return[header,...rows].join(`\r
|
|
2
|
-
`)}attributeChangedCallback(name,oldValue,value){super.attributeChangedCallback(name,oldValue,value),oldValue!==value&&(name==="style"||name==="class")&&(this.fitAxisTitles(),this.fitCategoryLabels())}connectedCallback(){super.connectedCallback(),this.syncAnnouncementSink(),this.armResizeObserver(),this.armForcedColorsWatcher()}armResizeObserver(){const target=this.svgEl,ownerDocument=this.ownerDocument;if(!this.isConnected||!target||this.resizeObserver&&this.resizeObserverDocument===ownerDocument&&this.resizeObserverTarget===target)return;this.resetResizeObserver();const ResizeObserverCtor=ownerDocument.defaultView?.ResizeObserver;if(!ResizeObserverCtor)return;const generation=this.resizeObserverGeneration,observer=new ResizeObserverCtor(entries=>{if(this.resizeObserver!==observer||this.resizeObserverGeneration!==generation||!this.isConnected||this.ownerDocument!==ownerDocument||this.resizeObserverTarget!==target)return;const svgEntry=entries.find(entry=>entry.target===target);if(svgEntry){const box=svgEntry.contentBoxSize?.[0];if(box)this.plotWidth=box.inlineSize,this.plotHeight=box.blockSize;else{const rect=target.getBoundingClientRect();this.plotWidth=rect.width,this.plotHeight=rect.height}}entries.some(entry=>this.axisTitleTargets.has(entry.target))&&this.queueAxisTitleFit()});this.resizeObserver=observer,this.resizeObserverDocument=ownerDocument,this.resizeObserverTarget=target,target&&observer.observe(target),this.syncAxisTitleTargets()}disconnectedCallback(){super.disconnectedCallback(),this.releaseAnnouncementSink(),this.lastDataTruncationAnnouncement="",this.isMounting=!0,this.resetResizeObserver(),this.disarmForcedColorsWatcher()}adoptedCallback(){super.adoptedCallback(),this.resetResizeObserver(),this.releaseAnnouncementSink(),this.syncAnnouncementSink(),this.refreshFitMeasurementAvailability(),this.armForcedColorsWatcher()}armForcedColorsWatcher(){const ownerWindow=this.ownerDocument?.defaultView??void 0;ownerWindow?.matchMedia&&(this.forcedColorsWindow===ownerWindow&&this.forcedColorsQuery||(this.disarmForcedColorsWatcher(),this.forcedColorsWindow=ownerWindow,this.forcedColorsQuery=ownerWindow.matchMedia("(forced-colors: active)"),this.forcedColorsQuery.addEventListener("change",this.onForcedColorsChange)))}disarmForcedColorsWatcher(){this.forcedColorsQuery?.removeEventListener("change",this.onForcedColorsChange),this.forcedColorsQuery=void 0,this.forcedColorsWindow=void 0}syncAnnouncementSink(){this.isConnected&&this.politeAnnouncementSink?.element.ownerDocument!==this.ownerDocument&&(this.releaseAnnouncementSink(),this.politeAnnouncementSink=acquireAnnouncementSink("polite",{document:this.ownerDocument,source:this}))}releaseAnnouncementSink(){this.politeAnnouncementSink?.release(),this.politeAnnouncementSink=void 0}resetResizeObserver(){this.axisTitleFrame!==void 0&&(this.resizeObserverDocument?.defaultView?.cancelAnimationFrame(this.axisTitleFrame),this.axisTitleFrame=void 0),this.axisTitleTargets.clear(),this.resizeObserverGeneration+=1,this.resizeObserver?.disconnect(),this.resizeObserver=void 0,this.resizeObserverDocument=void 0,this.resizeObserverTarget=void 0}firstUpdated(changed){super.firstUpdated(changed),this.armResizeObserver()}willUpdate(changed){if(super.willUpdate(changed),this.seedFirstRenderState(()=>{this.refreshFitMeasurementAvailability()}),!["type","labels","datasets","skipZero"].some(name=>changed.has(name)))return;const active=activeElementIn(this.shadowRoot)??null,hadFocusedMark=active?.matches('[part="bar"], [part="point"]')??!1,priorPosition=Number(active?.getAttribute("data-mark-index")??this.activeMarkIndex),datasetAttribute=active?.getAttribute("data-dataset-index"),indexAttribute=active?.getAttribute("data-index"),datasetIndex=Number(datasetAttribute),index=Number(indexAttribute),marks=this.interactiveMarks(),sameIdentity=datasetAttribute!=null&&indexAttribute!==null&&indexAttribute!==void 0?marks.findIndex(mark=>mark.datasetIndex===datasetIndex&&mark.index===index):-1;this.activeMarkIndex=marks.length?sameIdentity>=0?sameIdentity:Math.min(Math.max(priorPosition,0),marks.length-1):0,this.refocusMarkAfterUpdate=hadFocusedMark&&marks.length>0,this.refocusChartAfterUpdate=hadFocusedMark&&marks.length===0}updated(changed){super.updated(changed);const wasMounting=this.isMounting;if(this.isMounting=!1,changed.has("height")){const height=sanitizeCssLength(this.height,"height");height?this.style.setProperty("--_lr-chart-height",height):this.style.removeProperty("--_lr-chart-height")}const dataTruncation=this.dataTruncationMessage();wasMounting?this.lastDataTruncationAnnouncement=dataTruncation:dataTruncation!==this.lastDataTruncationAnnouncement&&(this.lastDataTruncationAnnouncement=dataTruncation,dataTruncation&&this.politeAnnouncementSink?.announce(dataTruncation)),this.refocusMarkAfterUpdate&&(this.refocusMarkAfterUpdate=!1,this.renderRoot.querySelectorAll('[part="bar"], [part="point"]')[this.normalizedMarkIndex()]?.focus()),this.refocusChartAfterUpdate&&(this.refocusChartAfterUpdate=!1,this.svgEl?.focus()),this.fitAxisTitles(),this.fitCategoryLabels(),this.syncAxisTitleTargets()}fitAxisTitles(){if(!(!this.ownerDocument?.defaultView||!this.isConnected||!this.svgEl?.getClientRects().length))for(const title of this.svgEl.querySelectorAll('[part="axis-title"]')){const text=Array.from(title.childNodes).find(node=>node.nodeType===3);if(!text)continue;const source=title.getAttribute("aria-label")??"",extent=finiteRange(Number(title.getAttribute("data-title-extent")),0,0,MAX_SCROLL_CONTENT_WIDTH),previous=this.axisTitleFits.get(title);if(!(previous?.source===source&&previous.extent===extent&&previous.display===text.data&&previous.width===title.getComputedTextLength())){if(title.style.removeProperty("opacity"),text.data=source,title.getComputedTextLength()>extent)if(text.data="…",title.getComputedTextLength()>extent)title.style.opacity="0";else{let lower=0,upper=source.length;for(;lower<upper;){const middle=Math.ceil((lower+upper)/2);text.data=`${source.slice(0,middle)}…`,title.getComputedTextLength()<=extent?lower=middle:upper=middle-1}const last=source.charCodeAt(lower-1);last>=55296&&last<=56319&&(lower-=1),text.data=`${source.slice(0,lower)}…`}this.axisTitleFits.set(title,{source,extent,display:text.data,width:title.getComputedTextLength()})}}}fitOneCategoryLabel(tick,x,anchor,extent){const bounded=finiteRange(extent,0,0,MAX_SCROLL_CONTENT_WIDTH);tick.setAttribute("data-label-extent",String(bounded));const text=Array.from(tick.childNodes).find(node=>node.nodeType===3);if(!text)return x;const source=tick.getAttribute("data-full-label")??"",previous=this.categoryLabelFits.get(tick);if(previous?.source===source&&previous.extent===bounded&&previous.display===text.data&&previous.width===tick.getComputedTextLength())return anchor==="start"?x+previous.width:anchor==="end"?x-previous.width:x;if(text.data=source,tick.getComputedTextLength()>bounded)if(source.length<=1)text.data=source.length===0?source:"…";else{let lower=0,upper=source.length;for(;lower<upper;){const middle=Math.ceil((lower+upper)/2);text.data=middle===0?"…":`${source.slice(0,middle)}…`,tick.getComputedTextLength()<=bounded?lower=middle:upper=middle-1}const lastCode=source.charCodeAt(lower-1);lastCode>=55296&&lastCode<=56319&&(lower-=1),text.data=lower===0?"…":`${source.slice(0,lower)}…`}text.data===source?tick.removeAttribute("aria-label"):tick.setAttribute("aria-label",source);const width=tick.getComputedTextLength();return this.categoryLabelFits.set(tick,{source,extent:bounded,display:text.data,width}),anchor==="start"?x+width:anchor==="end"?x-width:x}fitCategoryLabels(){if(!this.ownerDocument?.defaultView||!this.isConnected||!this.svgEl?.getClientRects().length)return;const ticks=[...this.svgEl.querySelectorAll('[part="axis-label"][data-full-label]')].filter(tick=>hasCategoryLabelText(tick.getAttribute("data-full-label"))).sort((a,b)=>Number(a.getAttribute("x"))-Number(b.getAttribute("x"))),count=ticks.length;if(count===0)return;const MARGIN=BAR_CORNER_RADIUS,positionOf=tick=>Number(tick.getAttribute("x"))||0,anchorOf=tick=>tick.getAttribute("text-anchor")??"middle",first=ticks[0],last=ticks[count-1],firstIsBoundary=count>1&&anchorOf(first)!=="middle",lastIsBoundary=count>1&&anchorOf(last)!=="middle";let firstRightEdge=positionOf(first),lastLeftEdge=positionOf(last);if(firstIsBoundary&&lastIsBoundary&&count===2){const half=Math.max(0,(positionOf(last)-positionOf(first))/2-MARGIN);firstRightEdge=this.fitOneCategoryLabel(first,positionOf(first),anchorOf(first),half),lastLeftEdge=this.fitOneCategoryLabel(last,positionOf(last),anchorOf(last),half)}else{if(firstIsBoundary){const gap=positionOf(ticks[1])-positionOf(first);firstRightEdge=this.fitOneCategoryLabel(first,positionOf(first),anchorOf(first),gap-MARGIN)}if(lastIsBoundary){const gap=positionOf(last)-positionOf(ticks[count-2]);lastLeftEdge=this.fitOneCategoryLabel(last,positionOf(last),anchorOf(last),gap-MARGIN)}}for(let index=0;index<count;index++){if(index===0&&firstIsBoundary||index===count-1&&lastIsBoundary)continue;const tick=ticks[index],x=positionOf(tick),leftAvailable=index===0?MAX_SCROLL_CONTENT_WIDTH:index===1&&firstIsBoundary?x-firstRightEdge:(x-positionOf(ticks[index-1]))/2,rightAvailable=index===count-1?MAX_SCROLL_CONTENT_WIDTH:index===count-2&&lastIsBoundary?lastLeftEdge-x:(positionOf(ticks[index+1])-x)/2,extent=2*Math.min(leftAvailable,rightAvailable)-MARGIN;this.fitOneCategoryLabel(tick,x,anchorOf(tick),extent)}}syncAxisTitleTargets(){if(!this.resizeObserver||!this.svgEl)return;const current=new Set(this.svgEl.querySelectorAll('[part="axis-title"]'));for(const title of this.axisTitleTargets)current.has(title)||this.resizeObserver.unobserve(title);for(const title of current)this.axisTitleTargets.has(title)||this.resizeObserver.observe(title);this.axisTitleTargets=current}queueAxisTitleFit(){const document=this.resizeObserverDocument,window=document?.defaultView;if(!window||this.axisTitleFrame!==void 0)return;const generation=this.resizeObserverGeneration,frame=window.requestAnimationFrame(()=>{this.axisTitleFrame!==frame||this.resizeObserverGeneration!==generation||!this.isConnected||this.ownerDocument!==document||(this.axisTitleFrame=void 0,this.fitAxisTitles())});this.axisTitleFrame=frame}colorFor(index,series){return sanitizeCssColor(series.color)??DEFAULT_PALETTE[index%DEFAULT_PALETTE.length]}get effectiveType(){return normalizeLiteChartType(this.type)}forcedColors(){return forcedColorsActive(this.ownerDocument?.defaultView)}markPaint(index,series){const color=this.colorFor(index,series);return this.effectiveType==="bar"&&this.forcedColors()?`url(#${this.forcedColorPatternId}-${index})`:color}legendEncoding(index){return this.forcedColors()?forcedColorEncoding(index).name:nothing}markDash(index){if(!this.forcedColors())return nothing;const dash=forcedColorEncoding(index).dash;return dash.length?dash.join(" "):"none"}renderForcedColorPatterns(){if(this.effectiveType!=="bar"||!this.forcedColors())return nothing;const size=8,half=size/2,texture="var(--lr-color-surface)";return svg`<defs>
|
|
1
|
+
import{__decorate}from"tslib";import{ChartSyncController}from"./chart-sync.js";import{chartSyncStyles}from"./chart-sync.styles.js";import{collectionSupport}from"../../../internal/collection-snapshot.js";import{nativeSvgTitle}from"../../../internal/svg-title.js";import{html,svg,nothing}from"lit";import{property,state,query}from"lit/decorators.js";import{styleMap}from"lit/directives/style-map.js";import{LyraElement}from"../../../internal/lyra-element.js";import{specialistTokens}from"../../../internal/specialist-tokens.styles.js";import{nextId,srOnly}from"../../../internal/a11y.js";import{getListFormat,getNumberFormat}from"../../../internal/intl-cache.js";import{finiteAdd,finiteCount,finiteNumber,finiteRange}from"../../../internal/numbers.js";import{escapeCsvField}from"../../utility/export-button/csv.js";import"../../utility/live-region/live-region.class.js";import{styles}from"./lite-chart.styles.js";import{bidiStyles,isolateHtml,isolatedMessage}from"./chart-bidi.js";import{forcedColorEncoding,forcedColorsActive}from"./chart-forced-colors.js";import{literalSetConverter}from"../../../internal/converters.js";import{sanitizeCssColor,sanitizeCssLength}from"../../../internal/safe-css.js";import{activeElementIn}from"../../../internal/active-element.js";import{acquireAnnouncementSink}from"../../../internal/announcer.js";import{MAX_RENDERED_CHART_RECORDS,sampleChartTableIndexes}from"./chart-table-sampling.js";import{chartChromeLegendPlacement,normalizeChartChromeLegendPosition}from"./chart-chrome.js";import{categoryLabelGrowth,hasCategoryLabelText,sparseCategoryLabelExtent,visibleCategoryLabelIndexes,widestEstimatedCategoryLabel}from"./lite-chart-axis-layout.js";import{LYRA_DEFAULT_chart,LYRA_DEFAULT_chartCategory,LYRA_DEFAULT_chartData,LYRA_DEFAULT_chartDataSampled,LYRA_DEFAULT_chartSeriesLabel,LYRA_DEFAULT_chartTotal,LYRA_DEFAULT_liteChartBarLabel,LYRA_DEFAULT_liteChartCustomMarkSummary,LYRA_DEFAULT_liteChartMarkSummary}from"../../../internal/default-strings.generated.js";function isLiteChartSeries(value){try{return typeof value=="object"&&value!==null&&!Array.isArray(value)&&Array.isArray(value.data)}catch{return!1}}function normalizeLiteChartSeries(value){try{return Object.freeze(Array.isArray(value)?value.filter(isLiteChartSeries):[])}catch{return Object.freeze([])}}function normalizeLiteChartType(value){return value==="line"||value==="bar"?value:"bar"}const LITE_CHART_LAYOUT=literalSetConverter(["fit","scroll"],"fit"),autoNumberConverter={fromAttribute:value=>{if(value===null)return;const trimmed=value.trim();return trimmed.toLowerCase()==="auto"?"auto":Number(trimmed)}},DEFAULT_PALETTE=["var(--lr-chart-color-1, var(--lr-color-chart-1))","var(--lr-chart-color-2, var(--lr-color-chart-2))","var(--lr-chart-color-3, var(--lr-color-chart-3))","var(--lr-chart-color-4, var(--lr-color-chart-4))","var(--lr-chart-color-5, var(--lr-color-chart-5))","var(--lr-chart-color-6, var(--lr-color-chart-6))","var(--lr-chart-color-7, var(--lr-color-chart-7))","var(--lr-chart-color-8, var(--lr-color-chart-8))"],PAD_LEFT=36,PAD_RIGHT=8,PAD_TOP=8,PAD_BOTTOM=30,CATEGORY_LABEL_OFFSET=24,AXIS_TITLE_SPACE=14,TICK_COUNT=4,BAR_GROUP_GAP=.2,BAR_GAP=.08,BAR_CORNER_RADIUS=4,APPROX_LABEL_CHARACTER_WIDTH=7,AUTO_CATEGORY_LABEL_INSET=10,VALUE_AXIS_TICK_OFFSET=6,AUTO_VALUE_AXIS_SAFETY_INSET=8,MAX_AUTO_VALUE_AXIS_GUTTER=240,MAX_AUTO_VALUE_AXIS_GUTTER_FRACTION=.4,MAX_SCROLL_CONTENT_WIDTH=1e6,CATEGORY_LABEL_SELECTION_BOUNDS=Object.freeze({characterWidth:APPROX_LABEL_CHARACTER_WIDTH,laneInset:AUTO_CATEGORY_LABEL_INSET,maxContentWidth:MAX_SCROLL_CONTENT_WIDTH,maxRenderedRecords:MAX_RENDERED_CHART_RECORDS});function niceStep(span,count){const rough=span/Math.max(1,count),magnitude=10**Math.floor(Math.log10(rough)),residual=rough/magnitude;return(residual<1.5?1:residual<3?2:residual<7?5:10)*magnitude}function logDomainFraction(value,lo,hi){const top=Math.max(hi,0);if(!Number.isFinite(top)||top<=0)return domainFraction(value,lo,hi);const bottom=lo>0?lo:top/10;if(!Number.isFinite(bottom)||bottom<=0||bottom>=top)return domainFraction(value,lo,hi);if(!Number.isFinite(value)||value<=bottom)return 0;if(value>=top)return 1;const fraction=(Math.log10(value)-Math.log10(bottom))/(Math.log10(top)-Math.log10(bottom));return Number.isFinite(fraction)?Math.min(1,Math.max(0,fraction)):0}function domainFraction(value,lo,hi){const span=hi-lo;if(Number.isFinite(span)&&span>0)return Math.min(1,Math.max(0,(value-lo)/span));const scale=Math.max(Math.abs(value),Math.abs(lo),Math.abs(hi),1),scaledSpan=hi/scale-lo/scale;if(!Number.isFinite(scaledSpan)||scaledSpan<=0)return 0;const fraction=(value/scale-lo/scale)/scaledSpan;return Number.isFinite(fraction)?Math.min(1,Math.max(0,fraction)):0}function safeDomainTicks(lo,hi,count){return Array.from({length:Math.max(1,count)+1},(_,index)=>{if(index===0)return lo;if(index===count)return hi;const ratio=index/count;return lo*(1-ratio)+hi*ratio}).filter(Number.isFinite)}function logarithmicTicks(lo,hi,count){if(!(lo>0&&hi>lo)||!Number.isFinite(lo)||!Number.isFinite(hi))return;const start=Math.log10(lo),end=Math.log10(hi),span=end-start;if(!(span>0))return;const decades=span>=1,step=decades?Math.ceil(span/count):niceStep(hi-lo,count);if(!Number.isFinite(step)||step<=0)return[...new Set(safeDomainTicks(lo,hi,count))];const ticks=[lo],minimumGap=decades?step/2:span/(count*2),first=Math.ceil((decades?start:lo)/step);for(let index=0;index<=count+1;index++){const value=decades?10**((first+index)*step):(first+index)*step;if(!Number.isFinite(value)||value>=hi)break;if(value<=ticks.at(-1))continue;const logarithm=Math.log10(value);logarithm-Math.log10(ticks.at(-1))>=minimumGap&&end-logarithm>=minimumGap&&ticks.push(value)}return ticks.push(hi),ticks}function niceDomain(dataLo,dataHi,beginAtZero,count){let lo=beginAtZero?Math.min(0,dataLo):dataLo,hi=beginAtZero?Math.max(0,dataHi):dataHi;lo===hi&&(Math.abs(lo)>Number.MAX_VALUE/2?(lo=lo>0?lo/2:lo,hi=hi<0?hi/2:hi):(lo-=1,hi+=1));const span=hi-lo;if(!Number.isFinite(span))return{lo,hi,ticks:safeDomainTicks(lo,hi,count)};const step=niceStep(span,count);if(!Number.isFinite(step)||step<=0)return{lo,hi,ticks:safeDomainTicks(lo,hi,count)};const roundedLo=Math.floor(lo/step)*step,roundedHi=Math.ceil(hi/step)*step;Number.isFinite(roundedLo)&&(lo=roundedLo),Number.isFinite(roundedHi)&&(hi=roundedHi);const slots=Math.floor((hi-lo)/step);if(!Number.isFinite(slots)||slots<0||slots>100)return{lo,hi,ticks:safeDomainTicks(lo,hi,count)};const ticks=[];for(let index=0;index<=slots;index++){const value=lo+index*step;Number.isFinite(value)&&ticks.push(value)}return ticks.at(-1)!==hi&&ticks.push(hi),{lo,hi,ticks}}class LyraLiteChart extends LyraElement{constructor(){super(...arguments),this.type="bar",this.labels=[],this._datasets=Object.freeze([]),this.withLegend=!1,this.legendPosition="bottom",this.height="280px",this.xLabel="",this.yLabel="",this.withoutZeroBaseline=!1,this.stacked=!1,this.tableTotals=!1,this.withDataTable=!1,this.dataTableToggle=!1,this.dataTableExpandedOverride=null,this.dataTableId=nextId("lite-chart-data-table"),this._layout="fit",this.barWidth=32,this.roundedBars=!1,this.skipZero=!1,this.scale="linear",this.withoutValueAxis=!1,this.selectedIndices=[],this.hostAccessibleLabel=null,this.label=null,this.description=null,this.forcedColorPatternId=nextId("lite-chart-pattern"),this.descriptionId=nextId("lite-chart-description"),this.plotWidth=0,this.plotHeight=0,this.fitMeasurementAvailable=!1,this.activeMarkIndex=0,this.syncPlot={y:0,height:0},this.syncCategoryPositions=new Map,this.resizeObserverGeneration=0,this.axisTitleTargets=new Set,this.axisTitleFits=new WeakMap,this.categoryLabelFits=new WeakMap,this.refocusMarkAfterUpdate=!1,this.refocusChartAfterUpdate=!1,this.lastDataTruncationAnnouncement="",this.isMounting=!0,this.syncGroup="",this.chartSync=new ChartSyncController(this,(label,index)=>this.syncPresentation(label,index),void 0,target=>target.nodeType===1&&target.hasAttribute("data-mark-index")),this.onForcedColorsChange=()=>{!this.isConnected||this.ownerDocument.defaultView!==this.forcedColorsWindow||this.requestUpdate()}}static{this.defaultStrings={...super.defaultStrings,chart:LYRA_DEFAULT_chart,chartCategory:LYRA_DEFAULT_chartCategory,chartData:LYRA_DEFAULT_chartData,chartDataSampled:LYRA_DEFAULT_chartDataSampled,chartSeriesLabel:LYRA_DEFAULT_chartSeriesLabel,chartTotal:LYRA_DEFAULT_chartTotal,liteChartBarLabel:LYRA_DEFAULT_liteChartBarLabel,liteChartCustomMarkSummary:LYRA_DEFAULT_liteChartCustomMarkSummary,liteChartMarkSummary:LYRA_DEFAULT_liteChartMarkSummary}}static{this.collectionSupport=collectionSupport}static{this.ownedCollectionProperties=Object.freeze(["labels","datasets","selectedIndices"])}static{this.styles=[LyraElement.styles,specialistTokens,styles,srOnly,bidiStyles,chartSyncStyles]}get datasets(){return this._datasets}set datasets(value){const previous=this._datasets;this._datasets=normalizeLiteChartSeries(value),this.requestUpdate("datasets",previous)}get dataTableVisible(){return this.dataTableToggle?this.dataTableExpandedOverride??this.withDataTable:this.withDataTable}toggleDataTable(){this.dataTableExpandedOverride=!this.dataTableVisible}get layout(){return this._layout}set layout(next){const normalized=LITE_CHART_LAYOUT.normalizeReflected(this,"layout",next),old=this._layout;old!==normalized&&(this._layout=normalized,this.requestUpdate("layout",old))}appendData(label,values,maxPoints=0){const limit=Math.max(0,finiteCount(maxPoints,0));let domainLength=this.labels.length;for(const series of this.datasets)domainLength=Math.max(domainLength,series.data.length);const labels=[...this.labels,...Array.from({length:Math.max(0,domainLength-this.labels.length)},()=>""),label],datasets=this.datasets.map((series,index)=>({...series,data:[...series.data,...Array.from({length:Math.max(0,domainLength-series.data.length)},()=>null),values[index]??null]}));this.labels=limit>0?labels.slice(-limit):labels,this.datasets=limit>0?datasets.map(series=>({...series,data:series.data.slice(-limit)})):datasets}exportData(format){if(format==="svg"){const XMLSerializerCtor=this.ownerDocument.defaultView?.XMLSerializer;return!this.svgEl||typeof XMLSerializerCtor!="function"?"":new XMLSerializerCtor().serializeToString(this.svgEl)}const header=["label",...this.datasets.map(series=>series.label)].map(escapeCsvField).join(","),rows=Array.from({length:this.recordCount()},(_,index)=>{const label=this.labels[index]??"";return[label,...this.datasets.map((series,datasetIndex)=>{const value=series.data[index];return typeof value=="number"&&Number.isFinite(value)?this.formatter?.({value,surface:"export",datasetIndex,index,label,seriesLabel:series.label,axis:"y"})??value:""})].map(escapeCsvField).join(",")});return[header,...rows].join(`\r
|
|
2
|
+
`)}attributeChangedCallback(name,oldValue,value){super.attributeChangedCallback(name,oldValue,value),oldValue!==value&&(name==="style"||name==="class")&&(this.fitAxisTitles(),this.fitCategoryLabels())}connectedCallback(){super.connectedCallback(),this.syncAnnouncementSink(),this.armResizeObserver(),this.armForcedColorsWatcher()}armResizeObserver(){const target=this.svgEl,ownerDocument=this.ownerDocument;if(!this.isConnected||!target||this.resizeObserver&&this.resizeObserverDocument===ownerDocument&&this.resizeObserverTarget===target)return;this.resetResizeObserver();const ResizeObserverCtor=ownerDocument.defaultView?.ResizeObserver;if(!ResizeObserverCtor)return;const generation=this.resizeObserverGeneration,observer=new ResizeObserverCtor(entries=>{if(this.resizeObserver!==observer||this.resizeObserverGeneration!==generation||!this.isConnected||this.ownerDocument!==ownerDocument||this.resizeObserverTarget!==target)return;const svgEntry=entries.find(entry=>entry.target===target);if(svgEntry){const box=svgEntry.contentBoxSize?.[0];if(box)this.plotWidth=box.inlineSize,this.plotHeight=box.blockSize;else{const rect=target.getBoundingClientRect();this.plotWidth=rect.width,this.plotHeight=rect.height}}entries.some(entry=>this.axisTitleTargets.has(entry.target))&&this.queueAxisTitleFit()});this.resizeObserver=observer,this.resizeObserverDocument=ownerDocument,this.resizeObserverTarget=target,target&&observer.observe(target),this.syncAxisTitleTargets()}disconnectedCallback(){this.chartSync.disconnect(),super.disconnectedCallback(),this.releaseAnnouncementSink(),this.lastDataTruncationAnnouncement="",this.isMounting=!0,this.resetResizeObserver(),this.disarmForcedColorsWatcher()}adoptedCallback(){this.chartSync.disconnect(),super.adoptedCallback(),this.requestUpdate(),this.resetResizeObserver(),this.releaseAnnouncementSink(),this.syncAnnouncementSink(),this.refreshFitMeasurementAvailability(),this.armForcedColorsWatcher()}armForcedColorsWatcher(){const ownerWindow=this.ownerDocument?.defaultView??void 0;ownerWindow?.matchMedia&&(this.forcedColorsWindow===ownerWindow&&this.forcedColorsQuery||(this.disarmForcedColorsWatcher(),this.forcedColorsWindow=ownerWindow,this.forcedColorsQuery=ownerWindow.matchMedia("(forced-colors: active)"),this.forcedColorsQuery.addEventListener("change",this.onForcedColorsChange)))}disarmForcedColorsWatcher(){this.forcedColorsQuery?.removeEventListener("change",this.onForcedColorsChange),this.forcedColorsQuery=void 0,this.forcedColorsWindow=void 0}syncAnnouncementSink(){this.isConnected&&this.politeAnnouncementSink?.element.ownerDocument!==this.ownerDocument&&(this.releaseAnnouncementSink(),this.politeAnnouncementSink=acquireAnnouncementSink("polite",{document:this.ownerDocument,source:this}))}releaseAnnouncementSink(){this.politeAnnouncementSink?.release(),this.politeAnnouncementSink=void 0}resetResizeObserver(){this.axisTitleFrame!==void 0&&(this.resizeObserverDocument?.defaultView?.cancelAnimationFrame(this.axisTitleFrame),this.axisTitleFrame=void 0),this.axisTitleTargets.clear(),this.resizeObserverGeneration+=1,this.resizeObserver?.disconnect(),this.resizeObserver=void 0,this.resizeObserverDocument=void 0,this.resizeObserverTarget=void 0}firstUpdated(changed){super.firstUpdated(changed),this.armResizeObserver()}willUpdate(changed){if(super.willUpdate(changed),this.seedFirstRenderState(()=>{this.refreshFitMeasurementAvailability()}),!["type","labels","datasets","skipZero"].some(name=>changed.has(name)))return;const active=activeElementIn(this.shadowRoot)??null,hadFocusedMark=active?.matches('[part="bar"], [part="point"]')??!1,priorPosition=Number(active?.getAttribute("data-mark-index")??this.activeMarkIndex),datasetAttribute=active?.getAttribute("data-dataset-index"),indexAttribute=active?.getAttribute("data-index"),datasetIndex=Number(datasetAttribute),index=Number(indexAttribute),marks=this.interactiveMarks(),sameIdentity=datasetAttribute!=null&&indexAttribute!==null&&indexAttribute!==void 0?marks.findIndex(mark=>mark.datasetIndex===datasetIndex&&mark.index===index):-1;this.activeMarkIndex=marks.length?sameIdentity>=0?sameIdentity:Math.min(Math.max(priorPosition,0),marks.length-1):0,this.refocusMarkAfterUpdate=hadFocusedMark&&marks.length>0,this.refocusChartAfterUpdate=hadFocusedMark&&marks.length===0}updated(changed){super.updated(changed);const wasMounting=this.isMounting;if(this.isMounting=!1,changed.has("height")){const height=sanitizeCssLength(this.height,"height");height?this.style.setProperty("--_lr-chart-height",height):this.style.removeProperty("--_lr-chart-height")}const dataTruncation=this.dataTruncationMessage();wasMounting?this.lastDataTruncationAnnouncement=dataTruncation:dataTruncation!==this.lastDataTruncationAnnouncement&&(this.lastDataTruncationAnnouncement=dataTruncation,dataTruncation&&this.politeAnnouncementSink?.announce(dataTruncation)),this.refocusMarkAfterUpdate&&(this.refocusMarkAfterUpdate=!1,this.renderRoot.querySelectorAll('[part="bar"], [part="point"]')[this.normalizedMarkIndex()]?.focus()),this.refocusChartAfterUpdate&&(this.refocusChartAfterUpdate=!1,this.svgEl?.focus()),this.fitAxisTitles(),this.fitCategoryLabels(),this.syncAxisTitleTargets();const dataChanged=["datasets","labels","type","skipZero","layout","maxRecords","maxSeries"].some(name=>changed.has(name));this.chartSync.update(this.syncGroup,!0,dataChanged)}fitAxisTitles(){if(!(!this.ownerDocument?.defaultView||!this.isConnected||!this.svgEl?.getClientRects().length))for(const title of this.svgEl.querySelectorAll('[part="axis-title"]')){const text=Array.from(title.childNodes).find(node=>node.nodeType===3);if(!text)continue;const source=title.getAttribute("aria-label")??"",extent=finiteRange(Number(title.getAttribute("data-title-extent")),0,0,MAX_SCROLL_CONTENT_WIDTH),previous=this.axisTitleFits.get(title);if(!(previous?.source===source&&previous.extent===extent&&previous.display===text.data&&previous.width===title.getComputedTextLength())){if(title.style.removeProperty("opacity"),text.data=source,title.getComputedTextLength()>extent)if(text.data="…",title.getComputedTextLength()>extent)title.style.opacity="0";else{let lower=0,upper=source.length;for(;lower<upper;){const middle=Math.ceil((lower+upper)/2);text.data=`${source.slice(0,middle)}…`,title.getComputedTextLength()<=extent?lower=middle:upper=middle-1}const last=source.charCodeAt(lower-1);last>=55296&&last<=56319&&(lower-=1),text.data=`${source.slice(0,lower)}…`}this.axisTitleFits.set(title,{source,extent,display:text.data,width:title.getComputedTextLength()})}}}fitOneCategoryLabel(tick,x,anchor,extent){const bounded=finiteRange(extent,0,0,MAX_SCROLL_CONTENT_WIDTH);tick.setAttribute("data-label-extent",String(bounded));const text=Array.from(tick.childNodes).find(node=>node.nodeType===3);if(!text)return x;const source=tick.getAttribute("data-full-label")??"",previous=this.categoryLabelFits.get(tick);if(previous?.source===source&&previous.extent===bounded&&previous.display===text.data&&previous.width===tick.getComputedTextLength())return anchor==="start"?x+previous.width:anchor==="end"?x-previous.width:x;if(text.data=source,tick.getComputedTextLength()>bounded)if(source.length<=1)text.data=source.length===0?source:"…";else{let lower=0,upper=source.length;for(;lower<upper;){const middle=Math.ceil((lower+upper)/2);text.data=middle===0?"…":`${source.slice(0,middle)}…`,tick.getComputedTextLength()<=bounded?lower=middle:upper=middle-1}const lastCode=source.charCodeAt(lower-1);lastCode>=55296&&lastCode<=56319&&(lower-=1),text.data=lower===0?"…":`${source.slice(0,lower)}…`}text.data===source?tick.removeAttribute("aria-label"):tick.setAttribute("aria-label",source);const width=tick.getComputedTextLength();return this.categoryLabelFits.set(tick,{source,extent:bounded,display:text.data,width}),anchor==="start"?x+width:anchor==="end"?x-width:x}fitCategoryLabels(){if(!this.ownerDocument?.defaultView||!this.isConnected||!this.svgEl?.getClientRects().length)return;const ticks=[...this.svgEl.querySelectorAll('[part="axis-label"][data-full-label]')].filter(tick=>hasCategoryLabelText(tick.getAttribute("data-full-label"))).sort((a,b)=>Number(a.getAttribute("x"))-Number(b.getAttribute("x"))),count=ticks.length;if(count===0)return;const MARGIN=BAR_CORNER_RADIUS,positionOf=tick=>Number(tick.getAttribute("x"))||0,anchorOf=tick=>tick.getAttribute("text-anchor")??"middle",first=ticks[0],last=ticks[count-1],firstIsBoundary=count>1&&anchorOf(first)!=="middle",lastIsBoundary=count>1&&anchorOf(last)!=="middle";let firstRightEdge=positionOf(first),lastLeftEdge=positionOf(last);if(firstIsBoundary&&lastIsBoundary&&count===2){const half=Math.max(0,(positionOf(last)-positionOf(first))/2-MARGIN);firstRightEdge=this.fitOneCategoryLabel(first,positionOf(first),anchorOf(first),half),lastLeftEdge=this.fitOneCategoryLabel(last,positionOf(last),anchorOf(last),half)}else{if(firstIsBoundary){const gap=positionOf(ticks[1])-positionOf(first);firstRightEdge=this.fitOneCategoryLabel(first,positionOf(first),anchorOf(first),gap-MARGIN)}if(lastIsBoundary){const gap=positionOf(last)-positionOf(ticks[count-2]);lastLeftEdge=this.fitOneCategoryLabel(last,positionOf(last),anchorOf(last),gap-MARGIN)}}for(let index=0;index<count;index++){if(index===0&&firstIsBoundary||index===count-1&&lastIsBoundary)continue;const tick=ticks[index],x=positionOf(tick),leftAvailable=index===0?MAX_SCROLL_CONTENT_WIDTH:index===1&&firstIsBoundary?x-firstRightEdge:(x-positionOf(ticks[index-1]))/2,rightAvailable=index===count-1?MAX_SCROLL_CONTENT_WIDTH:index===count-2&&lastIsBoundary?lastLeftEdge-x:(positionOf(ticks[index+1])-x)/2,extent=2*Math.min(leftAvailable,rightAvailable)-MARGIN;this.fitOneCategoryLabel(tick,x,anchorOf(tick),extent)}}syncAxisTitleTargets(){if(!this.resizeObserver||!this.svgEl)return;const current=new Set(this.svgEl.querySelectorAll('[part="axis-title"]'));for(const title of this.axisTitleTargets)current.has(title)||this.resizeObserver.unobserve(title);for(const title of current)this.axisTitleTargets.has(title)||this.resizeObserver.observe(title);this.axisTitleTargets=current}queueAxisTitleFit(){const document=this.resizeObserverDocument,window=document?.defaultView;if(!window||this.axisTitleFrame!==void 0)return;const generation=this.resizeObserverGeneration,frame=window.requestAnimationFrame(()=>{this.axisTitleFrame!==frame||this.resizeObserverGeneration!==generation||!this.isConnected||this.ownerDocument!==document||(this.axisTitleFrame=void 0,this.fitAxisTitles())});this.axisTitleFrame=frame}colorFor(index,series){return sanitizeCssColor(series.color)??DEFAULT_PALETTE[index%DEFAULT_PALETTE.length]}get effectiveType(){return normalizeLiteChartType(this.type)}forcedColors(){return forcedColorsActive(this.ownerDocument?.defaultView)}markPaint(index,series){const color=this.colorFor(index,series);return this.effectiveType==="bar"&&this.forcedColors()?`url(#${this.forcedColorPatternId}-${index})`:color}legendEncoding(index){return this.forcedColors()?forcedColorEncoding(index).name:nothing}markDash(index){if(!this.forcedColors())return nothing;const dash=forcedColorEncoding(index).dash;return dash.length?dash.join(" "):"none"}renderForcedColorPatterns(){if(this.effectiveType!=="bar"||!this.forcedColors())return nothing;const size=8,half=size/2,texture="var(--lr-color-surface)";return svg`<defs>
|
|
3
3
|
${this.recordSample().seriesIndexes.map(index=>{const series=this.datasets[index],encoding=forcedColorEncoding(index).name,shapes=(()=>{switch(encoding){case"horizontal":return svg`<rect y=${half} width=${size} height="1" fill=${texture}></rect>`;case"vertical":return svg`<rect x=${half} width="1" height=${size} fill=${texture}></rect>`;case"diagonal":return svg`<path
|
|
4
4
|
d=${`M${-half},${size} L${half},0 M${half},${size} L${size+half},0`}
|
|
5
5
|
stroke=${texture}
|
|
@@ -19,7 +19,7 @@ import{__decorate}from"tslib";import{collectionSupport}from"../../../internal/co
|
|
|
19
19
|
<rect width=${size} height=${size} fill=${this.colorFor(index,series)}></rect>
|
|
20
20
|
${shapes}
|
|
21
21
|
</pattern>`})}
|
|
22
|
-
</defs>`}resolvePointText(label,value,datasetIndex,index){return this.formatter?.({value,surface:"visual",datasetIndex,...index===void 0?{}:{index},label,seriesLabel:this.datasets[datasetIndex]?.label,axis:"y"})??this.pointText?.(label,value,datasetIndex)}formatTableCell(value,context,numberFormat){return this.formatter?.({value,surface:"table",datasetIndex:context.datasetIndex??void 0,index:context.index,label:context.label,seriesLabel:context.seriesLabel??void 0,axis:"y",...context.kind==="total"?{statistic:"total"}:{}})??this.tableCellFormatter?.(value,context)??numberFormat.format(value)}tableTotalAt(index,seriesIndexes){let total=0,hasValue=!1;for(const seriesIndex of seriesIndexes){const series=this.datasets[seriesIndex];if(!series)continue;const value=series.data[index];value==null||!Number.isFinite(value)||(total=finiteAdd(total,value),hasValue=!0)}return hasValue?total:null}recordCount(){let count=this.labels.length;for(const series of this.datasets)count=Math.max(count,series.data.length);return count}recordSample(){const rowCount=this.recordCount(),seriesCount=this.datasets.length;return{rowCount,seriesCount,...sampleChartTableIndexes(rowCount,seriesCount)}}generatedDataIsSampled(){if(this.hasCustomDataTable())return!1;const sample=this.recordSample();return sample.rowCount===0||sample.seriesCount===0?!1:sample.rowIndexes.length<sample.rowCount||sample.seriesIndexes.length<sample.seriesCount}dataTruncationMessage(){return this.generatedDataIsSampled()?this.localize("chartDataSampled"):""}hasCustomDataTable(){return Array.from(this.children).some(child=>child.getAttribute("slot")==="data-table")}interactiveMarks(){const marks=[],sample=this.recordSample();if(this.effectiveType==="bar")for(const index of sample.rowIndexes)for(const datasetIndex of sample.seriesIndexes){const value=this.datasets[datasetIndex]?.data[index];value==null||!Number.isFinite(value)||this.skipZero&&value===0||marks.push({datasetIndex,index,label:this.labels[index]??"",value})}else sample.seriesIndexes.forEach(datasetIndex=>{const series=this.datasets[datasetIndex];series&&sample.rowIndexes.forEach(index=>{const value=series.data[index];value==null||!Number.isFinite(value)||marks.push({datasetIndex,index,label:this.labels[index]??"",value})})});return marks}awaitingFitMeasurement(){return this.layout==="fit"&&this.fitMeasurementAvailable&&(this.plotWidth<=0||this.plotHeight<=0)}refreshFitMeasurementAvailability(){this.fitMeasurementAvailable=typeof this.ownerDocument?.defaultView?.ResizeObserver=="function"}markIndexMap(){return new Map(this.interactiveMarks().map((mark,index)=>[`${mark.datasetIndex}:${mark.index}`,index]))}normalizedMarkIndex(marks=this.interactiveMarks()){return marks.length?Math.min(Math.max(this.activeMarkIndex,0),marks.length-1):-1}markSummary(index,marks){const mark=marks[index];if(!mark)return;const series=this.datasets[mark.datasetIndex]?.label??this.localize("chartSeriesLabel"),custom=this.formatter?.({value:mark.value,surface:"spoken",datasetIndex:mark.datasetIndex,index:mark.index,label:mark.label,seriesLabel:series,axis:"y"})??this.resolvePointText(mark.label,mark.value,mark.datasetIndex,mark.index);return custom?{format:values=>this.localize("liteChartCustomMarkSummary",void 0,values),values:{content:custom,index:getNumberFormat(this.effectiveLocale).format(index+1),total:getNumberFormat(this.effectiveLocale).format(marks.length)},isolated:["content"]}:{format:values=>this.localize("liteChartMarkSummary",void 0,values),values:{series,label:mark.label,value:getNumberFormat(this.effectiveLocale).format(mark.value),index:getNumberFormat(this.effectiveLocale).format(index+1),total:getNumberFormat(this.effectiveLocale).format(marks.length)},isolated:["series","label","value"]}}markAnnouncement(index,marks=this.interactiveMarks()){const summary=this.markSummary(index,marks);return summary?summary.format(summary.values):""}markListItem(index,marks){const summary=this.markSummary(index,marks);return summary?isolatedMessage(summary.format,summary.values,summary.isolated):""}onMarkFocus(index){const marks=this.interactiveMarks();marks[index]&&(this.activeMarkIndex=index,this.liveRegion?.announce(this.markAnnouncement(index,marks),{force:!0}))}focusMark(index){this.interactiveMarks()[index]&&(this.activeMarkIndex=index,this.updateComplete.then(()=>{const mark=Array.from(this.renderRoot.querySelectorAll('[part="bar"], [part="point"]'))[index];mark&&(activeElementIn(this.shadowRoot)===mark?this.onMarkFocus(index):mark.focus())}))}barValueToY(value,plotY,plotH,lo,hi){if(this.scale==="sqrt"){const zeroY=plotY+plotH-domainFraction(0,lo,hi)*plotH;if(value>=0){const domainMax2=hi>0?hi:1,fraction2=Math.sqrt(Math.min(domainMax2,value)/domainMax2);return zeroY-fraction2*(zeroY-plotY)}const domainMax=lo<0?-lo:1,fraction=Math.sqrt(Math.min(domainMax,-value)/domainMax);return zeroY+fraction*(plotY+plotH-zeroY)}return plotY+plotH-this.valueFraction(value,lo,hi)*plotH}valueFraction(value,lo,hi){return this.scale==="logarithmic"?logDomainFraction(value,this.logDomainFloor(lo,hi),hi):domainFraction(value,lo,hi)}logDomainFloor(lo,hi){if(lo>0)return lo;let smallest=Number.POSITIVE_INFINITY;for(const series of this.datasets)for(const value of series.data)value==null||!Number.isFinite(value)||value<=0||value<smallest&&(smallest=value);return Number.isFinite(smallest)?smallest:hi>0?hi/10:1}effectiveMinBarHeight(){return this.minBarHeight==null?void 0:finiteRange(this.minBarHeight,0,0,MAX_SCROLL_CONTENT_WIDTH)}roundedBarPath(x,y,w,h){const r=Math.max(0,Math.min(BAR_CORNER_RADIUS,w/2,h));return r<=0?`M${x},${y} h${w} v${h} h${-w} Z`:`M${x},${y+r} Q${x},${y} ${x+r},${y} H${x+w-r} Q${x+w},${y} ${x+w},${y+r} V${y+h} H${x} Z`}domain(){let lo=1/0,hi=-1/0;if(this.effectiveType==="bar"&&this.stacked)for(let i=0;i<this.recordCount();i++){let pos=0,neg=0;for(const s of this.datasets){const v=s.data[i];v==null||!Number.isFinite(v)||(v>=0?pos=finiteAdd(pos,v):neg=finiteAdd(neg,v))}lo=Math.min(lo,neg),hi=Math.max(hi,pos)}else for(const s of this.datasets)for(const v of s.data)v==null||!Number.isFinite(v)||(lo=Math.min(lo,v),hi=Math.max(hi,v));(!Number.isFinite(lo)||!Number.isFinite(hi))&&(lo=0,hi=1);const domain=niceDomain(lo,hi,!this.withoutZeroBaseline,TICK_COUNT);if(this.scale==="logarithmic"){const ticks=logarithmicTicks(this.logDomainFloor(domain.lo,domain.hi),domain.hi,TICK_COUNT);if(ticks)return{...domain,ticks}}return domain}emitPoint(datasetIndex,index){const label=this.labels[index],value=this.datasets[datasetIndex]?.data[index]??null;this.emit("lr-datum-activate",{kind:this.effectiveType==="bar"?"bar":"point",datasetIndex,index,label,value}),this.emit("lr-point-activate",{datasetIndex,index,label,value})}emitNearestLinePoint(event,points,fallbackDatasetIndex,fallbackIndex){let selected=points.find(point=>point.datasetIndex===fallbackDatasetIndex&&point.index===fallbackIndex);const currentTarget=event.currentTarget,svgElement=currentTarget instanceof SVGElement?currentTarget.ownerSVGElement:null,screenMatrix=svgElement?.getScreenCTM();if(event.detail>0&&svgElement&&screenMatrix&&points.length){const renderedPoint=svgElement.createSVGPoint(),squaredDistance=point=>{renderedPoint.x=point.x,renderedPoint.y=point.y;const screenPoint=renderedPoint.matrixTransform(screenMatrix),dx=event.clientX-screenPoint.x,dy=event.clientY-screenPoint.y;return dx*dx+dy*dy};let bestDistance=selected?squaredDistance(selected):Number.POSITIVE_INFINITY;for(const point of points){const distance=squaredDistance(point);distance<bestDistance&&(selected=point,bestDistance=distance)}}this.emitPoint(selected?.datasetIndex??fallbackDatasetIndex,selected?.index??fallbackIndex)}onPointKeyDown(e,datasetIndex,index,markIndex){if(e.key==="Enter"||e.key===" "){e.preventDefault(),this.onMarkFocus(markIndex),this.emitPoint(datasetIndex,index);return}const marks=this.interactiveMarks();if(!marks.length)return;const rtl=this.effectiveDirection==="rtl",forwardKey=rtl?"ArrowLeft":"ArrowRight",backwardKey=rtl?"ArrowRight":"ArrowLeft";let next=markIndex;if(e.key===forwardKey||e.key==="ArrowDown")next=Math.min(marks.length-1,markIndex+1);else if(e.key===backwardKey||e.key==="ArrowUp")next=Math.max(0,markIndex-1);else if(e.key==="Home")next=0;else if(e.key==="End")next=marks.length-1;else return;e.preventDefault(),this.focusMark(next)}formatValueAxisTick(value){return this.formatter?.({value,surface:"tick",axis:"y"})??(this.tickFormat?this.tickFormat(value):formatTick(value,this.effectiveLocale))}renderGrid(plotX,plotY,plotW,plotH,ticks,lo,hi){const rtl=this.effectiveDirection==="rtl";return ticks.map(({value,label})=>{const y=plotY+plotH-this.valueFraction(value,lo,hi)*plotH;return svg`
|
|
22
|
+
</defs>`}resolvePointText(label,value,datasetIndex,index){return this.formatter?.({value,surface:"visual",datasetIndex,...index===void 0?{}:{index},label,seriesLabel:this.datasets[datasetIndex]?.label,axis:"y"})??this.pointText?.(label,value,datasetIndex)}formatTableCell(value,context,numberFormat){return this.formatter?.({value,surface:"table",datasetIndex:context.datasetIndex??void 0,index:context.index,label:context.label,seriesLabel:context.seriesLabel??void 0,axis:"y",...context.kind==="total"?{statistic:"total"}:{}})??this.tableCellFormatter?.(value,context)??numberFormat.format(value)}tableTotalAt(index,seriesIndexes){let total=0,hasValue=!1;for(const seriesIndex of seriesIndexes){const series=this.datasets[seriesIndex];if(!series)continue;const value=series.data[index];value==null||!Number.isFinite(value)||(total=finiteAdd(total,value),hasValue=!0)}return hasValue?total:null}recordCount(){let count=this.labels.length;for(const series of this.datasets)count=Math.max(count,series.data.length);return count}recordSample(){const rowCount=this.recordCount(),seriesCount=this.datasets.length;return{rowCount,seriesCount,...sampleChartTableIndexes(rowCount,seriesCount)}}generatedDataIsSampled(){if(this.hasCustomDataTable())return!1;const sample=this.recordSample();return sample.rowCount===0||sample.seriesCount===0?!1:sample.rowIndexes.length<sample.rowCount||sample.seriesIndexes.length<sample.seriesCount}dataTruncationMessage(){return this.generatedDataIsSampled()?this.localize("chartDataSampled"):""}hasCustomDataTable(){return Array.from(this.children).some(child=>child.getAttribute("slot")==="data-table")}interactiveMarks(){const marks=[],sample=this.recordSample();if(this.effectiveType==="bar")for(const index of sample.rowIndexes)for(const datasetIndex of sample.seriesIndexes){const value=this.datasets[datasetIndex]?.data[index];value==null||!Number.isFinite(value)||this.skipZero&&value===0||marks.push({datasetIndex,index,label:this.labels[index]??"",value})}else sample.seriesIndexes.forEach(datasetIndex=>{const series=this.datasets[datasetIndex];series&&sample.rowIndexes.forEach(index=>{const value=series.data[index];value==null||!Number.isFinite(value)||marks.push({datasetIndex,index,label:this.labels[index]??"",value})})});return marks}awaitingFitMeasurement(){return this.layout==="fit"&&this.fitMeasurementAvailable&&(this.plotWidth<=0||this.plotHeight<=0)}refreshFitMeasurementAvailability(){this.fitMeasurementAvailable=typeof this.ownerDocument?.defaultView?.ResizeObserver=="function"}markIndexMap(){return new Map(this.interactiveMarks().map((mark,index)=>[`${mark.datasetIndex}:${mark.index}`,index]))}normalizedMarkIndex(marks=this.interactiveMarks()){return marks.length?Math.min(Math.max(this.activeMarkIndex,0),marks.length-1):-1}markSummary(index,marks){const mark=marks[index];if(!mark)return;const series=this.datasets[mark.datasetIndex]?.label??this.localize("chartSeriesLabel"),custom=this.formatter?.({value:mark.value,surface:"spoken",datasetIndex:mark.datasetIndex,index:mark.index,label:mark.label,seriesLabel:series,axis:"y"})??this.resolvePointText(mark.label,mark.value,mark.datasetIndex,mark.index);return custom?{format:values=>this.localize("liteChartCustomMarkSummary",void 0,values),values:{content:custom,index:getNumberFormat(this.effectiveLocale).format(index+1),total:getNumberFormat(this.effectiveLocale).format(marks.length)},isolated:["content"]}:{format:values=>this.localize("liteChartMarkSummary",void 0,values),values:{series,label:mark.label,value:getNumberFormat(this.effectiveLocale).format(mark.value),index:getNumberFormat(this.effectiveLocale).format(index+1),total:getNumberFormat(this.effectiveLocale).format(marks.length)},isolated:["series","label","value"]}}markAnnouncement(index,marks=this.interactiveMarks()){const summary=this.markSummary(index,marks);return summary?summary.format(summary.values):""}markListItem(index,marks){const summary=this.markSummary(index,marks);return summary?isolatedMessage(summary.format,summary.values,summary.isolated):""}onMarkFocus(index){const marks=this.interactiveMarks();marks[index]&&(this.activeMarkIndex=index,this.publishSyncMark(marks[index]),this.liveRegion?.announce(this.markAnnouncement(index,marks),{force:!0}))}focusMark(index){this.interactiveMarks()[index]&&(this.activeMarkIndex=index,this.updateComplete.then(()=>{const mark=Array.from(this.renderRoot.querySelectorAll('[part="bar"], [part="point"]'))[index];mark&&(activeElementIn(this.shadowRoot)===mark?this.onMarkFocus(index):mark.focus())}))}barValueToY(value,plotY,plotH,lo,hi){if(this.scale==="sqrt"){const zeroY=plotY+plotH-domainFraction(0,lo,hi)*plotH;if(value>=0){const domainMax2=hi>0?hi:1,fraction2=Math.sqrt(Math.min(domainMax2,value)/domainMax2);return zeroY-fraction2*(zeroY-plotY)}const domainMax=lo<0?-lo:1,fraction=Math.sqrt(Math.min(domainMax,-value)/domainMax);return zeroY+fraction*(plotY+plotH-zeroY)}return plotY+plotH-this.valueFraction(value,lo,hi)*plotH}valueFraction(value,lo,hi){return this.scale==="logarithmic"?logDomainFraction(value,this.logDomainFloor(lo,hi),hi):domainFraction(value,lo,hi)}logDomainFloor(lo,hi){if(lo>0)return lo;let smallest=Number.POSITIVE_INFINITY;for(const series of this.datasets)for(const value of series.data)value==null||!Number.isFinite(value)||value<=0||value<smallest&&(smallest=value);return Number.isFinite(smallest)?smallest:hi>0?hi/10:1}effectiveMinBarHeight(){return this.minBarHeight==null?void 0:finiteRange(this.minBarHeight,0,0,MAX_SCROLL_CONTENT_WIDTH)}roundedBarPath(x,y,w,h){const r=Math.max(0,Math.min(BAR_CORNER_RADIUS,w/2,h));return r<=0?`M${x},${y} h${w} v${h} h${-w} Z`:`M${x},${y+r} Q${x},${y} ${x+r},${y} H${x+w-r} Q${x+w},${y} ${x+w},${y+r} V${y+h} H${x} Z`}domain(){let lo=1/0,hi=-1/0;if(this.effectiveType==="bar"&&this.stacked)for(let i=0;i<this.recordCount();i++){let pos=0,neg=0;for(const s of this.datasets){const v=s.data[i];v==null||!Number.isFinite(v)||(v>=0?pos=finiteAdd(pos,v):neg=finiteAdd(neg,v))}lo=Math.min(lo,neg),hi=Math.max(hi,pos)}else for(const s of this.datasets)for(const v of s.data)v==null||!Number.isFinite(v)||(lo=Math.min(lo,v),hi=Math.max(hi,v));(!Number.isFinite(lo)||!Number.isFinite(hi))&&(lo=0,hi=1);const domain=niceDomain(lo,hi,!this.withoutZeroBaseline,TICK_COUNT);if(this.scale==="logarithmic"){const ticks=logarithmicTicks(this.logDomainFloor(domain.lo,domain.hi),domain.hi,TICK_COUNT);if(ticks)return{...domain,ticks}}return domain}emitPoint(datasetIndex,index){const label=this.labels[index],value=this.datasets[datasetIndex]?.data[index]??null;this.emit("lr-datum-activate",{kind:this.effectiveType==="bar"?"bar":"point",datasetIndex,index,label,value}),this.emit("lr-point-activate",{datasetIndex,index,label,value})}emitNearestLinePoint(event,points,fallbackDatasetIndex,fallbackIndex){let selected=points.find(point=>point.datasetIndex===fallbackDatasetIndex&&point.index===fallbackIndex);const currentTarget=event.currentTarget,svgElement=currentTarget instanceof SVGElement?currentTarget.ownerSVGElement:null,screenMatrix=svgElement?.getScreenCTM();if(event.detail>0&&svgElement&&screenMatrix&&points.length){const renderedPoint=svgElement.createSVGPoint(),squaredDistance=point=>{renderedPoint.x=point.x,renderedPoint.y=point.y;const screenPoint=renderedPoint.matrixTransform(screenMatrix),dx=event.clientX-screenPoint.x,dy=event.clientY-screenPoint.y;return dx*dx+dy*dy};let bestDistance=selected?squaredDistance(selected):Number.POSITIVE_INFINITY;for(const point of points){const distance=squaredDistance(point);distance<bestDistance&&(selected=point,bestDistance=distance)}}this.emitPoint(selected?.datasetIndex??fallbackDatasetIndex,selected?.index??fallbackIndex)}publishSyncMark(mark){this.chartSync.publish(mark.label,mark.index)}syncPresentation(label,sourceIndex){const marks=this.interactiveMarks(),index=sourceIndex??marks.filter(mark=>mark.label===label).sort((a,b)=>a.index-b.index)[0]?.index;if(index===void 0||this.labels[index]!==label)return;const matched=marks.filter(mark=>mark.index===index);if(!matched.length||!this.svgEl)return;const target=this.svgEl.querySelector(`[data-dataset-index="${matched[0].datasetIndex}"][data-index="${index}"]`),container=this.renderRoot.querySelector('[part="base"]');if(!target||!container||!target.getClientRects().length)return;const bounds=container.getBoundingClientRect(),matrix=this.svgEl.getScreenCTM();if(!matrix)return;const rows=matched.map(mark=>{const series=this.datasets[mark.datasetIndex]?.label??"";return this.resolvePointText(mark.label,mark.value,mark.datasetIndex,mark.index)??this.localize("liteChartBarLabel",void 0,{series,label:mark.label,value:getNumberFormat(this.effectiveLocale).format(mark.value)})});return{container,x:matrix.a*(this.syncCategoryPositions.get(index)??0)+matrix.e-bounds.left+container.scrollLeft,top:matrix.d*this.syncPlot.y+matrix.f-bounds.top+container.scrollTop,height:Math.abs(matrix.d*this.syncPlot.height),tooltip:{title:label,rows}}}onPointKeyDown(e,datasetIndex,index,markIndex){if(e.key==="Enter"||e.key===" "){e.preventDefault(),this.onMarkFocus(markIndex),this.emitPoint(datasetIndex,index);return}const marks=this.interactiveMarks();if(!marks.length)return;const rtl=this.effectiveDirection==="rtl",forwardKey=rtl?"ArrowLeft":"ArrowRight",backwardKey=rtl?"ArrowRight":"ArrowLeft";let next=markIndex;if(e.key===forwardKey||e.key==="ArrowDown")next=Math.min(marks.length-1,markIndex+1);else if(e.key===backwardKey||e.key==="ArrowUp")next=Math.max(0,markIndex-1);else if(e.key==="Home")next=0;else if(e.key==="End")next=marks.length-1;else return;e.preventDefault(),this.focusMark(next)}formatValueAxisTick(value){return this.formatter?.({value,surface:"tick",axis:"y"})??(this.tickFormat?this.tickFormat(value):formatTick(value,this.effectiveLocale))}renderGrid(plotX,plotY,plotW,plotH,ticks,lo,hi){const rtl=this.effectiveDirection==="rtl";return ticks.map(({value,label})=>{const y=plotY+plotH-this.valueFraction(value,lo,hi)*plotH;return svg`
|
|
23
23
|
<line part="grid-line" x1=${plotX} y1=${y} x2=${plotX+plotW} y2=${y}></line>
|
|
24
24
|
<text
|
|
25
25
|
part="axis-label"
|
|
@@ -40,7 +40,7 @@ import{__decorate}from"tslib";import{collectionSupport}from"../../../internal/co
|
|
|
40
40
|
@click=${()=>this.emitPoint(di,i)}
|
|
41
41
|
></rect>
|
|
42
42
|
`;bars.push(this.roundedBars?svg`
|
|
43
|
-
<g class="mark-hit-group">
|
|
43
|
+
<g class="mark-hit-group" @pointermove=${()=>this.publishSyncMark({datasetIndex:di,index:i,label,value:v})}>
|
|
44
44
|
${hitTarget}
|
|
45
45
|
<path
|
|
46
46
|
part="bar"
|
|
@@ -58,10 +58,10 @@ import{__decorate}from"tslib";import{collectionSupport}from"../../../internal/co
|
|
|
58
58
|
@click=${()=>this.emitPoint(di,i)}
|
|
59
59
|
@focus=${()=>this.onMarkFocus(markIndex)}
|
|
60
60
|
@keydown=${e=>this.onPointKeyDown(e,di,i,markIndex)}
|
|
61
|
-
>${nativeSvgTitle(titleText)}</path>
|
|
61
|
+
>${typeof this.syncGroup=="string"&&this.syncGroup.trim()?nothing:nativeSvgTitle(titleText)}</path>
|
|
62
62
|
</g>
|
|
63
63
|
`:svg`
|
|
64
|
-
<g class="mark-hit-group">
|
|
64
|
+
<g class="mark-hit-group" @pointermove=${()=>this.publishSyncMark({datasetIndex:di,index:i,label,value:v})}>
|
|
65
65
|
${hitTarget}
|
|
66
66
|
<rect
|
|
67
67
|
part="bar"
|
|
@@ -82,10 +82,10 @@ import{__decorate}from"tslib";import{collectionSupport}from"../../../internal/co
|
|
|
82
82
|
@click=${()=>this.emitPoint(di,i)}
|
|
83
83
|
@focus=${()=>this.onMarkFocus(markIndex)}
|
|
84
84
|
@keydown=${e=>this.onPointKeyDown(e,di,i,markIndex)}
|
|
85
|
-
>${nativeSvgTitle(titleText)}</rect>
|
|
85
|
+
>${typeof this.syncGroup=="string"&&this.syncGroup.trim()?nothing:nativeSvgTitle(titleText)}</rect>
|
|
86
86
|
</g>
|
|
87
87
|
`)})}return bars}renderLines(plotX,plotY,plotW,plotH,lo,hi,recordSample,selectedIndices){const n=this.recordCount(),xFor=i=>plotX+(n>1?i/(n-1)*plotW:plotW/2),yFor=v=>plotY+plotH-this.valueFraction(v,lo,hi)*plotH,markIndexes=this.markIndexMap(),activeMarkIndex=this.normalizedMarkIndex(),numberFormat=getNumberFormat(this.effectiveLocale),hitPoints=[];return recordSample.seriesIndexes.forEach(datasetIndex=>{const series=this.datasets[datasetIndex];series&&recordSample.rowIndexes.forEach(index=>{const value=series.data[index];value==null||!Number.isFinite(value)||hitPoints.push({datasetIndex,index,x:xFor(index),y:yFor(value)})})}),recordSample.seriesIndexes.map(di=>{const s=this.datasets[di];if(!s)return nothing;const color=this.colorFor(di,s);let d="",penDown=!1,previousSourceIndex=-1;recordSample.rowIndexes.forEach(i=>{const v=s.data[i];if(v==null||!Number.isFinite(v)){penDown=!1,previousSourceIndex=i;return}if(penDown&&previousSourceIndex>=0&&i>previousSourceIndex+1)for(let skipped=previousSourceIndex+1;skipped<i;skipped++){const candidate=s.data[skipped];if(candidate==null||!Number.isFinite(candidate)){penDown=!1;break}}d+=`${penDown?"L":"M"}${xFor(i)},${yFor(v)} `,penDown=!0,previousSourceIndex=i});const dots=recordSample.rowIndexes.map(i=>{const v=s.data[i];if(v==null||!Number.isFinite(v))return nothing;const label=this.labels[i]??"",titleText=this.resolvePointText(label,v,di,i)??this.localize("liteChartBarLabel",void 0,{series:s.label,label,value:numberFormat.format(v)}),markIndex=markIndexes.get(`${di}:${i}`),selected=selectedIndices.has(i);return svg`
|
|
88
|
-
<g class="mark-hit-group">
|
|
88
|
+
<g class="mark-hit-group" @pointermove=${()=>this.publishSyncMark({datasetIndex:di,index:i,label,value:v})}>
|
|
89
89
|
<circle
|
|
90
90
|
data-mark-hit-target="point"
|
|
91
91
|
aria-hidden="true"
|
|
@@ -113,14 +113,14 @@ import{__decorate}from"tslib";import{collectionSupport}from"../../../internal/co
|
|
|
113
113
|
@click=${event=>this.emitNearestLinePoint(event,hitPoints,di,i)}
|
|
114
114
|
@focus=${()=>this.onMarkFocus(markIndex)}
|
|
115
115
|
@keydown=${e=>this.onPointKeyDown(e,di,i,markIndex)}
|
|
116
|
-
>${nativeSvgTitle(titleText)}</circle>
|
|
116
|
+
>${typeof this.syncGroup=="string"&&this.syncGroup.trim()?nothing:nativeSvgTitle(titleText)}</circle>
|
|
117
117
|
</g>
|
|
118
118
|
`});return svg`<path
|
|
119
119
|
part="line"
|
|
120
120
|
d=${d.trim()}
|
|
121
121
|
stroke=${color}
|
|
122
122
|
stroke-dasharray=${this.markDash(di)}
|
|
123
|
-
></path>${dots}`})}render(){return this.renderChart()}resolvedValueAxisGutter(ticks,measuredWidth){if(typeof this.valueAxisGutter=="number")return finiteRange(this.valueAxisGutter,PAD_LEFT,0,MAX_SCROLL_CONTENT_WIDTH);if(this.valueAxisGutter!=="auto"||ticks.length===0)return PAD_LEFT;let widest=0;for(const tick of ticks)widest=Math.max(widest,tick.label.length*APPROX_LABEL_CHARACTER_WIDTH);const requested=Math.ceil(widest)+VALUE_AXIS_TICK_OFFSET+AUTO_VALUE_AXIS_SAFETY_INSET,maximum=this.layout==="scroll"?MAX_AUTO_VALUE_AXIS_GUTTER:Math.max(PAD_LEFT,Math.min(MAX_AUTO_VALUE_AXIS_GUTTER,measuredWidth*MAX_AUTO_VALUE_AXIS_GUTTER_FRACTION));return finiteRange(requested,PAD_LEFT,PAD_LEFT,maximum)}widestEstimatedCategoryLabel(renderedIndexes){return widestEstimatedCategoryLabel(this.labels,renderedIndexes,APPROX_LABEL_CHARACTER_WIDTH)}visibleLabelIndexes(n,plotW,renderedIndexes,tickX){if(this.maxLabels==null)return;let estimatedWidth,positions;return this.maxLabels==="auto"&&tickX&&n>1&&(estimatedWidth=this.widestEstimatedCategoryLabel(renderedIndexes),estimatedWidth>0&&(positions=renderedIndexes.map(tickX))),visibleCategoryLabelIndexes(n,plotW,renderedIndexes,this.labels,this.maxLabels,positions,CATEGORY_LABEL_SELECTION_BOUNDS,estimatedWidth)}fixedBarSlotWidth(n){const requested=typeof this.barSlotWidth=="number"?finiteNumber(this.barSlotWidth,0):0;if(requested<=0)return;const maxSlot=n>0?MAX_SCROLL_CONTENT_WIDTH/n:MAX_SCROLL_CONTENT_WIDTH;return finiteRange(requested,0,0,maxSlot)}displayCategoryLabel(label,availableWidth){const maxCharacters=Math.max(1,Math.floor(availableWidth/APPROX_LABEL_CHARACTER_WIDTH));return label.length<=maxCharacters?label:maxCharacters===1?"…":`${label.slice(0,maxCharacters-1)}…`}renderChart(){const direction=this.effectiveDirection==="rtl"?"rtl":"ltr",n=this.recordCount(),awaitingFitMeasurement=this.awaitingFitMeasurement(),h=finiteRange(this.plotHeight||200,200,0,MAX_SCROLL_CONTENT_WIDTH),measuredWidth=finiteRange(this.plotWidth||400,400,0,MAX_SCROLL_CONTENT_WIDTH),{lo,hi,ticks}=this.domain(),formattedTicks=awaitingFitMeasurement||this.withoutValueAxis?[]:ticks.map(value=>({value,label:this.formatValueAxisTick(value)})),axisGutter=this.resolvedValueAxisGutter(formattedTicks,measuredWidth)+(this.yLabel?AXIS_TITLE_SPACE:0),rtl=this.effectiveDirection==="rtl",padBottom=PAD_BOTTOM+(this.xLabel?AXIS_TITLE_SPACE:0),plotX=rtl?PAD_RIGHT:axisGutter,plotY=PAD_TOP,plotH=Math.max(0,h-plotY-padBottom);let w,plotW,slot,fixedSlot;if(this.layout==="scroll"){const maxSlot=n>0?MAX_SCROLL_CONTENT_WIDTH/n:MAX_SCROLL_CONTENT_WIDTH;slot=finiteRange(this.barWidth,32,0,maxSlot),plotW=n*slot,w=axisGutter+plotW+PAD_RIGHT}else w=measuredWidth,plotW=Math.max(0,w-axisGutter-PAD_RIGHT),fixedSlot=this.fixedBarSlotWidth(n),slot=fixedSlot??(n>0?plotW/n:0);const recordSample=this.recordSample(),selectedIndices=new Set,renderedRows=new Set(recordSample.rowIndexes);for(let index=0;index<this.selectedIndices.length;index++){const candidate=this.selectedIndices[index];typeof candidate=="number"&&Number.isInteger(candidate)&&renderedRows.has(candidate)&&selectedIndices.add(candidate)}const barOrigins=this.effectiveType==="bar"&&!awaitingFitMeasurement?new Map(recordSample.rowIndexes.map(index=>{const fallback=plotX+index*slot,candidate=typeof this.barX=="function"?this.barX(index):fallback;return[index,finiteRange(candidate,fallback,-MAX_SCROLL_CONTENT_WIDTH,MAX_SCROLL_CONTENT_WIDTH)]})):new Map,grid=awaitingFitMeasurement||this.withoutValueAxis?[]:this.renderGrid(plotX,plotY,plotW,plotH,formattedTicks,lo,hi),marks=awaitingFitMeasurement?[]:this.effectiveType==="bar"?this.renderBars(plotX,plotY,plotH,slot,lo,hi,barOrigins,recordSample,selectedIndices):this.renderLines(plotX,plotY,plotW,plotH,lo,hi,recordSample,selectedIndices),categoryLabelX=i=>this.effectiveType==="bar"&&n>0?(barOrigins.get(i)??plotX+i*slot)+slot/2:plotX+(n>1?i/(n-1)*plotW:plotW/2),visibleLabelIndexes=this.visibleLabelIndexes(n,fixedSlot===void 0||this.effectiveType!=="bar"?plotW:n*slot,recordSample.rowIndexes,categoryLabelX),tickOverrides=new Map,renderedTickIndexes=[];for(const i of recordSample.rowIndexes){if(visibleLabelIndexes&&!visibleLabelIndexes.has(i))continue;const label=this.labels[i]??"",override=this.axisLabelText?.(label,i);override!==null&&(tickOverrides.set(i,override),renderedTickIndexes.push(i))}const categoryLabelPitch=(renderedTickIndexes.length?n/renderedTickIndexes.length:1)*(this.effectiveType==="bar"?slot:n>1?plotW/(n-1):plotW),categoryLabelWidth=Math.max(0,categoryLabelPitch-BAR_CORNER_RADIUS),tickFullLabels=renderedTickIndexes.map(i=>{const override=tickOverrides.get(i);return typeof override=="string"?override:this.labels[i]??""}),tickXs=renderedTickIndexes.map(categoryLabelX),categoryLabels=awaitingFitMeasurement?[]:renderedTickIndexes.map((i,position)=>{const fullLabel=tickFullLabels[position],x=tickXs[position],growth=categoryLabelGrowth(i,n),textAnchor=growth==="middle"?"middle":growth==="right"?rtl?"end":"start":rtl?"start":"end",labelExtent=sparseCategoryLabelExtent(tickFullLabels,tickXs,position,growth,categoryLabelPitch,categoryLabelWidth,BAR_CORNER_RADIUS,MAX_SCROLL_CONTENT_WIDTH),displayLabel=this.displayCategoryLabel(fullLabel,labelExtent);return svg`<text
|
|
123
|
+
></path>${dots}`})}render(){return this.renderChart()}resolvedValueAxisGutter(ticks,measuredWidth){if(typeof this.valueAxisGutter=="number")return finiteRange(this.valueAxisGutter,PAD_LEFT,0,MAX_SCROLL_CONTENT_WIDTH);if(this.valueAxisGutter!=="auto"||ticks.length===0)return PAD_LEFT;let widest=0;for(const tick of ticks)widest=Math.max(widest,tick.label.length*APPROX_LABEL_CHARACTER_WIDTH);const requested=Math.ceil(widest)+VALUE_AXIS_TICK_OFFSET+AUTO_VALUE_AXIS_SAFETY_INSET,maximum=this.layout==="scroll"?MAX_AUTO_VALUE_AXIS_GUTTER:Math.max(PAD_LEFT,Math.min(MAX_AUTO_VALUE_AXIS_GUTTER,measuredWidth*MAX_AUTO_VALUE_AXIS_GUTTER_FRACTION));return finiteRange(requested,PAD_LEFT,PAD_LEFT,maximum)}widestEstimatedCategoryLabel(renderedIndexes){return widestEstimatedCategoryLabel(this.labels,renderedIndexes,APPROX_LABEL_CHARACTER_WIDTH)}visibleLabelIndexes(n,plotW,renderedIndexes,tickX){if(this.maxLabels==null)return;let estimatedWidth,positions;return this.maxLabels==="auto"&&tickX&&n>1&&(estimatedWidth=this.widestEstimatedCategoryLabel(renderedIndexes),estimatedWidth>0&&(positions=renderedIndexes.map(tickX))),visibleCategoryLabelIndexes(n,plotW,renderedIndexes,this.labels,this.maxLabels,positions,CATEGORY_LABEL_SELECTION_BOUNDS,estimatedWidth)}fixedBarSlotWidth(n){const requested=typeof this.barSlotWidth=="number"?finiteNumber(this.barSlotWidth,0):0;if(requested<=0)return;const maxSlot=n>0?MAX_SCROLL_CONTENT_WIDTH/n:MAX_SCROLL_CONTENT_WIDTH;return finiteRange(requested,0,0,maxSlot)}displayCategoryLabel(label,availableWidth){const maxCharacters=Math.max(1,Math.floor(availableWidth/APPROX_LABEL_CHARACTER_WIDTH));return label.length<=maxCharacters?label:maxCharacters===1?"…":`${label.slice(0,maxCharacters-1)}…`}renderChart(){const direction=this.effectiveDirection==="rtl"?"rtl":"ltr",n=this.recordCount(),awaitingFitMeasurement=this.awaitingFitMeasurement(),h=finiteRange(this.plotHeight||200,200,0,MAX_SCROLL_CONTENT_WIDTH),measuredWidth=finiteRange(this.plotWidth||400,400,0,MAX_SCROLL_CONTENT_WIDTH),{lo,hi,ticks}=this.domain(),formattedTicks=awaitingFitMeasurement||this.withoutValueAxis?[]:ticks.map(value=>({value,label:this.formatValueAxisTick(value)})),axisGutter=this.resolvedValueAxisGutter(formattedTicks,measuredWidth)+(this.yLabel?AXIS_TITLE_SPACE:0),rtl=this.effectiveDirection==="rtl",padBottom=PAD_BOTTOM+(this.xLabel?AXIS_TITLE_SPACE:0),plotX=rtl?PAD_RIGHT:axisGutter,plotY=PAD_TOP,plotH=Math.max(0,h-plotY-padBottom);this.syncPlot={y:plotY,height:plotH};let w,plotW,slot,fixedSlot;if(this.layout==="scroll"){const maxSlot=n>0?MAX_SCROLL_CONTENT_WIDTH/n:MAX_SCROLL_CONTENT_WIDTH;slot=finiteRange(this.barWidth,32,0,maxSlot),plotW=n*slot,w=axisGutter+plotW+PAD_RIGHT}else w=measuredWidth,plotW=Math.max(0,w-axisGutter-PAD_RIGHT),fixedSlot=this.fixedBarSlotWidth(n),slot=fixedSlot??(n>0?plotW/n:0);const recordSample=this.recordSample(),selectedIndices=new Set,renderedRows=new Set(recordSample.rowIndexes);for(let index=0;index<this.selectedIndices.length;index++){const candidate=this.selectedIndices[index];typeof candidate=="number"&&Number.isInteger(candidate)&&renderedRows.has(candidate)&&selectedIndices.add(candidate)}const barOrigins=this.effectiveType==="bar"&&!awaitingFitMeasurement?new Map(recordSample.rowIndexes.map(index=>{const fallback=plotX+index*slot,candidate=typeof this.barX=="function"?this.barX(index):fallback;return[index,finiteRange(candidate,fallback,-MAX_SCROLL_CONTENT_WIDTH,MAX_SCROLL_CONTENT_WIDTH)]})):new Map,grid=awaitingFitMeasurement||this.withoutValueAxis?[]:this.renderGrid(plotX,plotY,plotW,plotH,formattedTicks,lo,hi),marks=awaitingFitMeasurement?[]:this.effectiveType==="bar"?this.renderBars(plotX,plotY,plotH,slot,lo,hi,barOrigins,recordSample,selectedIndices):this.renderLines(plotX,plotY,plotW,plotH,lo,hi,recordSample,selectedIndices),categoryLabelX=i=>this.effectiveType==="bar"&&n>0?(barOrigins.get(i)??plotX+i*slot)+slot/2:plotX+(n>1?i/(n-1)*plotW:plotW/2);this.syncCategoryPositions=typeof this.syncGroup=="string"&&this.syncGroup.trim()?new Map(recordSample.rowIndexes.map(index=>[index,categoryLabelX(index)])):new Map;const visibleLabelIndexes=this.visibleLabelIndexes(n,fixedSlot===void 0||this.effectiveType!=="bar"?plotW:n*slot,recordSample.rowIndexes,categoryLabelX),tickOverrides=new Map,renderedTickIndexes=[];for(const i of recordSample.rowIndexes){if(visibleLabelIndexes&&!visibleLabelIndexes.has(i))continue;const label=this.labels[i]??"",override=this.axisLabelText?.(label,i);override!==null&&(tickOverrides.set(i,override),renderedTickIndexes.push(i))}const categoryLabelPitch=(renderedTickIndexes.length?n/renderedTickIndexes.length:1)*(this.effectiveType==="bar"?slot:n>1?plotW/(n-1):plotW),categoryLabelWidth=Math.max(0,categoryLabelPitch-BAR_CORNER_RADIUS),tickFullLabels=renderedTickIndexes.map(i=>{const override=tickOverrides.get(i);return typeof override=="string"?override:this.labels[i]??""}),tickXs=renderedTickIndexes.map(categoryLabelX),categoryLabels=awaitingFitMeasurement?[]:renderedTickIndexes.map((i,position)=>{const fullLabel=tickFullLabels[position],x=tickXs[position],growth=categoryLabelGrowth(i,n),textAnchor=growth==="middle"?"middle":growth==="right"?rtl?"end":"start":rtl?"start":"end",labelExtent=sparseCategoryLabelExtent(tickFullLabels,tickXs,position,growth,categoryLabelPitch,categoryLabelWidth,BAR_CORNER_RADIUS,MAX_SCROLL_CONTENT_WIDTH),displayLabel=this.displayCategoryLabel(fullLabel,labelExtent);return svg`<text
|
|
124
124
|
part="axis-label"
|
|
125
125
|
x=${x}
|
|
126
126
|
y=${plotY+plotH+CATEGORY_LABEL_OFFSET}
|
|
@@ -211,4 +211,4 @@ import{__decorate}from"tslib";import{collectionSupport}from"../../../internal/co
|
|
|
211
211
|
`})}
|
|
212
212
|
</div>`:nothing}
|
|
213
213
|
</div>
|
|
214
|
-
`}}__decorate([property({converter:{fromAttribute:value=>normalizeLiteChartType(value)}})],LyraLiteChart.prototype,"type",void 0),__decorate([property({attribute:!1})],LyraLiteChart.prototype,"labels",void 0),__decorate([property({attribute:!1})],LyraLiteChart.prototype,"datasets",null),__decorate([property({type:Boolean,attribute:"with-legend"})],LyraLiteChart.prototype,"withLegend",void 0),__decorate([property({attribute:"legend-position",converter:{fromAttribute:normalizeChartChromeLegendPosition}})],LyraLiteChart.prototype,"legendPosition",void 0),__decorate([property()],LyraLiteChart.prototype,"height",void 0),__decorate([property({attribute:"x-label"})],LyraLiteChart.prototype,"xLabel",void 0),__decorate([property({attribute:"y-label"})],LyraLiteChart.prototype,"yLabel",void 0),__decorate([property({type:Boolean,attribute:"without-zero-baseline"})],LyraLiteChart.prototype,"withoutZeroBaseline",void 0),__decorate([property({type:Boolean})],LyraLiteChart.prototype,"stacked",void 0),__decorate([property({attribute:!1})],LyraLiteChart.prototype,"tickFormat",void 0),__decorate([property({attribute:!1})],LyraLiteChart.prototype,"tableCellFormatter",void 0),__decorate([property({attribute:!1})],LyraLiteChart.prototype,"formatter",void 0),__decorate([property({type:Boolean,attribute:"table-totals"})],LyraLiteChart.prototype,"tableTotals",void 0),__decorate([property({type:Boolean,attribute:"with-data-table"})],LyraLiteChart.prototype,"withDataTable",void 0),__decorate([property({type:Boolean,attribute:"data-table-toggle"})],LyraLiteChart.prototype,"dataTableToggle",void 0),__decorate([state()],LyraLiteChart.prototype,"dataTableExpandedOverride",void 0),__decorate([property({reflect:!0,converter:LITE_CHART_LAYOUT})],LyraLiteChart.prototype,"layout",null),__decorate([property({type:Number,attribute:"bar-width"})],LyraLiteChart.prototype,"barWidth",void 0),__decorate([property({type:Number,attribute:"bar-slot-width"})],LyraLiteChart.prototype,"barSlotWidth",void 0),__decorate([property({converter:autoNumberConverter,attribute:"max-labels"})],LyraLiteChart.prototype,"maxLabels",void 0),__decorate([property({attribute:!1})],LyraLiteChart.prototype,"barX",void 0),__decorate([property({attribute:!1})],LyraLiteChart.prototype,"pointText",void 0),__decorate([property({attribute:!1})],LyraLiteChart.prototype,"legendText",void 0),__decorate([property({attribute:!1})],LyraLiteChart.prototype,"axisLabelText",void 0),__decorate([property({type:Boolean,attribute:"rounded-bars"})],LyraLiteChart.prototype,"roundedBars",void 0),__decorate([property({type:Boolean,attribute:"skip-zero"})],LyraLiteChart.prototype,"skipZero",void 0),__decorate([property({converter:autoNumberConverter,attribute:"value-axis-gutter"})],LyraLiteChart.prototype,"valueAxisGutter",void 0),__decorate([property({type:Number,attribute:"bar-gap-ratio"})],LyraLiteChart.prototype,"barGapRatio",void 0),__decorate([property()],LyraLiteChart.prototype,"scale",void 0),__decorate([property({type:Boolean,attribute:"without-value-axis"})],LyraLiteChart.prototype,"withoutValueAxis",void 0),__decorate([property({type:Number,attribute:"min-bar-height"})],LyraLiteChart.prototype,"minBarHeight",void 0),__decorate([property({attribute:!1})],LyraLiteChart.prototype,"selectedIndices",void 0),__decorate([property({attribute:"aria-label"})],LyraLiteChart.prototype,"hostAccessibleLabel",void 0),__decorate([property()],LyraLiteChart.prototype,"label",void 0),__decorate([property()],LyraLiteChart.prototype,"description",void 0),__decorate([state()],LyraLiteChart.prototype,"plotWidth",void 0),__decorate([state()],LyraLiteChart.prototype,"plotHeight",void 0),__decorate([state()],LyraLiteChart.prototype,"fitMeasurementAvailable",void 0),__decorate([state()],LyraLiteChart.prototype,"activeMarkIndex",void 0),__decorate([query("svg")],LyraLiteChart.prototype,"svgEl",void 0),__decorate([query("lr-live-region")],LyraLiteChart.prototype,"liveRegion",void 0);function formatTick(v,locale){return getNumberFormat(locale,{maximumFractionDigits:6}).format(Number(v.toFixed(6)))}export{LyraLiteChart};
|
|
214
|
+
`}}__decorate([property({converter:{fromAttribute:value=>normalizeLiteChartType(value)}})],LyraLiteChart.prototype,"type",void 0),__decorate([property({attribute:!1})],LyraLiteChart.prototype,"labels",void 0),__decorate([property({attribute:!1})],LyraLiteChart.prototype,"datasets",null),__decorate([property({type:Boolean,attribute:"with-legend"})],LyraLiteChart.prototype,"withLegend",void 0),__decorate([property({attribute:"legend-position",converter:{fromAttribute:normalizeChartChromeLegendPosition}})],LyraLiteChart.prototype,"legendPosition",void 0),__decorate([property()],LyraLiteChart.prototype,"height",void 0),__decorate([property({attribute:"x-label"})],LyraLiteChart.prototype,"xLabel",void 0),__decorate([property({attribute:"y-label"})],LyraLiteChart.prototype,"yLabel",void 0),__decorate([property({type:Boolean,attribute:"without-zero-baseline"})],LyraLiteChart.prototype,"withoutZeroBaseline",void 0),__decorate([property({type:Boolean})],LyraLiteChart.prototype,"stacked",void 0),__decorate([property({attribute:!1})],LyraLiteChart.prototype,"tickFormat",void 0),__decorate([property({attribute:!1})],LyraLiteChart.prototype,"tableCellFormatter",void 0),__decorate([property({attribute:!1})],LyraLiteChart.prototype,"formatter",void 0),__decorate([property({type:Boolean,attribute:"table-totals"})],LyraLiteChart.prototype,"tableTotals",void 0),__decorate([property({type:Boolean,attribute:"with-data-table"})],LyraLiteChart.prototype,"withDataTable",void 0),__decorate([property({type:Boolean,attribute:"data-table-toggle"})],LyraLiteChart.prototype,"dataTableToggle",void 0),__decorate([state()],LyraLiteChart.prototype,"dataTableExpandedOverride",void 0),__decorate([property({reflect:!0,converter:LITE_CHART_LAYOUT})],LyraLiteChart.prototype,"layout",null),__decorate([property({type:Number,attribute:"bar-width"})],LyraLiteChart.prototype,"barWidth",void 0),__decorate([property({type:Number,attribute:"bar-slot-width"})],LyraLiteChart.prototype,"barSlotWidth",void 0),__decorate([property({converter:autoNumberConverter,attribute:"max-labels"})],LyraLiteChart.prototype,"maxLabels",void 0),__decorate([property({attribute:!1})],LyraLiteChart.prototype,"barX",void 0),__decorate([property({attribute:!1})],LyraLiteChart.prototype,"pointText",void 0),__decorate([property({attribute:!1})],LyraLiteChart.prototype,"legendText",void 0),__decorate([property({attribute:!1})],LyraLiteChart.prototype,"axisLabelText",void 0),__decorate([property({type:Boolean,attribute:"rounded-bars"})],LyraLiteChart.prototype,"roundedBars",void 0),__decorate([property({type:Boolean,attribute:"skip-zero"})],LyraLiteChart.prototype,"skipZero",void 0),__decorate([property({converter:autoNumberConverter,attribute:"value-axis-gutter"})],LyraLiteChart.prototype,"valueAxisGutter",void 0),__decorate([property({type:Number,attribute:"bar-gap-ratio"})],LyraLiteChart.prototype,"barGapRatio",void 0),__decorate([property()],LyraLiteChart.prototype,"scale",void 0),__decorate([property({type:Boolean,attribute:"without-value-axis"})],LyraLiteChart.prototype,"withoutValueAxis",void 0),__decorate([property({type:Number,attribute:"min-bar-height"})],LyraLiteChart.prototype,"minBarHeight",void 0),__decorate([property({attribute:!1})],LyraLiteChart.prototype,"selectedIndices",void 0),__decorate([property({attribute:"aria-label"})],LyraLiteChart.prototype,"hostAccessibleLabel",void 0),__decorate([property()],LyraLiteChart.prototype,"label",void 0),__decorate([property()],LyraLiteChart.prototype,"description",void 0),__decorate([state()],LyraLiteChart.prototype,"plotWidth",void 0),__decorate([state()],LyraLiteChart.prototype,"plotHeight",void 0),__decorate([state()],LyraLiteChart.prototype,"fitMeasurementAvailable",void 0),__decorate([state()],LyraLiteChart.prototype,"activeMarkIndex",void 0),__decorate([query("svg")],LyraLiteChart.prototype,"svgEl",void 0),__decorate([query("lr-live-region")],LyraLiteChart.prototype,"liveRegion",void 0),__decorate([property({attribute:"sync-group"})],LyraLiteChart.prototype,"syncGroup",void 0);function formatTick(v,locale){return getNumberFormat(locale,{maximumFractionDigits:6}).format(Number(v.toFixed(6)))}export{LyraLiteChart};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type{CalendarCell}from'./calendar-grid.js';export interface MatrixGridPosition{row:number;col:number;}export interface CalendarGridPosition{week:number;weekday:number;date:string;}export interface MatrixNavigationGeometry{readonly rows:number;readonly cols:number;readonly padLeft:number;readonly padTop:number;readonly cellSize:number;readonly cellWidth:number;readonly cellHeight:number;readonly customShape:boolean;}export interface CalendarNavigationGeometry{readonly weekCount:number;readonly cellSize:number;readonly padLeft:number;readonly padTop:number;
|
|
1
|
+
import type{CalendarCell}from'./calendar-grid.js';export interface MatrixGridPosition{row:number;col:number;}export interface CalendarGridPosition{week:number;weekday:number;date:string;}export interface MatrixNavigationGeometry{readonly rows:number;readonly cols:number;readonly padLeft:number;readonly padTop:number;readonly cellSize:number;readonly rowHeight?:number;readonly cellWidth:number;readonly cellHeight:number;readonly customShape:boolean;}export interface CalendarNavigationGeometry{readonly weekCount:number;readonly cellSize:number;readonly padLeft:number;readonly padTop:number;
|
|
2
2
|
/** Existing validated/cache-owned positions; callers must not copy these per interaction. */
|
|
3
3
|
readonly columnPositions:readonly number[];
|
|
4
4
|
/** Existing validated/cache-owned positions; callers must not copy these per interaction. */
|
|
5
|
-
readonly rowPositions:readonly number[];}export interface PaintedMatrixCellGeometry{readonly padLeft:number;readonly padTop:number;readonly cellSize:number;readonly cellWidth?:number;readonly cellHeight?:number;}export interface CellRect{x:number;y:number;w:number;h:number;}
|
|
5
|
+
readonly rowPositions:readonly number[];}export interface PaintedMatrixCellGeometry{readonly padLeft:number;readonly padTop:number;readonly cellSize:number;readonly rowHeight?:number;readonly cellWidth?:number;readonly cellHeight?:number;}export interface CellRect{x:number;y:number;w:number;h:number;}
|
|
6
6
|
/** Canvas-local matrix hit test against the same resolved geometry used by drawing. */
|
|
7
7
|
export declare function hitTestMatrix(x:number,y:number,geometry:MatrixNavigationGeometry,isInteractive:(position:MatrixGridPosition)=>boolean):MatrixGridPosition|null;export declare function firstInteractiveMatrixCell(rows:number,cols:number,isInteractive:(position:MatrixGridPosition)=>boolean):MatrixGridPosition|null;export declare function nextInteractiveMatrixCell(row:number,col:number,dRow:number,dCol:number,rows:number,cols:number,isInteractive:(position:MatrixGridPosition)=>boolean):MatrixGridPosition;export declare function hitTestCalendar(x:number,y:number,weekCount:number,columnPositions:readonly number[],cellSize:()=>number,rowPositions:()=>readonly number[],positionAt:(week:number,weekday:number)=>CalendarGridPosition,isInteractive:(position:CalendarGridPosition)=>boolean):CalendarGridPosition|null;export declare function firstInteractiveCalendarCell(weekCount:number,positionAt:(week:number,weekday:number)=>CalendarGridPosition,isInteractive:(position:CalendarGridPosition)=>boolean):CalendarGridPosition|null;export declare function nextInteractiveCalendarCell(week:number,weekday:number,dWeek:number,dWeekday:number,weekCount:number,positionAt:(week:number,weekday:number)=>CalendarGridPosition,isInteractive:(position:CalendarGridPosition)=>boolean):CalendarGridPosition;export declare function calendarDateAt(week:number,weekday:number,datesByPosition:readonly string[],firstWeekStart:Date):string;export declare function calendarCellAt(week:number,weekday:number,cellsByPosition:ReadonlyMap<string,CalendarCell>,datesByPosition:readonly string[],firstWeekStart:Date,signedDomain:boolean):{date:string;value:number;};export declare function calendarValueAt(week:number,weekday:number,cellsByPosition:ReadonlyMap<string,CalendarCell>,signedDomain:boolean):number;export declare function matrixCellRect(position:MatrixGridPosition,geometry:MatrixNavigationGeometry):CellRect;export declare function calendarCellRect(week:number,weekday:number,geometry:CalendarNavigationGeometry):CellRect;export declare function accessibleMatrixCellRect(position:MatrixGridPosition,painted:PaintedMatrixCellGeometry):CellRect;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const MS_PER_DAY=864e5;function hitTestMatrix(x,y,geometry,isInteractive){const{rows,cols,cellSize,padLeft,padTop}=geometry;if(rows===0||cols===0)return null;const col=Math.floor((x-padLeft)/cellSize),row=Math.floor((y-padTop)/cellSize);if(row<0||row>=rows||col<0||col>=cols||geometry.customShape&&(x-padLeft-col*cellSize>=geometry.cellWidth||y-padTop-row*cellSize>=geometry.cellHeight))return null;const position={row,col};return isInteractive(position)?position:null}function firstInteractiveMatrixCell(rows,cols,isInteractive){for(let row=0;row<rows;row++)for(let col=0;col<cols;col++){const position={row,col};if(isInteractive(position))return position}return null}function nextInteractiveMatrixCell(row,col,dRow,dCol,rows,cols,isInteractive){let nextRow=row,nextCol=col;for(;;){const candidateRow=Math.min(rows-1,Math.max(0,nextRow+dRow)),candidateCol=Math.min(cols-1,Math.max(0,nextCol+dCol));if(candidateRow===nextRow&&candidateCol===nextCol)return{row,col};nextRow=candidateRow,nextCol=candidateCol;const position={row:nextRow,col:nextCol};if(isInteractive(position))return position}}function hitTestCalendar(x,y,weekCount,columnPositions,cellSize,rowPositions,positionAt,isInteractive){if(weekCount===0)return null;const resolvedCellSize=cellSize();let week=null;for(let index=0;index<weekCount;index++){const start=columnPositions[index];if(x>=start&&x<start+resolvedCellSize){week=index;break}}if(week===null)return null;const resolvedRows=rowPositions(),resolvedRowCellSize=cellSize();let weekday=null;for(let index=0;index<7;index++){const start=resolvedRows[index];if(y>=start&&y<start+resolvedRowCellSize){weekday=index;break}}if(weekday===null)return null;const position=positionAt(week,weekday);return isInteractive(position)?position:null}function firstInteractiveCalendarCell(weekCount,positionAt,isInteractive){for(let week=0;week<weekCount;week++)for(let weekday=0;weekday<7;weekday++){const position=positionAt(week,weekday);if(isInteractive(position))return position}return null}function nextInteractiveCalendarCell(week,weekday,dWeek,dWeekday,weekCount,positionAt,isInteractive){let nextWeek=week,nextWeekday=weekday;for(;;){const candidateWeek=Math.min(weekCount-1,Math.max(0,nextWeek+dWeek)),candidateWeekday=Math.min(6,Math.max(0,nextWeekday+dWeekday));if(candidateWeek===nextWeek&&candidateWeekday===nextWeekday)return positionAt(week,weekday);nextWeek=candidateWeek,nextWeekday=candidateWeekday;const position=positionAt(nextWeek,nextWeekday);if(isInteractive(position))return position}}function calendarDateAt(week,weekday,datesByPosition,firstWeekStart){const index=week*7+weekday;return datesByPosition[index]??new Date(firstWeekStart.getTime()+index*864e5).toISOString().slice(0,10)}function calendarCellAt(week,weekday,cellsByPosition,datesByPosition,firstWeekStart,signedDomain){const cell=cellsByPosition.get(`${week}:${weekday}`);return cell?{date:cell.date,value:cell.value}:{date:calendarDateAt(week,weekday,datesByPosition,firstWeekStart),value:signedDomain?Number.NaN:-1}}function calendarValueAt(week,weekday,cellsByPosition,signedDomain){const cell=cellsByPosition.get(`${week}:${weekday}`);return cell?cell.value:signedDomain?Number.NaN:-1}function matrixCellRect(position,geometry){return{x:geometry.padLeft+position.col*geometry.cellSize,y:geometry.padTop+position.row*geometry.cellSize,w:geometry.cellWidth,h:geometry.cellHeight}}function calendarCellRect(week,weekday,geometry){return{x:geometry.columnPositions[week]??geometry.padLeft,y:geometry.rowPositions[weekday]??geometry.padTop,w:geometry.cellSize,h:geometry.cellSize}}function accessibleMatrixCellRect(position,painted){return{x:painted.padLeft+position.col*painted.cellSize,y:painted.padTop+position.row*painted.cellSize,w:painted.cellWidth??painted.cellSize-1,h:painted.cellHeight??painted.cellSize-1}}export{accessibleMatrixCellRect,calendarCellAt,calendarCellRect,calendarDateAt,calendarValueAt,firstInteractiveCalendarCell,firstInteractiveMatrixCell,hitTestCalendar,hitTestMatrix,matrixCellRect,nextInteractiveCalendarCell,nextInteractiveMatrixCell};
|
|
1
|
+
const MS_PER_DAY=864e5;function hitTestMatrix(x,y,geometry,isInteractive){const{rows,cols,cellSize,padLeft,padTop}=geometry;if(rows===0||cols===0)return null;const col=Math.floor((x-padLeft)/cellSize),row=Math.floor((y-padTop)/(geometry.rowHeight??cellSize));if(row<0||row>=rows||col<0||col>=cols||geometry.customShape&&(x-padLeft-col*cellSize>=geometry.cellWidth||y-padTop-row*(geometry.rowHeight??cellSize)>=geometry.cellHeight))return null;const position={row,col};return isInteractive(position)?position:null}function firstInteractiveMatrixCell(rows,cols,isInteractive){for(let row=0;row<rows;row++)for(let col=0;col<cols;col++){const position={row,col};if(isInteractive(position))return position}return null}function nextInteractiveMatrixCell(row,col,dRow,dCol,rows,cols,isInteractive){let nextRow=row,nextCol=col;for(;;){const candidateRow=Math.min(rows-1,Math.max(0,nextRow+dRow)),candidateCol=Math.min(cols-1,Math.max(0,nextCol+dCol));if(candidateRow===nextRow&&candidateCol===nextCol)return{row,col};nextRow=candidateRow,nextCol=candidateCol;const position={row:nextRow,col:nextCol};if(isInteractive(position))return position}}function hitTestCalendar(x,y,weekCount,columnPositions,cellSize,rowPositions,positionAt,isInteractive){if(weekCount===0)return null;const resolvedCellSize=cellSize();let week=null;for(let index=0;index<weekCount;index++){const start=columnPositions[index];if(x>=start&&x<start+resolvedCellSize){week=index;break}}if(week===null)return null;const resolvedRows=rowPositions(),resolvedRowCellSize=cellSize();let weekday=null;for(let index=0;index<7;index++){const start=resolvedRows[index];if(y>=start&&y<start+resolvedRowCellSize){weekday=index;break}}if(weekday===null)return null;const position=positionAt(week,weekday);return isInteractive(position)?position:null}function firstInteractiveCalendarCell(weekCount,positionAt,isInteractive){for(let week=0;week<weekCount;week++)for(let weekday=0;weekday<7;weekday++){const position=positionAt(week,weekday);if(isInteractive(position))return position}return null}function nextInteractiveCalendarCell(week,weekday,dWeek,dWeekday,weekCount,positionAt,isInteractive){let nextWeek=week,nextWeekday=weekday;for(;;){const candidateWeek=Math.min(weekCount-1,Math.max(0,nextWeek+dWeek)),candidateWeekday=Math.min(6,Math.max(0,nextWeekday+dWeekday));if(candidateWeek===nextWeek&&candidateWeekday===nextWeekday)return positionAt(week,weekday);nextWeek=candidateWeek,nextWeekday=candidateWeekday;const position=positionAt(nextWeek,nextWeekday);if(isInteractive(position))return position}}function calendarDateAt(week,weekday,datesByPosition,firstWeekStart){const index=week*7+weekday;return datesByPosition[index]??new Date(firstWeekStart.getTime()+index*864e5).toISOString().slice(0,10)}function calendarCellAt(week,weekday,cellsByPosition,datesByPosition,firstWeekStart,signedDomain){const cell=cellsByPosition.get(`${week}:${weekday}`);return cell?{date:cell.date,value:cell.value}:{date:calendarDateAt(week,weekday,datesByPosition,firstWeekStart),value:signedDomain?Number.NaN:-1}}function calendarValueAt(week,weekday,cellsByPosition,signedDomain){const cell=cellsByPosition.get(`${week}:${weekday}`);return cell?cell.value:signedDomain?Number.NaN:-1}function matrixCellRect(position,geometry){return{x:geometry.padLeft+position.col*geometry.cellSize,y:geometry.padTop+position.row*(geometry.rowHeight??geometry.cellSize),w:geometry.cellWidth,h:geometry.cellHeight}}function calendarCellRect(week,weekday,geometry){return{x:geometry.columnPositions[week]??geometry.padLeft,y:geometry.rowPositions[weekday]??geometry.padTop,w:geometry.cellSize,h:geometry.cellSize}}function accessibleMatrixCellRect(position,painted){return{x:painted.padLeft+position.col*painted.cellSize,y:painted.padTop+position.row*(painted.rowHeight??painted.cellSize),w:painted.cellWidth??painted.cellSize-1,h:painted.cellHeight??painted.cellSize-1}}export{accessibleMatrixCellRect,calendarCellAt,calendarCellRect,calendarDateAt,calendarValueAt,firstInteractiveCalendarCell,firstInteractiveMatrixCell,hitTestCalendar,hitTestMatrix,matrixCellRect,nextInteractiveCalendarCell,nextInteractiveMatrixCell};
|
|
@@ -127,7 +127,9 @@ export declare function normalizeBucketCount(bucketCount:number):number;
|
|
|
127
127
|
* silently drawing the wrong color.
|
|
128
128
|
*/
|
|
129
129
|
export declare function resolveRgb(color:string,fallbackHex:string,ownerDocument?:Document):[number,number,number,number];export type LyraHeatmapCellClickDetail={date:string;value:number;}|{row:number;col:number;value:number;};export type LyraHeatmapMatrixGeometryChangeDetail={padLeft:number;padTop:number;cellSize:number;
|
|
130
|
-
/**
|
|
130
|
+
/** Vertical row pitch; omitted when it equals the horizontal cellSize. */
|
|
131
|
+
rowHeight?:number;
|
|
132
|
+
/** Custom painted bounds; present for rectangular rows or custom gaps/corners, omitted for default square cells. */
|
|
131
133
|
cellWidth?:number;cellHeight?:number;cellRadius?:number;};
|
|
132
134
|
/**
|
|
133
135
|
* The painted calendar-mode geometry `LyraHeatmap.calendarGeometry` reports, in CSS pixels.
|
|
@@ -168,7 +170,9 @@ export type LyraHeatmapExportFormat='csv'|'png';
|
|
|
168
170
|
* narrow one cannot collapse into hairlines. Both are ignored while
|
|
169
171
|
* `fitToWidth` is unset (an explicit `cellSize` is an exact request), and the
|
|
170
172
|
* canvas is sized from the *clamped* size — a capped grid leaves the host's
|
|
171
|
-
* remaining width unfilled rather than stretching to it.
|
|
173
|
+
* remaining width unfilled rather than stretching to it. Matrix-only `rowHeight` independently
|
|
174
|
+
* sets vertical row pitch, including the trailing separator, while columns retain the fit-derived
|
|
175
|
+
* size. Unset preserves square geometry; calendar mode ignores it.
|
|
172
176
|
*
|
|
173
177
|
* The sequential color ramp's endpoints are read from the
|
|
174
178
|
* `--lr-heatmap-scale-lo`/`-hi` custom properties (declared in
|
|
@@ -282,7 +286,7 @@ export type LyraHeatmapExportFormat='csv'|'png';
|
|
|
282
286
|
* wording that is not represented by the locale catalog.
|
|
283
287
|
* `cellColor` overrides a cell's ramp-computed color entirely for an exact value.
|
|
284
288
|
* @event lr-matrix-geometry-change - Fired after a matrix-mode draw pass whose resolved
|
|
285
|
-
* `matrixGeometry` (`padLeft`/`padTop`/`cellSize`) differs from the previous draw -- e.g. after
|
|
289
|
+
* `matrixGeometry` (`padLeft`/`padTop`/`cellSize`/optional `rowHeight`) differs from the previous draw -- e.g. after
|
|
286
290
|
* `row-label-width="auto"`/`col-label-height="auto"` resolves against new label content or a
|
|
287
291
|
* resize. `detail` is the same object `matrixGeometry` returns. Never fired in calendar mode.
|
|
288
292
|
* @event lr-calendar-geometry-change - Fired after a calendar-mode draw pass whose resolved
|
|
@@ -435,7 +439,8 @@ private resolvedRowLabelWidth;private get matrixPadLeft();
|
|
|
435
439
|
/**
|
|
436
440
|
* The gutter/cell geometry the last matrix-mode draw actually painted with --
|
|
437
441
|
* `{ padLeft, padTop, cellSize }`, all in CSS pixels. Custom gaps/radius additionally report
|
|
438
|
-
* `cellWidth`, `cellHeight`, and `cellRadius`;
|
|
442
|
+
* `cellWidth`, `cellHeight`, and `cellRadius`; rectangular rows also report `rowHeight`.
|
|
443
|
+
* The vertical pitch is `rowHeight ?? cellSize`; square default cells omit these fields. This lets a light-DOM consumer
|
|
439
444
|
* (e.g. a sticky header mirror) line up with the canvas without hardcoding the same numbers `row-label-width`
|
|
440
445
|
* or `col-label-height`'s `"auto"` resolution would otherwise keep private. `undefined` in
|
|
441
446
|
* calendar mode, and before the first matrix draw.
|
|
@@ -520,7 +525,14 @@ private measureCalendarWeekdayLabelWidth;private get matrixRowLabels();private g
|
|
|
520
525
|
* never touches `cellSize` sees no change in either mode. Set explicitly
|
|
521
526
|
* (attribute or property), the same value governs both modes alike.
|
|
522
527
|
*/
|
|
523
|
-
get cellSize():number;set cellSize(value:number|undefined|null);
|
|
528
|
+
get cellSize():number;set cellSize(value:number|undefined|null);private _rowHeight?;
|
|
529
|
+
/** Matrix-only vertical row pitch in CSS pixels, including the trailing cellGapY separator.
|
|
530
|
+
* Unset, removed, null, undefined, or non-finite values restore square rows from the effective
|
|
531
|
+
* cellSize. Finite values clamp between one and 4096 to bound numeric outliers. fitToWidth and its min/maxCellSize clamps keep
|
|
532
|
+
* governing column pitch independently. Calendar mode ignores this setting.
|
|
533
|
+
* With accessibleCells, each axis independently honors the minimum accessible target, which
|
|
534
|
+
* can make dense columns overflow their allocation. */
|
|
535
|
+
get rowHeight():number|undefined;set rowHeight(value:number|undefined|null);
|
|
524
536
|
/** Legend caption. Unset uses the localized default; every supplied string is literal. */
|
|
525
537
|
valueLabel?:string;
|
|
526
538
|
/**
|
|
@@ -548,13 +560,13 @@ withoutLegend:boolean;
|
|
|
548
560
|
* rest of a skewed dataset.
|
|
549
561
|
*/
|
|
550
562
|
scale:HeatmapScale;
|
|
551
|
-
/** Trailing horizontal separator in CSS pixels. In matrix mode it is subtracted from the
|
|
552
|
-
* cell pitch, clamped between zero and
|
|
563
|
+
/** Trailing horizontal separator in CSS pixels. In matrix mode it is subtracted from the
|
|
564
|
+
* horizontal cell pitch, clamped between zero and the horizontal pitch minus one; non-finite values use the default.
|
|
553
565
|
* In calendar mode it is opt-in: only an explicitly set value (property or attribute) replaces
|
|
554
566
|
* the calendar's original 2px spacing between week columns, adding to the column pitch with the
|
|
555
567
|
* same bounds; a non-finite value, or removing the attribute, restores the original spacing. */
|
|
556
568
|
cellGapX:number;
|
|
557
|
-
/** Trailing vertical separator in CSS pixels,
|
|
569
|
+
/** Trailing vertical separator in CSS pixels, bounded by the vertical row pitch minus one. In calendar mode
|
|
558
570
|
* an explicitly set value replaces the original 2px spacing between weekday rows. */
|
|
559
571
|
cellGapY:number;
|
|
560
572
|
/** Painted corner radius in CSS pixels, clamped to half the smaller painted side. Does not change
|
|
@@ -1001,7 +1013,10 @@ private paintCalendarAxisLabels;private drawCalendar;
|
|
|
1001
1013
|
* below (`hitTestMatrix()`, `cellRect()`) so they always agree on exactly
|
|
1002
1014
|
* the same geometry as what's actually painted.
|
|
1003
1015
|
*/
|
|
1004
|
-
private matrixCellSize;
|
|
1016
|
+
private matrixCellSize;
|
|
1017
|
+
/** Vertical pitch shares the square default, but independently preserves accessible targets
|
|
1018
|
+
* when an explicit rowHeight is supplied. Keep the existing square accessibility path intact. */
|
|
1019
|
+
private matrixRowHeight;private matrixCellShape;
|
|
1005
1020
|
/** Calendar ring clip shape: `undefined` (square, the original path) unless an explicit
|
|
1006
1021
|
* `cellRadius` resolved above zero. */
|
|
1007
1022
|
private calendarCellShape;private fillMatrixCell;private paintMatrixCell;private paintMatrixFocusOverlays;private focusRepaintBounds;private repaintMatrixFocusCell;private paintCalendarCell;
|