@opendata-ai/openchart-engine 7.10.0 → 7.11.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/dist/index.d.ts +20 -1
- package/dist/index.js +26 -11
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/dimensions.test.ts +49 -4
- package/src/__tests__/legend.test.ts +51 -0
- package/src/compile.ts +5 -0
- package/src/index.ts +8 -0
- package/src/layout/dimensions.ts +39 -12
- package/src/layout/plan.ts +3 -2
- package/src/legend/compute.ts +7 -1
- package/src/legend/wrap.ts +8 -0
package/dist/index.d.ts
CHANGED
|
@@ -658,6 +658,25 @@ declare function getChartRenderer(type: string): ChartRenderer | undefined;
|
|
|
658
658
|
*/
|
|
659
659
|
declare function clearRenderers(): void;
|
|
660
660
|
|
|
661
|
+
/**
|
|
662
|
+
* Legend row-wrap geometry.
|
|
663
|
+
*
|
|
664
|
+
* Shared helper for measuring how legend entries flow across horizontal rows
|
|
665
|
+
* when wrapped at a max width. Both the main legend compute and the sankey
|
|
666
|
+
* legend compile use this to size their legends — the main legend uses
|
|
667
|
+
* `fittingCount` for truncation decisions, while sankey uses `rowCount` to
|
|
668
|
+
* reserve vertical height.
|
|
669
|
+
*
|
|
670
|
+
* The geometry matches the existing layout exactly: each entry occupies
|
|
671
|
+
* SWATCH_SIZE + SWATCH_GAP + labelWidth + ENTRY_GAP pixels, a new row is
|
|
672
|
+
* started when the accumulated row width plus the next entry would exceed
|
|
673
|
+
* maxWidth (and the current row is non-empty), and rowWidths captures the
|
|
674
|
+
* in-row accumulated width at the point of wrapping.
|
|
675
|
+
*/
|
|
676
|
+
|
|
677
|
+
/** Gap between legend and chart area, responsive to container width. */
|
|
678
|
+
declare function legendGap(width: number): number;
|
|
679
|
+
|
|
661
680
|
/**
|
|
662
681
|
* Bin transform: discretizes a continuous field into bins.
|
|
663
682
|
*
|
|
@@ -792,4 +811,4 @@ declare function runTimeUnit(data: DataRow[], transform: TimeUnitTransform): Dat
|
|
|
792
811
|
*/
|
|
793
812
|
declare function runTransforms(data: DataRow[], transforms: Transform[]): DataRow[];
|
|
794
813
|
|
|
795
|
-
export { type AnnotationContext, type AnnotationMeasureTextFn, type ChartRenderer, type CompileResult, type CompiledGraphEdge, type CompiledGraphNode, ENTER_DEFAULTS, EXIT_DEFAULTS, type GraphCompilation, type NormalizedBarListSpec, type NormalizedChartSpec, type NormalizedChrome, type NormalizedGraphSpec, type NormalizedSankeySpec, type NormalizedSpec, type NormalizedTableSpec, type NormalizedTileMapSpec, type ObstacleKind, type PlacementObstacle, type SimulationConfig, UPDATE_DEFAULTS, type ValidationError, type ValidationErrorCode, type ValidationResult, buildAreaPath, buildLinePath, clampStaggerDelay, clearRenderers, compile, compileBarList, compileChart, compileGraph, compileLayer, compileSankey, compileTable, compileTileMap, dedupeKeys, evaluatePredicate, getChartRenderer, heuristicMeasure, isConditionalValueDef, normalizeSpec, registerChartRenderer, resolveAnimation, resolveConditionalValue, runBin, runCalculate, runFilter, runTimeUnit, runTransforms, serializeKeyValue, validateSpec };
|
|
814
|
+
export { type AnnotationContext, type AnnotationMeasureTextFn, type ChartRenderer, type CompileResult, type CompiledGraphEdge, type CompiledGraphNode, ENTER_DEFAULTS, EXIT_DEFAULTS, type GraphCompilation, type NormalizedBarListSpec, type NormalizedChartSpec, type NormalizedChrome, type NormalizedGraphSpec, type NormalizedSankeySpec, type NormalizedSpec, type NormalizedTableSpec, type NormalizedTileMapSpec, type ObstacleKind, type PlacementObstacle, type SimulationConfig, UPDATE_DEFAULTS, type ValidationError, type ValidationErrorCode, type ValidationResult, buildAreaPath, buildLinePath, clampStaggerDelay, clearRenderers, compile, compileBarList, compileChart, compileGraph, compileLayer, compileSankey, compileTable, compileTileMap, dedupeKeys, evaluatePredicate, getChartRenderer, heuristicMeasure, isConditionalValueDef, legendGap, normalizeSpec, registerChartRenderer, resolveAnimation, resolveConditionalValue, runBin, runCalculate, runFilter, runTimeUnit, runTransforms, serializeKeyValue, validateSpec };
|
package/dist/index.js
CHANGED
|
@@ -10153,6 +10153,7 @@ var SWATCH_GAP = 6;
|
|
|
10153
10153
|
var ENTRY_GAP = 16;
|
|
10154
10154
|
var ENTRY_GAP_COMPACT = 10;
|
|
10155
10155
|
var LEGEND_GAP = 8;
|
|
10156
|
+
var TOP_LEGEND_GAP_ABOVE = 6;
|
|
10156
10157
|
function legendGap(width) {
|
|
10157
10158
|
return width < COMPACT_WIDTH ? 0 : LEGEND_GAP;
|
|
10158
10159
|
}
|
|
@@ -10449,7 +10450,7 @@ function computeLegendContent(spec, strategy, theme, availableWidth, availableHe
|
|
|
10449
10450
|
rowHeight
|
|
10450
10451
|
};
|
|
10451
10452
|
}
|
|
10452
|
-
function placeLegend(content, chartArea, containerWidth, _theme, xAxisHeight) {
|
|
10453
|
+
function placeLegend(content, chartArea, containerWidth, _theme, xAxisHeight, axisGapBelowLegend = 0) {
|
|
10453
10454
|
const { position, entries, labelStyle, legendWidth, height, offset } = content;
|
|
10454
10455
|
if (entries.length === 0) {
|
|
10455
10456
|
return {
|
|
@@ -10477,7 +10478,7 @@ function placeLegend(content, chartArea, containerWidth, _theme, xAxisHeight) {
|
|
|
10477
10478
|
boundsY = chartArea.y + chartArea.height + xAxisHeight + gap + offsetDy;
|
|
10478
10479
|
} else {
|
|
10479
10480
|
boundsX = chartArea.x + offsetDx;
|
|
10480
|
-
boundsY = chartArea.y - gap - height + offsetDy;
|
|
10481
|
+
boundsY = chartArea.y - axisGapBelowLegend - gap - height + offsetDy;
|
|
10481
10482
|
}
|
|
10482
10483
|
const bounds = { x: boundsX, y: boundsY, width: legendWidth, height };
|
|
10483
10484
|
const entryPositions = resolveEntryPositions(content.relativePositions, bounds);
|
|
@@ -11815,7 +11816,7 @@ function resolveLayoutPlan(chartSpec, renderSpec, options, theme, strategy, wate
|
|
|
11815
11816
|
const topAxisGap = axisMargin + inlineTickOverhang;
|
|
11816
11817
|
const effectiveTopAxisGap = hasTopLegend ? inlineTickOverhang : topAxisGap;
|
|
11817
11818
|
let topMargin = topPad + chrome.topHeight;
|
|
11818
|
-
if (hasTopLegend) topMargin += legendContent.height + gap;
|
|
11819
|
+
if (hasTopLegend) topMargin += TOP_LEGEND_GAP_ABOVE + legendContent.height + gap;
|
|
11819
11820
|
topMargin += effectiveTopAxisGap;
|
|
11820
11821
|
const bMargin = bottomMargin(chrome.bottomHeight, padding, xAxisExtent);
|
|
11821
11822
|
const chartHeight = Math.max(0, height - topMargin - bMargin);
|
|
@@ -12969,7 +12970,15 @@ function computeDimensions(spec, options, legendLayout, theme, strategy, waterma
|
|
|
12969
12970
|
width: Math.max(0, width - margins2.left - margins2.right),
|
|
12970
12971
|
height: Math.max(0, height - margins2.top - margins2.bottom)
|
|
12971
12972
|
};
|
|
12972
|
-
return {
|
|
12973
|
+
return {
|
|
12974
|
+
total: total2,
|
|
12975
|
+
chrome,
|
|
12976
|
+
chartArea: chartArea2,
|
|
12977
|
+
margins: margins2,
|
|
12978
|
+
theme,
|
|
12979
|
+
xAxisHeight: xAxisSpace,
|
|
12980
|
+
effectiveAxisGap: 0
|
|
12981
|
+
};
|
|
12973
12982
|
}
|
|
12974
12983
|
const total = { x: 0, y: 0, width, height };
|
|
12975
12984
|
const isRadial = spec.markType === "arc";
|
|
@@ -13205,10 +13214,11 @@ function computeDimensions(spec, options, legendLayout, theme, strategy, waterma
|
|
|
13205
13214
|
if (legendPos === "right" || legendPos === "bottom-right") {
|
|
13206
13215
|
margins.right += legendBoundsWidth + 8;
|
|
13207
13216
|
} else if (legendPos === "top") {
|
|
13208
|
-
margins.top += legendHeight + gap;
|
|
13217
|
+
margins.top += TOP_LEGEND_GAP_ABOVE + legendHeight + gap;
|
|
13209
13218
|
}
|
|
13210
13219
|
}
|
|
13211
|
-
|
|
13220
|
+
const effectiveAxisGap = hasTopLegend ? inlineTickOverhang : topAxisGap;
|
|
13221
|
+
margins.top += effectiveAxisGap;
|
|
13212
13222
|
let chartArea = {
|
|
13213
13223
|
x: margins.left,
|
|
13214
13224
|
y: margins.top,
|
|
@@ -13236,7 +13246,7 @@ function computeDimensions(spec, options, legendLayout, theme, strategy, waterma
|
|
|
13236
13246
|
const bottomDelta = margins.bottom - newBottom;
|
|
13237
13247
|
if (topDelta > 0 || bottomDelta > 0) {
|
|
13238
13248
|
const gap = legendGap(width);
|
|
13239
|
-
margins.top = newTop + (hasTopLegend ? legendHeight + gap : 0) + fallbackEffectiveAxisGap;
|
|
13249
|
+
margins.top = newTop + (hasTopLegend ? TOP_LEGEND_GAP_ABOVE + legendHeight + gap : 0) + fallbackEffectiveAxisGap;
|
|
13240
13250
|
margins.bottom = newBottom;
|
|
13241
13251
|
chartArea = {
|
|
13242
13252
|
x: margins.left,
|
|
@@ -13269,7 +13279,8 @@ function computeDimensions(spec, options, legendLayout, theme, strategy, waterma
|
|
|
13269
13279
|
margins,
|
|
13270
13280
|
theme,
|
|
13271
13281
|
metrics: fallbackMetrics,
|
|
13272
|
-
xAxisHeight
|
|
13282
|
+
xAxisHeight,
|
|
13283
|
+
effectiveAxisGap: fallbackEffectiveAxisGap
|
|
13273
13284
|
};
|
|
13274
13285
|
}
|
|
13275
13286
|
}
|
|
@@ -13291,7 +13302,8 @@ function computeDimensions(spec, options, legendLayout, theme, strategy, waterma
|
|
|
13291
13302
|
margins,
|
|
13292
13303
|
theme,
|
|
13293
13304
|
metrics: resolvedMetrics,
|
|
13294
|
-
xAxisHeight
|
|
13305
|
+
xAxisHeight,
|
|
13306
|
+
effectiveAxisGap
|
|
13295
13307
|
};
|
|
13296
13308
|
}
|
|
13297
13309
|
function resolveMetrics(spec, metricsTopY, metricsArea, remainingChartHeight, measureText, theme) {
|
|
@@ -16466,7 +16478,8 @@ function compileChart(spec, options) {
|
|
|
16466
16478
|
chartArea,
|
|
16467
16479
|
options.width,
|
|
16468
16480
|
theme,
|
|
16469
|
-
plan.xAxisExtent
|
|
16481
|
+
plan.xAxisExtent,
|
|
16482
|
+
dims.effectiveAxisGap
|
|
16470
16483
|
);
|
|
16471
16484
|
let scaleArea = chartArea;
|
|
16472
16485
|
if (plan.inlineYLabelInset > 0 && plan.inlineYLabelInset < chartArea.width) {
|
|
@@ -16640,7 +16653,8 @@ function compileFaceted(chartSpec, renderSpec, facetChannel, options, theme, str
|
|
|
16640
16653
|
chartArea,
|
|
16641
16654
|
options.width,
|
|
16642
16655
|
theme,
|
|
16643
|
-
plan.xAxisExtent
|
|
16656
|
+
plan.xAxisExtent,
|
|
16657
|
+
dims.effectiveAxisGap
|
|
16644
16658
|
);
|
|
16645
16659
|
const leftReservation = plan.leftGutter;
|
|
16646
16660
|
const bottomReservation = plan.xAxisExtent;
|
|
@@ -16839,6 +16853,7 @@ export {
|
|
|
16839
16853
|
getChartRenderer,
|
|
16840
16854
|
heuristicMeasure,
|
|
16841
16855
|
isConditionalValueDef,
|
|
16856
|
+
legendGap,
|
|
16842
16857
|
normalizeSpec,
|
|
16843
16858
|
registerChartRenderer,
|
|
16844
16859
|
resolveAnimation,
|