update trendline

This commit is contained in:
Nate Kelley 2025-05-13 10:38:42 -06:00
parent 38ea7378d3
commit 5cf34201b4
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
7 changed files with 69 additions and 11 deletions

View File

@ -548,6 +548,27 @@ pub struct Trendline {
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(alias = "trend_line_color")]
pub trend_line_color: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(alias = "trendline_label_position_offset")]
pub trendline_label_position_offset: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(alias = "projection")]
pub projection: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(alias = "line_style")]
pub line_style: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(alias = "offset")]
pub offset: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(alias = "polynomial_order")]
pub polynomial_order: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(alias = "aggregate_all_categories")]
pub aggregate_all_categories: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(alias = "id")]
pub id: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
@ -705,7 +726,7 @@ pub enum MetricValueAggregate {
Count,
Max,
Min,
First
First,
}
#[derive(Debug, Serialize, Deserialize, Clone)]

View File

@ -22,10 +22,10 @@ export interface Trendline {
| 'median'; //default is linear trend
trendLineColor?: string | null | 'inherit'; //OPTIONAL: default is #000000, inherit will inherit the color from the line/bar
columnId: string;
trendlineLabelPositionOffset?: number; //OPTIONAL: default is 0.85. Goes from 0 to 1.
trendlineLabelPositionOffset?: number; //OPTIONAL: default is 0.85. Goes from 0 to 1. This is where the label will be placed on the trendline.
projection?: boolean; //OPTIONAL: default is false. if true, the trendline will be projected to the end of the chart.
lineStyle?: 'solid' | 'dotted' | 'dashed' | 'dashdot';
offset?: number; //OPTIONAL: default is -15. if true, the trendline will be projected to the end of the chart.
offset?: number; //OPTIONAL: default is 0. if true, the label will be offset vertically from the trendline.
polynomialOrder?: number;
aggregateAllCategories?: boolean; //OPTIONAL: default is true. if true, the trendline will be calculated for all categories. if false, the trendline will be calculated for the category specified in the columnId.
id?: string;

View File

@ -20,6 +20,7 @@ interface ColorPickerProps {
children?: React.ReactNode;
showInput?: boolean;
showPicker?: boolean;
pickerBackgroundImage?: string;
}
const colorPickerWrapperVariants = cva('border p-0.5 rounded cursor-pointer shadow', {
@ -47,6 +48,7 @@ const ColorPicker = ({
children,
showInput = true,
showPicker = true,
pickerBackgroundImage,
...props
}: ColorPickerProps) => {
const [open, setOpen] = useState(false);
@ -89,7 +91,12 @@ const ColorPicker = ({
<PopoverRoot onOpenChange={setOpen} open={open}>
<PopoverTrigger asChild disabled={disabled}>
<div>
<ColorPickerInputBox parsedValue={parsedValue} size={size} disabled={disabled} />
<ColorPickerInputBox
parsedValue={parsedValue}
size={size}
disabled={disabled}
pickerBackgroundImage={pickerBackgroundImage}
/>
</div>
</PopoverTrigger>
<PopoverContent className="w-full" align="end" side="bottom">
@ -116,16 +123,19 @@ ColorPicker.displayName = 'ColorPicker';
const ColorPickerInputBox = ({
parsedValue,
size,
disabled
disabled,
pickerBackgroundImage
}: {
parsedValue: string;
size: 'default' | 'small' | 'tall';
disabled: boolean | undefined;
pickerBackgroundImage: string | undefined;
}) => {
const backgroundStyle =
parsedValue === 'inherit'
parsedValue === 'inherit' || pickerBackgroundImage
? {
backgroundImage:
pickerBackgroundImage ||
'linear-gradient(to right, red, orange, yellow, green, blue, indigo, violet)'
}
: { backgroundColor: parsedValue };

View File

@ -177,6 +177,7 @@ export const MetricStylingApp: React.FC<{
barShowTotalAtTop={barShowTotalAtTop}
rowCount={rowCount}
pieSortBy={pieSortBy}
colors={colors}
/>
)}

View File

@ -20,11 +20,11 @@ import { TypeToLabel } from './config';
import { JOIN_CHARACTER } from '@/components/ui/charts/commonHelpers';
import isEqual from 'lodash/isEqual';
import { TrendlineLabelPositionOffset } from './TrendlineLabelPositionOffset';
import { TrendlineProjection } from './TrendlineProjection';
import { TrendlineLineStyle } from './TrendlineLineStyle';
import { TrendlineOffset } from './TrendlineOffset';
import { TrendlinePolynomialOrder } from './TrendlinePolynomialOrder';
import { TrendlineAggregateAllCategories } from './TrendlineAggregateAllCategories';
// import { TrendlineProjection } from './TrendlineProjection';
// import { TrendlinePolynomialOrder } from './TrendlinePolynomialOrder';
export interface LoopTrendline extends Trendline {
id: string;
@ -32,6 +32,7 @@ export interface LoopTrendline extends Trendline {
export const EditTrendline: React.FC<{
trendlines: IBusterMetricChartConfig['trendlines'];
colors: string[];
onUpdateChartConfig: (chartConfig: Partial<IBusterMetricChartConfig>) => void;
selectedAxis: ChartEncodes;
columnMetadata: ColumnMetaData[];
@ -40,6 +41,7 @@ export const EditTrendline: React.FC<{
}> = React.memo(
({
trendlines,
colors,
onUpdateChartConfig,
selectedAxis,
columnMetadata,
@ -175,6 +177,7 @@ export const EditTrendline: React.FC<{
onDeleteTrendline={onDeleteTrendline}
onUpdateExisitingTrendline={onUpdateExisitingTrendline}
isNewTrend={newTrendIds.has(trend.id)}
colors={colors}
/>
</motion.div>
))}
@ -193,6 +196,7 @@ const EditTrendlineItem: React.FC<{
yAxisEncodes: string[];
xAxisEncodes: string[];
categoryEncodes: string[] | undefined;
colors: string[];
selectedChartType: IBusterMetricChartConfig['selectedChartType'];
onUpdateExisitingTrendline: (trend: LoopTrendline) => void;
onDeleteTrendline: (id: string) => void;
@ -205,6 +209,7 @@ const EditTrendlineItem: React.FC<{
yAxisEncodes,
xAxisEncodes,
categoryEncodes,
colors,
selectedChartType,
onUpdateExisitingTrendline,
onDeleteTrendline
@ -234,6 +239,7 @@ const EditTrendlineItem: React.FC<{
columnLabelFormats={columnLabelFormats}
yAxisEncodes={yAxisEncodes}
xAxisEncodes={xAxisEncodes}
colors={colors}
categoryEncodes={categoryEncodes}
selectedChartType={selectedChartType}
onUpdateExisitingTrendline={onUpdateExisitingTrendline}
@ -249,6 +255,7 @@ const TrendlineItemContent: React.FC<{
columnMetadata: ColumnMetaData[];
yAxisEncodes: string[];
xAxisEncodes: string[];
colors: string[];
categoryEncodes: string[] | undefined;
columnLabelFormats: IBusterMetricChartConfig['columnLabelFormats'];
selectedChartType: IBusterMetricChartConfig['selectedChartType'];
@ -256,6 +263,7 @@ const TrendlineItemContent: React.FC<{
}> = React.memo(
({
trend,
colors,
categoryEncodes,
yAxisEncodes,
xAxisEncodes,
@ -316,6 +324,7 @@ const TrendlineItemContent: React.FC<{
<TrendlineColorPicker
trend={trend}
colors={colors}
onUpdateExisitingTrendline={onUpdateExisitingTrendline}
/>
</>

View File

@ -1,5 +1,5 @@
import { ColorPicker } from '@/components/ui/color-picker';
import React from 'react';
import React, { useMemo } from 'react';
import { LabelAndInput } from '../../Common';
import { LoopTrendline } from './EditTrendline';
import { useMemoizedFn } from '@/hooks';
@ -8,10 +8,12 @@ import { Switch } from '@/components/ui/switch';
export const TrendlineColorPicker = React.memo(
({
trend,
colors,
onUpdateExisitingTrendline
}: {
trend: LoopTrendline;
onUpdateExisitingTrendline: (trend: LoopTrendline) => void;
colors: string[];
}) => {
const onChangeComplete = useMemoizedFn((color: string) => {
const hexColor = color;
@ -24,6 +26,16 @@ export const TrendlineColorPicker = React.memo(
const isInheritColor = trend.trendLineColor === 'inherit';
const pickerBackgroundImage = useMemo(() => {
if (isInheritColor) {
const colorsToUse = colors.slice(0, 4);
return `repeating-linear-gradient(90deg, ${colorsToUse
.map((color, index) => `${color} ${index * 25}%, ${color} ${(index + 1) * 25}%`)
.join(', ')})`;
}
return undefined;
}, [colors, isInheritColor]);
return (
<LabelAndInput label="Color">
<div className="flex w-full items-center justify-end">
@ -31,6 +43,7 @@ export const TrendlineColorPicker = React.memo(
size="small"
showInput={!isInheritColor}
showPicker={!isInheritColor}
pickerBackgroundImage={pickerBackgroundImage}
value={trend.trendLineColor || '#000000'}
onChangeComplete={onChangeComplete}>
<LabelAndInput label="Inherit color">

View File

@ -72,7 +72,8 @@ export const StylingAppStyling: React.FC<
barShowTotalAtTop,
yAxisShowAxisTitle,
rowCount,
pieSortBy
pieSortBy,
colors
}) => {
const { onUpdateMetricChartConfig } = useUpdateMetricChart();
@ -175,6 +176,7 @@ export const StylingAppStyling: React.FC<
lineGroupType={lineGroupType}
barGroupType={barGroupType}
onUpdateChartConfig={onUpdateChartConfig}
colors={colors}
/>
</div>
);
@ -477,7 +479,8 @@ const EtcSettings: React.FC<
columnMetadata,
columnLabelFormats,
lineGroupType,
barGroupType
barGroupType,
colors
}) => {
const isScatterChart = selectedChartType === 'scatter';
const isPieChart = selectedChartType === 'pie';
@ -546,6 +549,7 @@ const EtcSettings: React.FC<
columnMetadata={columnMetadata}
selectedChartType={selectedChartType}
onUpdateChartConfig={onUpdateChartConfig}
colors={colors}
/>
)
}