Skip to content

Commit 7f80713

Browse files
committed
config min marker size for better colors
1 parent 076b09c commit 7f80713

File tree

5 files changed

+40
-23
lines changed

5 files changed

+40
-23
lines changed

smoosense-gui/src/lib/features/bubblePlot/BubblePlotMoreControls.tsx

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import CategoricalColumnDropdown from '@/components/common/CategoricalColumnDrop
77
import NumericalColumnDropdown from '@/components/common/NumericalColumnDropdown'
88
import { Select, SelectContent, SelectItem, SelectTrigger } from '@/components/ui/select'
99
import { useAppSelector, useAppDispatch } from '@/lib/hooks'
10-
import { setBubblePlotMaxMarkerSize, setBubblePlotOpacity, setBubblePlotMarkerSizeContrastRatio, setBubblePlotColorScale } from '@/lib/features/ui/uiSlice'
10+
import { setBubblePlotMaxMarkerSize, setBubblePlotMinMarkerSize, setBubblePlotOpacity, setBubblePlotMarkerSizeContrastRatio, setBubblePlotColorScale } from '@/lib/features/ui/uiSlice'
1111

1212
// Plotly color scales with their CSS gradient representations
1313
const COLOR_SCALES: Record<string, string> = {
@@ -30,6 +30,7 @@ function ColorScaleBar({ scale }: { scale: string }) {
3030
function BubblePlotMoreControlsContent() {
3131
const dispatch = useAppDispatch()
3232
const bubblePlotMaxMarkerSize = useAppSelector((state) => state.ui.bubblePlotMaxMarkerSize)
33+
const bubblePlotMinMarkerSize = useAppSelector((state) => state.ui.bubblePlotMinMarkerSize)
3334
const bubblePlotOpacity = useAppSelector((state) => state.ui.bubblePlotOpacity)
3435
const bubblePlotMarkerSizeContrastRatio = useAppSelector((state) => state.ui.bubblePlotMarkerSizeContrastRatio)
3536
const bubblePlotColorScale = useAppSelector((state) => state.ui.bubblePlotColorScale)
@@ -71,6 +72,20 @@ function BubblePlotMoreControlsContent() {
7172
</div>
7273
</div>
7374

75+
<div>
76+
<label className="text-sm font-medium mb-2 block">
77+
Min Marker Size: {bubblePlotMinMarkerSize}
78+
</label>
79+
<Slider
80+
value={[bubblePlotMinMarkerSize]}
81+
onValueChange={(value) => dispatch(setBubblePlotMinMarkerSize(value[0]))}
82+
max={15}
83+
min={2}
84+
step={1}
85+
className="w-full"
86+
/>
87+
</div>
88+
7489
<div>
7590
<label className="text-sm font-medium mb-2 block">
7691
Max Marker Size: {bubblePlotMaxMarkerSize}

smoosense-gui/src/lib/features/bubblePlot/PlotlyBubblePlot.tsx

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ const PlotlyBubblePlot = React.memo(function PlotlyBubblePlot({ data }: PlotlyBu
3434
const yColumn = useAppSelector((state) => state.ui.bubblePlotYColumn)
3535
const breakdownColumn = useAppSelector((state) => state.ui.bubblePlotBreakdownColumn)
3636
const maxMarkerSize = useAppSelector((state) => state.ui.bubblePlotMaxMarkerSize)
37+
const minMarkerSize = useAppSelector((state) => state.ui.bubblePlotMinMarkerSize)
3738
const opacity = useAppSelector((state) => state.ui.bubblePlotOpacity)
3839
const markerSizeContrastRatio = useAppSelector((state) => state.ui.bubblePlotMarkerSizeContrastRatio)
3940
const colorColumn = useAppSelector((state) => state.ui.bubblePlotColorColumn)
@@ -63,39 +64,30 @@ const PlotlyBubblePlot = React.memo(function PlotlyBubblePlot({ data }: PlotlyBu
6364
// Shifted logistic function: markerSize = 2 * maxMarkerSize * (1 / (1 + exp(-markerSizeContrastRatio * count)) - 0.5)
6465
const k = Math.exp(-markerSizeContrastRatio)
6566
const logisticValue = 1 / (1 + Math.exp(-k * c.count))
66-
return Math.max(5, 2 * maxMarkerSize * (logisticValue - 0.5))
67+
return Math.max(minMarkerSize, 2 * maxMarkerSize * (logisticValue - 0.5))
6768
})
6869

6970
// Build marker config
7071
// eslint-disable-next-line @typescript-eslint/no-explicit-any
7172
const marker: any = {
7273
size: markerSizes,
7374
opacity: opacity,
75+
line: {
76+
width: 0.5,
77+
color: colors.foreground
78+
}
7479
}
7580

7681
// Add color mapping if color column is selected
7782
if (hasColorValues) {
78-
const colorValues = item.customdata.map(c => c.colorValue ?? 0)
79-
marker.color = colorValues
83+
marker.color = item.customdata.map(c => c.colorValue ?? 0)
8084
marker.colorscale = colorScale
8185
marker.showscale = true
8286
marker.colorbar = {
8387
title: colorColumn,
8488
thickness: 15,
8589
len: 0.5
8690
}
87-
// Use same color for border (no separate border color)
88-
marker.line = {
89-
width: 1,
90-
color: colorValues,
91-
colorscale: colorScale
92-
}
93-
} else {
94-
// Default border color when no color column
95-
marker.line = {
96-
width: 1,
97-
color: colors.foreground
98-
}
9991
}
10092

10193
const trace: Partial<PlotData> = {
@@ -123,9 +115,10 @@ const PlotlyBubblePlot = React.memo(function PlotlyBubblePlot({ data }: PlotlyBu
123115
setPlotlyError((error as Error).message)
124116
return []
125117
}
126-
}, [data, xColumn, yColumn, breakdownColumn, colorColumn, colorScale, opacity, maxMarkerSize, markerSizeContrastRatio, colors.foreground])
118+
}, [data, xColumn, yColumn, breakdownColumn, colorColumn, colorScale, opacity, maxMarkerSize, minMarkerSize, markerSizeContrastRatio, colors.foreground])
127119

128120
const baseLayout = usePlotlyLayout({
121+
title: colorColumn ? `Color: ${colorColumn}` : undefined,
129122
xTitle: `X: ${xColumn}`,
130123
yTitle: `Y: ${yColumn}`,
131124
showLegend: breakdownColumn !== null

smoosense-gui/src/lib/features/ui/uiSlice.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ interface UiState {
3636
bubblePlotYColumn: string
3737
bubblePlotBreakdownColumn: string | null
3838
bubblePlotMaxMarkerSize: number
39+
bubblePlotMinMarkerSize: number
3940
bubblePlotOpacity: number
4041
bubblePlotMarkerSizeContrastRatio: number
4142
bubblePlotColorColumn: string
@@ -83,6 +84,7 @@ const initialState: UiState = {
8384
bubblePlotYColumn: '',
8485
bubblePlotBreakdownColumn: null,
8586
bubblePlotMaxMarkerSize: 20,
87+
bubblePlotMinMarkerSize: 7,
8688
bubblePlotOpacity: 0.7,
8789
bubblePlotMarkerSizeContrastRatio: 4.2,
8890
bubblePlotColorColumn: '',
@@ -209,6 +211,9 @@ export const uiSlice = createSlice({
209211
setBubblePlotMaxMarkerSize: (state, action: PayloadAction<number>) => {
210212
state.bubblePlotMaxMarkerSize = Math.max(5, Math.min(50, action.payload))
211213
},
214+
setBubblePlotMinMarkerSize: (state, action: PayloadAction<number>) => {
215+
state.bubblePlotMinMarkerSize = Math.max(2, Math.min(15, action.payload))
216+
},
212217
setBubblePlotOpacity: (state, action: PayloadAction<number>) => {
213218
state.bubblePlotOpacity = Math.max(0.1, Math.min(1, action.payload))
214219
},
@@ -312,6 +317,7 @@ export const {
312317
setBubblePlotYColumn,
313318
setBubblePlotBreakdownColumn,
314319
setBubblePlotMaxMarkerSize,
320+
setBubblePlotMinMarkerSize,
315321
setBubblePlotOpacity,
316322
setBubblePlotMarkerSizeContrastRatio,
317323
setBubblePlotColorColumn,

smoosense-gui/src/lib/test-utils.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export function createDefaultTestState(): RootState {
6060
bubblePlotYColumn: '',
6161
bubblePlotBreakdownColumn: null,
6262
bubblePlotMaxMarkerSize: 20,
63+
bubblePlotMinMarkerSize: 7,
6364
bubblePlotOpacity: 0.7,
6465
bubblePlotMarkerSizeContrastRatio: 0.5,
6566
bubblePlotColorColumn: '',

smoosense-gui/src/lib/utils/plotlyTheme.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,13 @@ export const usePlotlyAxis = ({
7272
/**
7373
* Hook to configure common Plotly layout with theming
7474
*/
75-
export const usePlotlyLayout = ({
76-
xTitle = '',
75+
export const usePlotlyLayout = ({
76+
title,
77+
xTitle = '',
7778
yTitle = '',
7879
showLegend = true
79-
}: {
80+
}: {
81+
title?: string
8082
xTitle?: string
8183
yTitle?: string
8284
showLegend?: boolean
@@ -91,7 +93,7 @@ export const usePlotlyLayout = ({
9193

9294
return useMemo(() => ({
9395
title: {
94-
text: '',
96+
text: title || '',
9597
font: {
9698
color: colors.foreground,
9799
family: 'system-ui, -apple-system, sans-serif'
@@ -108,7 +110,7 @@ export const usePlotlyLayout = ({
108110
margin: {
109111
l: Math.round(fontSize * 4.3),
110112
r: Math.round(fontSize * 2.1),
111-
t: Math.round(fontSize * 2.1),
113+
t: title ? Math.round(fontSize * 2.5) : Math.round(fontSize * 2.1),
112114
b: Math.round(fontSize * 4.3)
113115
},
114116
dragmode: 'pan' as const,
@@ -123,7 +125,7 @@ export const usePlotlyLayout = ({
123125
}
124126
},
125127
hovermode: 'closest' as const
126-
}), [colors, xAxis, yAxis, showLegend, fontSize])
128+
}), [colors, xAxis, yAxis, showLegend, fontSize, title])
127129
}
128130

129131

0 commit comments

Comments
 (0)