@adaptabletools/adaptable 23.0.0-canary.7 → 23.0.0-canary.8
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/index.css +75 -9
- package/package.json +1 -1
- package/src/AdaptableState/StyledColumnState.d.ts +8 -850
- package/src/AdaptableState/StyledColumnState.js +1 -9
- package/src/AdaptableState/StyledColumns/BadgeStyle.d.ts +143 -0
- package/src/AdaptableState/StyledColumns/BadgeStyle.js +9 -0
- package/src/AdaptableState/StyledColumns/BulletChartStyle.d.ts +147 -0
- package/src/AdaptableState/StyledColumns/BulletChartStyle.js +1 -0
- package/src/AdaptableState/StyledColumns/Common/BarChartCellText.d.ts +60 -0
- package/src/AdaptableState/StyledColumns/Common/BarChartCellText.js +6 -0
- package/src/AdaptableState/StyledColumns/Common/BarChartMarker.d.ts +24 -0
- package/src/AdaptableState/StyledColumns/Common/BarChartMarker.js +5 -0
- package/src/AdaptableState/StyledColumns/Common/CellTextOptions.d.ts +13 -0
- package/src/AdaptableState/StyledColumns/Common/CellTextOptions.js +6 -0
- package/src/AdaptableState/StyledColumns/Common/NumericStyledColumn.d.ts +79 -0
- package/src/AdaptableState/StyledColumns/Common/NumericStyledColumn.js +9 -0
- package/src/AdaptableState/StyledColumns/GradientStyle.d.ts +48 -0
- package/src/AdaptableState/StyledColumns/GradientStyle.js +1 -0
- package/src/AdaptableState/StyledColumns/IconStyle.d.ts +158 -0
- package/src/AdaptableState/StyledColumns/IconStyle.js +1 -0
- package/src/AdaptableState/StyledColumns/PercentBarStyle.d.ts +32 -0
- package/src/AdaptableState/StyledColumns/PercentBarStyle.js +1 -0
- package/src/AdaptableState/StyledColumns/RangeBarStyle.d.ts +155 -0
- package/src/AdaptableState/StyledColumns/RangeBarStyle.js +1 -0
- package/src/AdaptableState/StyledColumns/RatingStyle.d.ts +111 -0
- package/src/AdaptableState/StyledColumns/RatingStyle.js +1 -0
- package/src/AdaptableState/StyledColumns/SparklineStyle.d.ts +21 -0
- package/src/AdaptableState/StyledColumns/SparklineStyle.js +1 -0
- package/src/Api/ColumnScopeApi.d.ts +1 -1
- package/src/Api/Implementation/ColumnScopeApiImpl.d.ts +1 -1
- package/src/Api/Internal/StyledColumnInternalApi.d.ts +3 -1
- package/src/Utilities/Helpers/IconStylePresets.d.ts +1 -1
- package/src/Utilities/Helpers/StyledColumnGradientHelper.d.ts +3 -1
- package/src/Utilities/Helpers/barChartCellText.d.ts +63 -0
- package/src/Utilities/Helpers/barChartCellText.js +316 -0
- package/src/Utilities/Helpers/percentBarPreviewHelper.d.ts +2 -1
- package/src/Utilities/Helpers/percentBarPreviewHelper.js +3 -8
- package/src/View/Alert/Wizard/AlertButtonsEditor.js +159 -126
- package/src/View/Alert/Wizard/AlertNotificationWizardSection.js +1 -1
- package/src/View/Alert/Wizard/AlertWizard.js +9 -1
- package/src/View/Components/AdaptableObjectList/AdaptableObjectCompactList.js +3 -2
- package/src/View/Components/AdaptableObjectList/AdaptableObjectList.js +3 -2
- package/src/View/Components/AdaptableObjectList/objectListActionButtonStyles.d.ts +2 -0
- package/src/View/Components/AdaptableObjectList/objectListActionButtonStyles.js +2 -0
- package/src/View/Components/Buttons/EntityListActionButtons.js +1 -1
- package/src/View/Components/Buttons/SuspendToggleButton/SuspendToggleButton.d.ts +1 -0
- package/src/View/Components/Buttons/SuspendToggleButton/SuspendToggleButton.js +8 -8
- package/src/View/Components/ColumnFilter/ColumnFilter.js +14 -1
- package/src/View/Components/Popups/AdaptablePopup/AdaptablePopupModuleView.js +1 -1
- package/src/View/Components/RangesComponent.d.ts +2 -1
- package/src/View/Export/ExportSchedulesTab.js +3 -4
- package/src/View/Filter/FilterViewPanel.js +1 -1
- package/src/View/Layout/Wizard/sections/RowSummarySection.js +129 -103
- package/src/View/StyledColumn/Wizard/BadgePillStyleEditor.d.ts +1 -1
- package/src/View/StyledColumn/Wizard/StyledColumnBadgeSection.js +36 -30
- package/src/View/StyledColumn/Wizard/StyledColumnSliceStyleEditors.d.ts +1 -3
- package/src/View/StyledColumn/Wizard/StyledColumnWizardBulletSection.js +73 -58
- package/src/View/StyledColumn/Wizard/StyledColumnWizardIconSection.js +38 -11
- package/src/View/StyledColumn/Wizard/StyledColumnWizardRangeBarSection.js +86 -44
- package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/BarChartCellTextLayoutEditor.d.ts +9 -0
- package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/BarChartCellTextLayoutEditor.js +35 -0
- package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/BarChartCellTextPreview.d.ts +23 -0
- package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/BarChartCellTextPreview.js +57 -0
- package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/BulletRangesSummaryPreview.d.ts +1 -1
- package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/GradientSummaryPreview.d.ts +2 -1
- package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/RangeBarRangesSummaryPreview.d.ts +1 -1
- package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/StyledColumnBadgePreview.js +3 -2
- package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/StyledColumnBulletPreview.d.ts +2 -1
- package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/StyledColumnBulletPreview.js +13 -17
- package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/StyledColumnChartListPreviews.d.ts +2 -1
- package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/StyledColumnChartListPreviews.js +5 -5
- package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/StyledColumnIconPreview.js +2 -2
- package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/StyledColumnPercentBarPreview.js +14 -7
- package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/StyledColumnRangeBarPreview.js +11 -17
- package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/StyledColumnRatingPreview.d.ts +2 -1
- package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/StyledColumnWizardStyleSection.js +18 -54
- package/src/agGrid/AgGridColumnAdapter.js +2 -1
- package/src/agGrid/cellRenderers/BadgeRenderer.js +7 -5
- package/src/agGrid/cellRenderers/BulletChartRenderer.js +43 -42
- package/src/agGrid/cellRenderers/IconRenderer.d.ts +2 -1
- package/src/agGrid/cellRenderers/IconRenderer.js +13 -11
- package/src/agGrid/cellRenderers/PercentBarRenderer.js +24 -96
- package/src/agGrid/cellRenderers/RangeBarRenderer.js +49 -46
- package/src/env.js +2 -2
- package/src/metamodel/adaptable.metamodel.d.ts +80 -14
- package/src/metamodel/adaptable.metamodel.js +1 -1
- package/src/migration/VersionUpgrade23.d.ts +27 -31
- package/src/migration/VersionUpgrade23.js +110 -29
- package/src/types.d.ts +12 -1
- package/tsconfig.esm.tsbuildinfo +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import Helper from '../../Utilities/Helpers/Helper';
|
|
2
2
|
import clamp from '../../Utilities/utils/clamp';
|
|
3
|
+
import { buildBarChartCellTextLabels, hasBarChartCellTextConfigured, mountBarChartCellText, } from '../../Utilities/Helpers/barChartCellText';
|
|
3
4
|
import { shouldRenderStyledColumnOnRow } from './shouldRenderStyledColumnOnRow';
|
|
4
5
|
const SVG_NS = 'http://www.w3.org/2000/svg';
|
|
5
6
|
const DEFAULT_BAR_HEIGHT = 8;
|
|
@@ -52,19 +53,18 @@ const normaliseMarker = (override, base) => {
|
|
|
52
53
|
};
|
|
53
54
|
};
|
|
54
55
|
const resolveTargets = (bulletStyle, styledColumn, abColumn, rowNode, api) => {
|
|
55
|
-
|
|
56
|
+
const targetSpec = bulletStyle.TargetProperties?.Target;
|
|
57
|
+
if (targetSpec == undefined) {
|
|
56
58
|
return [];
|
|
57
59
|
}
|
|
58
|
-
const targets = Array.isArray(
|
|
59
|
-
? bulletStyle.Target
|
|
60
|
-
: [bulletStyle.Target];
|
|
60
|
+
const targets = Array.isArray(targetSpec) ? targetSpec : [targetSpec];
|
|
61
61
|
const resolved = [];
|
|
62
62
|
for (const target of targets) {
|
|
63
63
|
const value = resolveTargetValue(target, styledColumn, abColumn, rowNode, api);
|
|
64
64
|
if (value == undefined || isNaN(value)) {
|
|
65
65
|
continue;
|
|
66
66
|
}
|
|
67
|
-
const marker = normaliseMarker(isTargetDefinition(target) ? target.Marker : undefined, bulletStyle.
|
|
67
|
+
const marker = normaliseMarker(isTargetDefinition(target) ? target.Marker : undefined, bulletStyle.TargetProperties?.Marker);
|
|
68
68
|
resolved.push({
|
|
69
69
|
value,
|
|
70
70
|
marker,
|
|
@@ -152,10 +152,10 @@ export const getBulletChartRendererForColumn = (styledColumn, abColumn, api) =>
|
|
|
152
152
|
// `BarThickness` is the bar's *short* axis (height in horizontal,
|
|
153
153
|
// width in vertical). `BandThickness` is the matching short-axis
|
|
154
154
|
// size of the surrounding bands.
|
|
155
|
-
const barThickness = bulletStyle.
|
|
155
|
+
const barThickness = bulletStyle.Bar?.Height ?? DEFAULT_BAR_HEIGHT;
|
|
156
156
|
const bandThickness = Math.max(barThickness + 6, DEFAULT_BAND_HEIGHT);
|
|
157
|
-
const
|
|
158
|
-
const
|
|
157
|
+
const cellTextProperties = bulletStyle.CellTextProperties;
|
|
158
|
+
const hasCellText = hasBarChartCellTextConfigured(cellTextProperties);
|
|
159
159
|
// Map a 0..1 value fraction onto the long-axis viewBox (0..100).
|
|
160
160
|
// In horizontal: 0 -> left, 1 -> right.
|
|
161
161
|
// In vertical: 0 -> bottom, 1 -> top (SVG y origin is at the top so
|
|
@@ -172,7 +172,7 @@ export const getBulletChartRendererForColumn = (styledColumn, abColumn, api) =>
|
|
|
172
172
|
this.eGui.style.alignItems = isVertical ? 'center' : 'stretch';
|
|
173
173
|
this.eGui.style.justifyContent = 'center';
|
|
174
174
|
this.eGui.style.position = 'relative';
|
|
175
|
-
this.eGui.style.height =
|
|
175
|
+
this.eGui.style.height = '100%';
|
|
176
176
|
// SVG chart - we let `preserveAspectRatio="none"` stretch the long axis
|
|
177
177
|
// (viewBox 0..100) to fill the cell while the short axis stays fixed
|
|
178
178
|
// in pixels.
|
|
@@ -243,7 +243,7 @@ export const getBulletChartRendererForColumn = (styledColumn, abColumn, api) =>
|
|
|
243
243
|
const barCrossOffset = (bandThickness - barThickness) / 2;
|
|
244
244
|
const bar = document.createElementNS(SVG_NS, 'rect');
|
|
245
245
|
setRectAxes(bar, Math.min(valueCoord, originCoord), Math.abs(valueCoord - originCoord), barCrossOffset, barThickness);
|
|
246
|
-
bar.setAttribute('fill', bulletStyle.
|
|
246
|
+
bar.setAttribute('fill', bulletStyle.Bar?.Color ?? DEFAULT_BAR_COLOR);
|
|
247
247
|
bar.setAttribute('class', 'ab-BulletChart__bar');
|
|
248
248
|
svg.appendChild(bar);
|
|
249
249
|
// Target markers
|
|
@@ -255,39 +255,40 @@ export const getBulletChartRendererForColumn = (styledColumn, abColumn, api) =>
|
|
|
255
255
|
svg.appendChild(marker);
|
|
256
256
|
}
|
|
257
257
|
}
|
|
258
|
-
|
|
258
|
+
// Wrap the SVG in a positioned container so a `Merged` text row can
|
|
259
|
+
// be absolute-positioned to the centre of the *bar* (matching Percent
|
|
260
|
+
// Bar's behaviour) instead of falling through to the wrapper centre,
|
|
261
|
+
// which would otherwise overlap an `Above` / `Below` band.
|
|
262
|
+
const svgContainer = document.createElement('div');
|
|
263
|
+
svgContainer.style.position = 'relative';
|
|
264
|
+
svgContainer.style.display = 'flex';
|
|
265
|
+
svgContainer.style.alignItems = 'center';
|
|
266
|
+
svgContainer.style.justifyContent = 'center';
|
|
267
|
+
// Horizontal: take the SVG's natural (bandThickness) height.
|
|
268
|
+
// Vertical: stretch to fill the wrapper so the SVG's `height: 100%`
|
|
269
|
+
// resolves against a real size.
|
|
270
|
+
if (isVertical) {
|
|
271
|
+
svgContainer.style.flex = '1 1 auto';
|
|
272
|
+
svgContainer.style.minHeight = '0';
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
svgContainer.style.flex = '0 0 auto';
|
|
276
|
+
}
|
|
277
|
+
svgContainer.appendChild(svg);
|
|
278
|
+
this.eGui.appendChild(svgContainer);
|
|
259
279
|
if (hasCellText) {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
const
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
case 'Above':
|
|
273
|
-
this.eGui.prepend(textEl);
|
|
274
|
-
break;
|
|
275
|
-
case 'Merged':
|
|
276
|
-
textEl.style.position = 'absolute';
|
|
277
|
-
textEl.style.top = '50%';
|
|
278
|
-
textEl.style.transform = 'translateY(-50%)';
|
|
279
|
-
textEl.style.left = '0';
|
|
280
|
-
textEl.style.right = '0';
|
|
281
|
-
textEl.style.paddingLeft = '5px';
|
|
282
|
-
textEl.style.paddingRight = '5px';
|
|
283
|
-
textEl.style.pointerEvents = 'none';
|
|
284
|
-
this.eGui.appendChild(textEl);
|
|
285
|
-
break;
|
|
286
|
-
case 'Below':
|
|
287
|
-
default:
|
|
288
|
-
this.eGui.appendChild(textEl);
|
|
289
|
-
break;
|
|
290
|
-
}
|
|
280
|
+
// See PercentBarRenderer: `params.formatValue` on a column without a
|
|
281
|
+
// `valueFormatter` returns the raw value (a number here), so coerce
|
|
282
|
+
// to string before it flows into the helpers.
|
|
283
|
+
const formattedCellValue = String(params.formatValue?.(cellValue) ?? cellValue);
|
|
284
|
+
const labels = buildBarChartCellTextLabels(cellTextProperties, formattedCellValue, `${(valueFraction * 100).toFixed(0)}%`);
|
|
285
|
+
mountBarChartCellText({
|
|
286
|
+
wrapperEl: this.eGui,
|
|
287
|
+
mergedOverlayEl: svgContainer,
|
|
288
|
+
textClassName: 'ab-BulletChart__text',
|
|
289
|
+
cellTextProperties,
|
|
290
|
+
labels,
|
|
291
|
+
});
|
|
291
292
|
}
|
|
292
293
|
}
|
|
293
294
|
getGui() {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { StyledColumn } from '../../AdaptableState/StyledColumnState';
|
|
2
|
+
import { IconStyle, IconStyleMapping } from '../../AdaptableState/StyledColumns/IconStyle';
|
|
2
3
|
import { AdaptableApi } from '../../Api/AdaptableApi';
|
|
3
4
|
import { AdaptableColumn } from '../../AdaptableState/Common/AdaptableColumn';
|
|
4
5
|
/**
|
|
@@ -193,7 +193,9 @@ export const getIconRendererForColumn = (styledColumn, abColumn, api) => {
|
|
|
193
193
|
const iconStyle = styledColumn.IconStyle;
|
|
194
194
|
const size = iconStyle.Size ?? DEFAULT_SIZE;
|
|
195
195
|
const gap = iconStyle.Gap ?? DEFAULT_GAP;
|
|
196
|
-
const
|
|
196
|
+
const cellTextProperties = iconStyle.CellTextProperties;
|
|
197
|
+
const textPosition = cellTextProperties?.CellTextPosition ?? 'After';
|
|
198
|
+
const cellTextTokens = cellTextProperties?.CellText ?? [];
|
|
197
199
|
const matchMode = iconStyle.MatchMode ?? 'Exact';
|
|
198
200
|
// Resolve once at column-setup time. Cheap; recomputed when the column
|
|
199
201
|
// is reconfigured (which is when this factory is re-invoked anyway).
|
|
@@ -230,16 +232,15 @@ export const getIconRendererForColumn = (styledColumn, abColumn, api) => {
|
|
|
230
232
|
const formatted = params.formatValue?.(cellValue) ??
|
|
231
233
|
(cellValue != undefined ? String(cellValue) : '');
|
|
232
234
|
// `CellText` describes the *companion text alongside a matched icon*.
|
|
233
|
-
// `
|
|
234
|
-
// independent: when there is no match,
|
|
235
|
-
// — `CellText` does not get to override `
|
|
235
|
+
// `FallbackProperties.Mode` describes *what to do when no mapping matches*.
|
|
236
|
+
// They are independent: when there is no match, the fallback decides
|
|
237
|
+
// on its own — `CellText` does not get to override `Mode: 'Hide'`.
|
|
236
238
|
let iconSpec;
|
|
237
239
|
let text;
|
|
238
240
|
let descriptionForTooltip;
|
|
239
241
|
if (matched) {
|
|
240
242
|
iconSpec = matched.Icon;
|
|
241
243
|
descriptionForTooltip = matched.Description;
|
|
242
|
-
const cellTextTokens = iconStyle.CellText ?? [];
|
|
243
244
|
const textParts = [];
|
|
244
245
|
if (cellTextTokens.includes('CellValue') && formatted) {
|
|
245
246
|
textParts.push(formatted);
|
|
@@ -250,17 +251,18 @@ export const getIconRendererForColumn = (styledColumn, abColumn, api) => {
|
|
|
250
251
|
text = textParts.length > 0 ? textParts.join(' · ') : undefined;
|
|
251
252
|
}
|
|
252
253
|
else if (!cellValueIsEmpty) {
|
|
253
|
-
// Unmatched, non-empty cell: defer entirely to
|
|
254
|
-
const
|
|
255
|
-
|
|
254
|
+
// Unmatched, non-empty cell: defer entirely to the fallback config.
|
|
255
|
+
const fallbackMode = iconStyle.FallbackProperties?.Mode ?? 'Hide';
|
|
256
|
+
const fallbackIcon = iconStyle.FallbackProperties?.Icon;
|
|
257
|
+
if (fallbackMode === 'ShowText') {
|
|
256
258
|
text = formatted || undefined;
|
|
257
259
|
}
|
|
258
|
-
else if (
|
|
259
|
-
iconSpec =
|
|
260
|
+
else if (fallbackMode === 'Icon' && fallbackIcon) {
|
|
261
|
+
iconSpec = fallbackIcon;
|
|
260
262
|
}
|
|
261
263
|
// 'Hide' (and the unsupported permutations) render nothing.
|
|
262
264
|
}
|
|
263
|
-
// else: empty cell → render nothing, regardless of
|
|
265
|
+
// else: empty cell → render nothing, regardless of fallback config.
|
|
264
266
|
// If we have nothing to draw, leave the cell empty (and skip mounting
|
|
265
267
|
// a React root for this row).
|
|
266
268
|
if (!iconSpec && !text) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import Helper from '../../Utilities/Helpers/Helper';
|
|
2
2
|
import clamp from '../../Utilities/utils/clamp';
|
|
3
3
|
import { shouldRenderStyledColumnOnRow } from './shouldRenderStyledColumnOnRow';
|
|
4
|
+
import { buildBarChartCellTextLabels, hasBarChartCellTextConfigured, mountBarChartCellText, } from '../../Utilities/Helpers/barChartCellText';
|
|
4
5
|
/**
|
|
5
6
|
* Resolve the origin value (in the same numeric space as `min`/`max`) the bar
|
|
6
7
|
* should grow from.
|
|
@@ -41,58 +42,6 @@ const columnComparisonUsesCentredAxis = (origin) => {
|
|
|
41
42
|
}
|
|
42
43
|
return o === 'Zero' || o === 'Auto';
|
|
43
44
|
};
|
|
44
|
-
/**
|
|
45
|
-
* Linear (non-comparison) mode: bar grows from an interior point of the scale
|
|
46
|
-
* (so positives / negatives can diverge left and right).
|
|
47
|
-
*/
|
|
48
|
-
const linearScaleUsesCentredAxis = (percentBarStyle, cellValue, min, max) => {
|
|
49
|
-
const origin = percentBarStyle.Origin ?? 'Auto';
|
|
50
|
-
if (origin === 'Zero') {
|
|
51
|
-
return true;
|
|
52
|
-
}
|
|
53
|
-
if (origin === 'Min') {
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
if (typeof origin === 'number') {
|
|
57
|
-
if (max === min) {
|
|
58
|
-
return false;
|
|
59
|
-
}
|
|
60
|
-
const f = toFraction(origin, min, max);
|
|
61
|
-
return f > 0 && f < 1;
|
|
62
|
-
}
|
|
63
|
-
// Auto — same condition as resolveOrigin using 0 as the pivot.
|
|
64
|
-
return min < 0 || max < 0 || cellValue < 0;
|
|
65
|
-
};
|
|
66
|
-
const resolveCellTextAlignCss = (percentBarStyle, args) => {
|
|
67
|
-
const mode = percentBarStyle.CellTextAlignment;
|
|
68
|
-
if (mode == undefined) {
|
|
69
|
-
return undefined;
|
|
70
|
-
}
|
|
71
|
-
if (mode === 'Left') {
|
|
72
|
-
return 'left';
|
|
73
|
-
}
|
|
74
|
-
if (mode === 'Right') {
|
|
75
|
-
return 'right';
|
|
76
|
-
}
|
|
77
|
-
if (mode === 'Center') {
|
|
78
|
-
return 'center';
|
|
79
|
-
}
|
|
80
|
-
// Auto
|
|
81
|
-
const centred = args.hasColumnComparison
|
|
82
|
-
? columnComparisonUsesCentredAxis(percentBarStyle.Origin)
|
|
83
|
-
: linearScaleUsesCentredAxis(percentBarStyle, args.numericValue, args.min, args.max);
|
|
84
|
-
if (!centred) {
|
|
85
|
-
return undefined;
|
|
86
|
-
}
|
|
87
|
-
const v = args.hasColumnComparison ? args.percentageValue : args.numericValue;
|
|
88
|
-
if (v > 0) {
|
|
89
|
-
return 'right';
|
|
90
|
-
}
|
|
91
|
-
if (v < 0) {
|
|
92
|
-
return 'left';
|
|
93
|
-
}
|
|
94
|
-
return 'center';
|
|
95
|
-
};
|
|
96
45
|
export const getPercentBarRendererForColumn = (styledColumn, abColumn, api) => {
|
|
97
46
|
if (!styledColumn.PercentBarStyle) {
|
|
98
47
|
return;
|
|
@@ -191,11 +140,14 @@ export const getPercentBarRendererForColumn = (styledColumn, abColumn, api) => {
|
|
|
191
140
|
}
|
|
192
141
|
}
|
|
193
142
|
// ----- Build the DOM -------------------------------------------------
|
|
194
|
-
const
|
|
195
|
-
const
|
|
143
|
+
const cellTextProperties = percentBarStyle.CellTextProperties;
|
|
144
|
+
const hasCellText = hasBarChartCellTextConfigured(cellTextProperties);
|
|
145
|
+
// Wrapper always fills the cell. The bar is the flex-grow child so it
|
|
146
|
+
// claims whatever space the (compact) text rows leave, with a small
|
|
147
|
+
// floor to stay visible even on short rows.
|
|
196
148
|
this.eGui = document.createElement('div');
|
|
197
149
|
this.eGui.className = 'ab-PercentBar__wrapper';
|
|
198
|
-
this.eGui.style.height =
|
|
150
|
+
this.eGui.style.height = '100%';
|
|
199
151
|
this.eGui.style.display = 'flex';
|
|
200
152
|
this.eGui.style.flexDirection = 'column';
|
|
201
153
|
this.eGui.style.justifyContent = 'center';
|
|
@@ -208,7 +160,10 @@ export const getPercentBarRendererForColumn = (styledColumn, abColumn, api) => {
|
|
|
208
160
|
if (percentBarStyle.BackColor) {
|
|
209
161
|
barEl.style.background = percentBarStyle.BackColor;
|
|
210
162
|
}
|
|
211
|
-
barEl.style.flex = '1';
|
|
163
|
+
barEl.style.flex = '1 1 0';
|
|
164
|
+
// Floor so the bar can't be squeezed out of existence when both
|
|
165
|
+
// `Above` and `Below` bands are populated on a short row.
|
|
166
|
+
barEl.style.minHeight = '6px';
|
|
212
167
|
// Render the inside bar whenever a colour has been resolved, even at
|
|
213
168
|
// 0% width. A zero-width div is visually identical to skipping the
|
|
214
169
|
// element but keeps the DOM consistent so tests / tooling can still
|
|
@@ -229,47 +184,20 @@ export const getPercentBarRendererForColumn = (styledColumn, abColumn, api) => {
|
|
|
229
184
|
}
|
|
230
185
|
this.eGui.append(barEl);
|
|
231
186
|
if (hasCellText) {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
percentageValue,
|
|
246
|
-
min,
|
|
247
|
-
max,
|
|
248
|
-
hasColumnComparison: !!percentBarStyle.ColumnComparison,
|
|
187
|
+
// Coerce to string: when no `valueFormatter` is set on the column,
|
|
188
|
+
// `params.formatValue` returns the raw value (a number for numeric
|
|
189
|
+
// columns), which then propagates through the helpers as a non-string
|
|
190
|
+
// and breaks string-only operations (e.g. `.length` checks).
|
|
191
|
+
const formattedCellValue = String(params.formatValue?.(rawCellValue) ?? rawCellValue);
|
|
192
|
+
const labels = buildBarChartCellTextLabels(cellTextProperties, formattedCellValue, `${percentageValue.toFixed(0)}%`);
|
|
193
|
+
mountBarChartCellText({
|
|
194
|
+
wrapperEl: this.eGui,
|
|
195
|
+
mergedOverlayEl: barEl,
|
|
196
|
+
textClassName: 'ab-PercentBar__text',
|
|
197
|
+
cellTextProperties,
|
|
198
|
+
labels,
|
|
199
|
+
mergedPointerEventsNone: false,
|
|
249
200
|
});
|
|
250
|
-
if (textAlignCss) {
|
|
251
|
-
textEl.style.textAlign = textAlignCss;
|
|
252
|
-
}
|
|
253
|
-
switch (percentBarStyle.CellTextPosition) {
|
|
254
|
-
case 'Above':
|
|
255
|
-
this.eGui.prepend(textEl);
|
|
256
|
-
break;
|
|
257
|
-
case 'Merged':
|
|
258
|
-
textEl.style.position = 'absolute';
|
|
259
|
-
// Centre vertically without knowing the row height
|
|
260
|
-
textEl.style.top = '50%';
|
|
261
|
-
textEl.style.transform = 'translateY(-50%)';
|
|
262
|
-
textEl.style.left = '0';
|
|
263
|
-
textEl.style.right = '0';
|
|
264
|
-
textEl.style.paddingLeft = '5px';
|
|
265
|
-
textEl.style.paddingRight = '5px';
|
|
266
|
-
barEl.append(textEl);
|
|
267
|
-
break;
|
|
268
|
-
case 'Below':
|
|
269
|
-
default:
|
|
270
|
-
this.eGui.append(textEl);
|
|
271
|
-
break;
|
|
272
|
-
}
|
|
273
201
|
}
|
|
274
202
|
}
|
|
275
203
|
getGui() {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import Helper from '../../Utilities/Helpers/Helper';
|
|
2
2
|
import clamp from '../../Utilities/utils/clamp';
|
|
3
|
+
import { buildBarChartCellTextLabels, hasBarChartCellTextConfigured, mountBarChartCellText, } from '../../Utilities/Helpers/barChartCellText';
|
|
3
4
|
import { shouldRenderStyledColumnOnRow } from './shouldRenderStyledColumnOnRow';
|
|
4
5
|
const SVG_NS = 'http://www.w3.org/2000/svg';
|
|
5
6
|
const DEFAULT_TRACK_HEIGHT = 4;
|
|
@@ -96,8 +97,9 @@ export const getRangeBarRendererForColumn = (styledColumn, abColumn, api) => {
|
|
|
96
97
|
this.eGui.append(params.formatValue?.(rawCellValue) ?? String(rawCellValue));
|
|
97
98
|
return;
|
|
98
99
|
}
|
|
99
|
-
const
|
|
100
|
-
|
|
100
|
+
const referenceProperties = rangeStyle.Reference;
|
|
101
|
+
const referenceValue = referenceProperties?.Value != undefined
|
|
102
|
+
? resolveBoundValue(referenceProperties.Value, abColumn, params.node, api)
|
|
101
103
|
: undefined;
|
|
102
104
|
// Markers - resolve user overrides against per-marker defaults.
|
|
103
105
|
const valueMarker = normaliseMarker(rangeStyle.Marker, {
|
|
@@ -105,21 +107,24 @@ export const getRangeBarRendererForColumn = (styledColumn, abColumn, api) => {
|
|
|
105
107
|
Color: DEFAULT_VALUE_MARKER_COLOR,
|
|
106
108
|
Size: DEFAULT_VALUE_MARKER_SIZE,
|
|
107
109
|
});
|
|
108
|
-
const referenceMarker = normaliseMarker(
|
|
110
|
+
const referenceMarker = normaliseMarker(referenceProperties?.Marker, {
|
|
109
111
|
Shape: 'Line',
|
|
110
112
|
Color: DEFAULT_REFERENCE_MARKER_COLOR,
|
|
111
113
|
Size: DEFAULT_LINE_MARKER_THICKNESS,
|
|
112
114
|
});
|
|
113
115
|
// Out-of-range handling
|
|
114
|
-
const
|
|
116
|
+
const outOfRangeProperties = rangeStyle.OutOfRange;
|
|
117
|
+
const outOfRangeMode = outOfRangeProperties?.Mode ?? 'Clamp';
|
|
118
|
+
const outOfRangeColor = outOfRangeProperties?.Color;
|
|
115
119
|
const isOutOfRange = numericValue < min || numericValue > max;
|
|
116
120
|
const hideValueMarker = isOutOfRange && outOfRangeMode === 'Hide';
|
|
117
121
|
// Layout
|
|
118
122
|
const isVertical = rangeStyle.Orientation === 'Vertical';
|
|
119
|
-
const
|
|
123
|
+
const trackProperties = rangeStyle.Track;
|
|
124
|
+
const trackThickness = trackProperties?.Height ?? DEFAULT_TRACK_HEIGHT;
|
|
120
125
|
const bandThickness = Math.max(trackThickness + 6, DEFAULT_BAND_HEIGHT);
|
|
121
|
-
const
|
|
122
|
-
const
|
|
126
|
+
const cellTextProperties = rangeStyle.CellTextProperties;
|
|
127
|
+
const hasCellText = hasBarChartCellTextConfigured(cellTextProperties);
|
|
123
128
|
// Map a 0..1 fraction onto the long-axis viewBox (0..100). Vertical
|
|
124
129
|
// orientation inverts so that lower values appear at the bottom of
|
|
125
130
|
// the cell, matching user expectation.
|
|
@@ -132,7 +137,7 @@ export const getRangeBarRendererForColumn = (styledColumn, abColumn, api) => {
|
|
|
132
137
|
this.eGui.style.alignItems = isVertical ? 'center' : 'stretch';
|
|
133
138
|
this.eGui.style.justifyContent = 'center';
|
|
134
139
|
this.eGui.style.position = 'relative';
|
|
135
|
-
this.eGui.style.height =
|
|
140
|
+
this.eGui.style.height = '100%';
|
|
136
141
|
const svg = document.createElementNS(SVG_NS, 'svg');
|
|
137
142
|
svg.setAttribute('class', 'ab-RangeBar__svg');
|
|
138
143
|
svg.setAttribute('preserveAspectRatio', 'none');
|
|
@@ -191,11 +196,11 @@ export const getRangeBarRendererForColumn = (styledColumn, abColumn, api) => {
|
|
|
191
196
|
const trackCrossOffset = (bandThickness - trackThickness) / 2;
|
|
192
197
|
const track = document.createElementNS(SVG_NS, 'rect');
|
|
193
198
|
setRectAxes(track, 0, 100, trackCrossOffset, trackThickness);
|
|
194
|
-
track.setAttribute('fill',
|
|
199
|
+
track.setAttribute('fill', trackProperties?.Color ?? DEFAULT_TRACK_COLOR);
|
|
195
200
|
track.setAttribute('class', 'ab-RangeBar__track');
|
|
196
201
|
// Slight transparency by default so the track doesn't drown out the
|
|
197
|
-
// band colours; honour explicit user
|
|
198
|
-
if (
|
|
202
|
+
// band colours; honour explicit user Track.Color as-is.
|
|
203
|
+
if (trackProperties?.Color == undefined) {
|
|
199
204
|
// With no bands the cell background is often plain — the same muted
|
|
200
205
|
// foreground at 0.35 opacity can disappear (only the accent marker reads).
|
|
201
206
|
// Bands provide contrast underneath, so keep the subtle blend there.
|
|
@@ -224,8 +229,8 @@ export const getRangeBarRendererForColumn = (styledColumn, abColumn, api) => {
|
|
|
224
229
|
valueFraction = toFraction(numericValue, min, max);
|
|
225
230
|
}
|
|
226
231
|
const valueCoord = valueAxisCoord(valueFraction);
|
|
227
|
-
const effectiveMarker = isOutOfRange && outOfRangeMode === 'Clamp' &&
|
|
228
|
-
? { ...valueMarker, Color:
|
|
232
|
+
const effectiveMarker = isOutOfRange && outOfRangeMode === 'Clamp' && outOfRangeColor
|
|
233
|
+
? { ...valueMarker, Color: outOfRangeColor }
|
|
229
234
|
: valueMarker;
|
|
230
235
|
const markerEl = createMarkerElement(effectiveMarker, valueCoord, bandThickness, isVertical);
|
|
231
236
|
if (markerEl) {
|
|
@@ -233,40 +238,38 @@ export const getRangeBarRendererForColumn = (styledColumn, abColumn, api) => {
|
|
|
233
238
|
svg.appendChild(markerEl);
|
|
234
239
|
}
|
|
235
240
|
}
|
|
236
|
-
|
|
241
|
+
// Wrap the SVG in a positioned container so a `Merged` text row sits
|
|
242
|
+
// centred on the *bar*, not on the cell — see BulletChartRenderer for
|
|
243
|
+
// the same fix and Percent Bar for the matching behaviour via its
|
|
244
|
+
// `barEl`.
|
|
245
|
+
const svgContainer = document.createElement('div');
|
|
246
|
+
svgContainer.style.position = 'relative';
|
|
247
|
+
svgContainer.style.display = 'flex';
|
|
248
|
+
svgContainer.style.alignItems = 'center';
|
|
249
|
+
svgContainer.style.justifyContent = 'center';
|
|
250
|
+
if (isVertical) {
|
|
251
|
+
svgContainer.style.flex = '1 1 auto';
|
|
252
|
+
svgContainer.style.minHeight = '0';
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
svgContainer.style.flex = '0 0 auto';
|
|
256
|
+
}
|
|
257
|
+
svgContainer.appendChild(svg);
|
|
258
|
+
this.eGui.appendChild(svgContainer);
|
|
237
259
|
if (hasCellText) {
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
case 'Above':
|
|
252
|
-
this.eGui.prepend(textEl);
|
|
253
|
-
break;
|
|
254
|
-
case 'Merged':
|
|
255
|
-
textEl.style.position = 'absolute';
|
|
256
|
-
textEl.style.top = '50%';
|
|
257
|
-
textEl.style.transform = 'translateY(-50%)';
|
|
258
|
-
textEl.style.left = '0';
|
|
259
|
-
textEl.style.right = '0';
|
|
260
|
-
textEl.style.paddingLeft = '5px';
|
|
261
|
-
textEl.style.paddingRight = '5px';
|
|
262
|
-
textEl.style.pointerEvents = 'none';
|
|
263
|
-
this.eGui.appendChild(textEl);
|
|
264
|
-
break;
|
|
265
|
-
case 'Below':
|
|
266
|
-
default:
|
|
267
|
-
this.eGui.appendChild(textEl);
|
|
268
|
-
break;
|
|
269
|
-
}
|
|
260
|
+
const pct = clamp((numericValue - min) / (max - min), 0, 1) * 100;
|
|
261
|
+
// See PercentBarRenderer: `params.formatValue` on a column without a
|
|
262
|
+
// `valueFormatter` returns the raw value (a number here), so coerce
|
|
263
|
+
// to string before it flows into the helpers.
|
|
264
|
+
const formattedCellValue = String(params.formatValue?.(numericValue) ?? numericValue);
|
|
265
|
+
const labels = buildBarChartCellTextLabels(cellTextProperties, formattedCellValue, `${pct.toFixed(0)}%`);
|
|
266
|
+
mountBarChartCellText({
|
|
267
|
+
wrapperEl: this.eGui,
|
|
268
|
+
mergedOverlayEl: svgContainer,
|
|
269
|
+
textClassName: 'ab-RangeBar__text',
|
|
270
|
+
cellTextProperties,
|
|
271
|
+
labels,
|
|
272
|
+
});
|
|
270
273
|
}
|
|
271
274
|
}
|
|
272
275
|
getGui() {
|
package/src/env.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
NEXT_PUBLIC_INFINITE_TABLE_LICENSE_KEY: "StartDate=2021-06-29|EndDate=2030-01-01|Owner=Adaptable|Type=distribution|TS=1624971462479|C=137829811,1004007071,2756196225,1839832928,3994409405,636616862" || '',
|
|
3
|
-
PUBLISH_TIMESTAMP:
|
|
4
|
-
VERSION: "23.0.0-canary.
|
|
3
|
+
PUBLISH_TIMESTAMP: 1782067349296 || Date.now(),
|
|
4
|
+
VERSION: "23.0.0-canary.8" || '--current-version--',
|
|
5
5
|
};
|