@adaptabletools/adaptable
Version:
Powerful AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
161 lines (160 loc) • 7 kB
JavaScript
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;
}
};
};