UNPKG

@adaptabletools/adaptable

Version:

Powerful AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements

161 lines (160 loc) 7 kB
import Helper from '../../Utilities/Helpers/Helper'; import { clamp } from '../../Utilities/Extensions/NumberExtensions'; import { shouldRenderStyledColumnOnRow } from '../../Utilities/Helpers/StyledColumns/StyledColumnHelper'; import { buildBarStyleCellTextLabels, hasBarStyleCellTextConfigured, mountBarStyleCellText, } from '../../Utilities/Helpers/StyledColumns/BarStylesHelper'; const resolveOrigin = (percentBarStyle, cellValue, min, max) => { const origin = percentBarStyle.Origin ?? 'Auto'; if (typeof origin === 'number') { return origin; } if (origin === 'Zero') { return 0; } if (origin === 'Min') { return min; } if (min < 0 || max < 0 || cellValue < 0) { return 0; } return min; }; const toFraction = (value, min, max) => { if (max === min) { return 0; } return clamp((value - min) / (max - min), 0, 1); }; const columnComparisonUsesCentredAxis = (origin) => { const o = origin ?? 'Auto'; if (typeof o === 'number') { return false; } return o === 'Zero' || o === 'Auto'; }; export const getPercentBarRendererForColumn = (styledColumn, abColumn, api) => { if (!styledColumn.PercentBarStyle) { return; } return class PercentBarRenderer { eGui; init(params) { if (!shouldRenderStyledColumnOnRow(styledColumn, params.node, api)) { if (params.value != undefined) { this.eGui = document.createElement('div'); this.eGui.append(String(params.value)); } return; } const rawCellValue = params.value; if (Helper.objectNotExists(rawCellValue)) { this.eGui = document.createElement('div'); return; } const numericValue = typeof rawCellValue === 'number' ? rawCellValue : Number(rawCellValue); if (isNaN(numericValue)) { this.eGui = document.createElement('div'); this.eGui.append(params.formatValue?.(rawCellValue) ?? String(rawCellValue)); return; } const min = api.styledColumnApi.internalApi.getNumericStyleMinValue(styledColumn, abColumn, params.node, rawCellValue); const max = api.styledColumnApi.internalApi.getNumericStyleMaxValue(styledColumn, abColumn, params.node, rawCellValue); const percentBarStyle = styledColumn.PercentBarStyle; let percentageValue; let barLeftPercent; let barWidthPercent; if (percentBarStyle.ColumnComparison) { const absMax = Math.abs(max); percentageValue = absMax === 0 ? 0 : (numericValue / absMax) * 100; const magnitude = Math.min(100, Math.abs(percentageValue)); const origin = percentBarStyle.Origin ?? 'Auto'; const isCentred = columnComparisonUsesCentredAxis(origin); if (isCentred) { const halfWidth = magnitude / 2; if (percentageValue >= 0) { barLeftPercent = 50; barWidthPercent = halfWidth; } else { barLeftPercent = 50 - halfWidth; barWidthPercent = halfWidth; } } else { barLeftPercent = 0; barWidthPercent = magnitude; } } else if (max === min) { percentageValue = 0; barLeftPercent = 0; barWidthPercent = 0; } else { percentageValue = ((clamp(numericValue, min, max) - min) / (max - min)) * 100; const origin = resolveOrigin(percentBarStyle, numericValue, min, max); const valueFrac = toFraction(numericValue, min, max); const originFrac = toFraction(origin, min, max); const start = Math.min(valueFrac, originFrac); const end = Math.max(valueFrac, originFrac); barLeftPercent = start * 100; barWidthPercent = (end - start) * 100; } let cellBackColor; if (percentBarStyle.ColumnComparison) { cellBackColor = percentBarStyle.ColumnComparison.Color; } else { const matchingRange = api.styledColumnApi.internalApi.findRangeForColumn(percentBarStyle.CellRanges, abColumn, percentBarStyle.RangeValueType, numericValue); if (matchingRange) { cellBackColor = matchingRange.Color; } } const cellTextProperties = percentBarStyle.CellTextProperties; const hasCellText = hasBarStyleCellTextConfigured(cellTextProperties); this.eGui = document.createElement('div'); this.eGui.className = 'ab-PercentBar__wrapper'; this.eGui.style.height = '100%'; this.eGui.style.display = 'flex'; this.eGui.style.flexDirection = 'column'; this.eGui.style.justifyContent = 'center'; const barEl = document.createElement('div'); barEl.className = 'ab-PercentBar__bar'; barEl.style.position = 'relative'; if (percentBarStyle.BackColor) { barEl.style.background = percentBarStyle.BackColor; } barEl.style.flex = '1 1 0'; barEl.style.minHeight = '6px'; if (cellBackColor) { const barInsideEl = document.createElement('div'); barInsideEl.className = 'ab-PercentBar__barInside'; barInsideEl.style.background = cellBackColor; barInsideEl.style.height = '100%'; barInsideEl.style.position = 'absolute'; barInsideEl.style.left = `${barLeftPercent.toFixed(2)}%`; barInsideEl.style.width = `${barWidthPercent.toFixed(2)}%`; barInsideEl.style.top = '0'; barEl.append(barInsideEl); } this.eGui.append(barEl); if (hasCellText) { const formattedCellValue = String(params.formatValue?.(rawCellValue) ?? rawCellValue); const labels = buildBarStyleCellTextLabels(cellTextProperties, formattedCellValue, `${percentageValue.toFixed(0)}%`); mountBarStyleCellText({ wrapperEl: this.eGui, mergedOverlayEl: barEl, textClassName: 'ab-PercentBar__text', cellTextProperties, labels, mergedPointerEventsNone: false, }); } } getGui() { return this.eGui; } refresh(_params) { return false; } }; };