Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/components/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@labkey/components",
"version": "6.70.8",
"version": "6.71.0",
"description": "Components, models, actions, and utility functions for LabKey applications and pages",
"sideEffects": false,
"files": [
Expand Down
7 changes: 7 additions & 0 deletions packages/components/releaseNotes/components.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
# @labkey/components
Components, models, actions, and utility functions for LabKey applications and pages

### version 6.71.0
*Released*: 20 November 2025
- Line chart trendline options for provided parameters to CalculateCurveFit API
- ChartBuilderModal update to include trendline option for provided parameters
- Include new 5 Parameter nonlinear curve fit option in trendline select
- Use column metadata displayWidth in app grid column render calcWidths

### version 6.70.8
*Released*: 19 November 2025
- Merge from release25.11-SNAPSHOT to develop
Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/internal/components/base/Grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ function processColumns(columns: List<any>): List<GridColumn> {
raw: c,
tableCell: c.tableCell,
title: c.title || c.caption,
width: c.width,
width: c.width || c.displayWidth,
});
})
.toList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ export const SVGChart: FC<Props> = memo(({ api, chart, container, filters, query
measureStore,
trendlineData
);
setPlot(plots[0]);
if (plots) setPlot(plots[0]);
}
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export const getChartBuilderQueryConfig = (
viewName: savedConfig?.viewName || viewName,
columns: Object.values(fieldValues)
.filter(field => field?.value && typeof field.value === 'string') // just those fields with values
.filter(field => !field.equation) // exclude the trendlineType field (which has an equation value)
.map(field => field.data?.fieldKey ?? field.value), // Issue 52050: use fieldKey for special characters
sort: LABKEY_VIS.GenericChartHelper.getQueryConfigSortKey(chartConfig.measures),
filterArray: savedConfig?.filterArray ?? [],
Expand Down Expand Up @@ -140,6 +141,7 @@ export const getChartBuilderChartConfig = (
trendlineType: undefined,
trendlineAsymptoteMin: undefined,
trendlineAsymptoteMax: undefined,
trendlineParameters: undefined,
...savedConfig?.geomOptions,
},
} as ChartConfig;
Expand Down Expand Up @@ -186,6 +188,7 @@ export const getChartBuilderChartConfig = (
config.geomOptions.trendlineType = type === '' ? undefined : type;
config.geomOptions.trendlineAsymptoteMin = fieldValues.trendlineAsymptoteMin?.value;
config.geomOptions.trendlineAsymptoteMax = fieldValues.trendlineAsymptoteMax?.value;
config.geomOptions.trendlineParameters = fieldValues.trendlineParameters?.value;
}

if (
Expand Down Expand Up @@ -377,8 +380,10 @@ const ChartTypeQueryForm: FC<ChartTypeQueryFormProps> = memo(props => {
{hasTrendlineOption && (
<TrendlineOption
fieldValues={fieldValues}
model={model}
onFieldChange={onFieldChange}
schemaQuery={model.schemaQuery}
selectedType={selectedType}
/>
)}
</div>
Expand Down Expand Up @@ -673,6 +678,11 @@ export const ChartBuilderModal: FC<ChartBuilderModalProps> = memo(({ actions, mo
value: chartConfig.geomOptions.trendlineAsymptoteMax,
};
}
if (chartConfig.geomOptions.trendlineParameters) {
fieldValues_['trendlineParameters'] = {
value: chartConfig.geomOptions.trendlineParameters,
};
}
}

return fieldValues_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ import { SchemaQuery } from '../../../public/SchemaQuery';
import { QueryInfo } from '../../../public/QueryInfo';
import { ViewInfo } from '../../ViewInfo';

import { ChartFieldOption, getSelectOptions } from './ChartFieldOption';
import { ChartFieldOption } from './ChartFieldOption';
import { ChartFieldInfo, ChartTypeInfo } from './models';

LABKEY_VIS = {
GenericChartHelper: {
getAllowableTypes: () => ['int', 'double'],
isMeasureDimensionMatch: () => true,
isNumericType: (type: string) => type === 'int',
},
};
Expand Down Expand Up @@ -60,37 +61,17 @@ const model = makeTestQueryModel(
0
);

describe('getSelectOptions', () => {
test('hasMatchingType', () => {
LABKEY_VIS.GenericChartHelper = {
...LABKEY_VIS.GenericChartHelper,
isMeasureDimensionMatch: () => false,
};
const field = { name: 'x' } as ChartFieldInfo;
const options = getSelectOptions(model, BAR_CHART_TYPE, field);
expect(options.length).toBe(2);
});

test('isMeasureDimensionMatch', () => {
LABKEY_VIS.GenericChartHelper = {
...LABKEY_VIS.GenericChartHelper,
isMeasureDimensionMatch: () => true,
};
const field = { name: 'x' } as ChartFieldInfo;
const options = getSelectOptions(model, BAR_CHART_TYPE, field);
expect(options.length).toBe(3);
});
});

describe('ChartFieldOption', () => {
test('line chart for x, showFieldOptions for int', async () => {
render(
<ChartFieldOption
field={{ name: 'x', label: 'X Axis', required: true } as ChartFieldInfo}
fieldValues={{ x: { value: 'field1', data: { type: 'int' } } }}
model={model}
onErrorBarChange={jest.fn()}
onScaleChange={jest.fn()}
onSelectFieldChange={jest.fn()}
scaleValues={undefined}
selectedType={LINE_PLOT_TYPE}
/>
);
Expand All @@ -108,8 +89,10 @@ describe('ChartFieldOption', () => {
field={{ name: 'x', label: 'X Axis', required: true } as ChartFieldInfo}
fieldValues={{ x: { value: 'field1', data: { type: 'date' } } }}
model={model}
onErrorBarChange={jest.fn()}
onScaleChange={jest.fn()}
onSelectFieldChange={jest.fn()}
scaleValues={undefined}
selectedType={LINE_PLOT_TYPE}
/>
);
Expand All @@ -127,8 +110,10 @@ describe('ChartFieldOption', () => {
field={{ name: 'x', label: 'X Axis', required: true } as ChartFieldInfo}
fieldValues={{ x: { value: 'field1', data: { type: 'int' } } }}
model={model}
onErrorBarChange={jest.fn()}
onScaleChange={jest.fn()}
onSelectFieldChange={jest.fn()}
scaleValues={undefined}
selectedType={BAR_CHART_TYPE}
/>
);
Expand All @@ -146,8 +131,10 @@ describe('ChartFieldOption', () => {
field={{ name: 'x', label: 'X Axis', required: false } as ChartFieldInfo}
fieldValues={{ x: { value: 'field1', data: { type: 'date' } } }}
model={model}
onErrorBarChange={jest.fn()}
onScaleChange={jest.fn()}
onSelectFieldChange={jest.fn()}
scaleValues={undefined}
selectedType={LINE_PLOT_TYPE}
/>
);
Expand All @@ -163,8 +150,10 @@ describe('ChartFieldOption', () => {
field={{ name: 'x', label: 'X Axis', required: true } as ChartFieldInfo}
fieldValues={{ x: { value: 'field1', data: { type: 'int' } } }}
model={model}
onErrorBarChange={jest.fn()}
onScaleChange={jest.fn()}
onSelectFieldChange={jest.fn()}
scaleValues={undefined}
selectedType={LINE_PLOT_TYPE}
/>
);
Expand Down Expand Up @@ -194,6 +183,7 @@ describe('ChartFieldOption', () => {
field={{ name: 'x', label: 'X Axis', required: true } as ChartFieldInfo}
fieldValues={{ x: { value: 'field1', data: { type: 'int' } } }}
model={model}
onErrorBarChange={jest.fn()}
onScaleChange={jest.fn()}
onSelectFieldChange={jest.fn()}
scaleValues={{ trans: 'log', type: 'manual', min: '3', max: '20' }}
Expand Down Expand Up @@ -231,6 +221,7 @@ describe('ChartFieldOption', () => {
field={{ name: 'x', label: 'X Axis', required: true } as ChartFieldInfo}
fieldValues={{ x: { value: 'field1', data: { type: 'int' } } }}
model={model}
onErrorBarChange={jest.fn()}
onScaleChange={jest.fn()}
onSelectFieldChange={jest.fn()}
scaleValues={{ trans: 'log', type: 'manual', min: '1', max: '0' }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,12 @@ import { SelectInput, SelectInputOption } from '../forms/input/SelectInput';
import { QueryModel } from '../../../public/QueryModel/QueryModel';

import { LABKEY_VIS } from '../../constants';
import { naturalSortByProperty } from '../../../public/sort';

import { ChartFieldRangeScaleOptions } from './ChartFieldRangeScaleOptions';
import { ChartFieldInfo, ChartTypeInfo, ScaleType } from './models';
import { getFieldDataType, shouldShowAggregateOptions, shouldShowRangeScaleOptions } from './utils';
import { getFieldDataType, getSelectOptions, shouldShowAggregateOptions, shouldShowRangeScaleOptions } from './utils';
import { ChartFieldAggregateOptions } from './ChartFieldAggregateOptions';

export const getSelectOptions = (
model: QueryModel,
chartType: ChartTypeInfo,
field: ChartFieldInfo
): SelectInputOption[] => {
const allowableTypes = LABKEY_VIS.GenericChartHelper.getAllowableTypes(field);

return model.queryInfo
.getDisplayColumns(model.viewName)
.filter(col => {
const colType = getFieldDataType(col);
const hasMatchingType = allowableTypes.indexOf(colType) > -1;
const isMeasureDimensionMatch = LABKEY_VIS.GenericChartHelper.isMeasureDimensionMatch(
chartType.name,
field,
col.measure,
col.dimension
);
return hasMatchingType || isMeasureDimensionMatch;
})
.sort(naturalSortByProperty('caption'))
.map(col => ({ label: col.caption, value: col.fieldKey, data: col }));
};

const DEFAULT_SCALE_VALUES = { type: 'automatic', trans: 'linear' };

interface OwnProps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ interface NonlinearCurveFitData {
}

interface NonlinearCurveFit extends CurveFit, NonlinearCurveFitData {
type: '3 Parameter' | '4 Parameter' | 'Five Parameter' | 'Four Parameter' | 'Three Parameter';
type: '3 Parameter' | '4 Parameter' | '5 Parameter' | 'Five Parameter' | 'Four Parameter' | 'Three Parameter';
}

interface CurveFitData<T extends CurveFit, S extends CurveFitStats> {
Expand Down Expand Up @@ -138,7 +138,14 @@ type PossibleTrendlines =
| Trendline<NonlinearCurveFit, NonlinearCurveFitStats>
| Trendline<PolynomialCurveFit>;

const nonLinearTrendlineTypes = ['3 Parameter', '4 Parameter', 'Five Parameter', 'Four Parameter', 'Three Parameter'];
const nonLinearTrendlineTypes = [
'3 Parameter',
'4 Parameter',
'5 Parameter',
'Five Parameter',
'Four Parameter',
'Three Parameter',
];
function isNonlinearTrendline(
trendline: PossibleTrendlines
): trendline is Trendline<NonlinearCurveFit, NonlinearCurveFitStats> {
Expand Down
Loading
Loading