99} from "@/charts/shared/use-chart-state" ;
1010import { useInteractiveFilters } from "@/charts/shared/use-interactive-filters" ;
1111import Flex from "@/components/flex" ;
12- import { Checkbox } from "@/components/form" ;
12+ import { Checkbox , CheckboxProps } from "@/components/form" ;
1313import {
1414 DataSource ,
1515 isSegmentInConfig ,
@@ -31,7 +31,7 @@ import { getLegendGroups } from "./legend-color-helpers";
3131
3232type LegendSymbol = "square" | "line" | "circle" ;
3333
34- const useStyles = makeStyles < Theme > ( ( ) => ( {
34+ const useStyles = makeStyles < Theme > ( ( theme ) => ( {
3535 legendContainer : {
3636 position : "relative" ,
3737 justifyContent : "flex-start" ,
@@ -51,6 +51,10 @@ const useStyles = makeStyles<Theme>(() => ({
5151 display : "flex" ,
5252 flexWrap : "wrap" ,
5353 columnGap : "1rem" ,
54+ flexDirection : "column" ,
55+ } ,
56+ groupHeader : {
57+ marginBottom : theme . spacing ( 1 ) ,
5458 } ,
5559} ) ) ;
5660
@@ -80,66 +84,11 @@ const useItemStyles = makeStyles<
8084 borderRadius : ( { symbol } ) => ( symbol === "circle" ? "50%" : 0 ) ,
8185 } ,
8286 } ,
83- } ) ) ;
84-
85- export const InteractiveLegendColor = ( ) => {
86- const [ state , dispatch ] = useInteractiveFilters ( ) ;
87- const { categories } = state ;
88-
89- const activeInteractiveFilters = useMemo ( ( ) => {
90- return new Set ( Object . keys ( categories ) ) ;
91- } , [ categories ] ) ;
92-
93- const { colors } = useChartState ( ) as ColorsChartState ;
94-
95- const setFilter = useEvent ( ( item : string ) => {
96- if ( activeInteractiveFilters . has ( item ) ) {
97- dispatch ( {
98- type : "REMOVE_INTERACTIVE_FILTER" ,
99- value : item ,
100- } ) ;
101- } else {
102- dispatch ( {
103- type : "ADD_INTERACTIVE_FILTER" ,
104- value : item ,
105- } ) ;
106- }
107- } ) ;
10887
109- const groups = useMemo ( ( ) => {
110- return [ { label : undefined , value : "" , values : colors . domain ( ) } ] ;
111- } , [ colors ] ) ;
112- const classes = useStyles ( ) ;
113- return (
114- < Flex
115- className = { clsx (
116- classes . legendContainer ,
117- groups . length === 1 ? classes . legendContainerNoGroups : undefined
118- ) }
119- >
120- { groups . map ( ( group ) => {
121- return (
122- < div key = { group . value } >
123- { group . label ? (
124- < Typography variant = "h4" > { group . label } </ Typography >
125- ) : null }
126- { colors . domain ( ) . map ( ( item , i ) => (
127- < Checkbox
128- label = { item }
129- name = { item }
130- value = { item }
131- checked = { ! activeInteractiveFilters . has ( item ) }
132- onChange = { ( ) => setFilter ( item ) }
133- key = { i }
134- color = { colors ( item ) }
135- />
136- ) ) }
137- </ div >
138- ) ;
139- } ) }
140- </ Flex >
141- ) ;
142- } ;
88+ legendCheckbox : {
89+ marginTop : ( ) => "0.25rem" ,
90+ } ,
91+ } ) ) ;
14392
14493const useDimension = ( {
14594 dataset,
@@ -228,8 +177,10 @@ const useLegendGroups = ({
228177
229178export const LegendColor = memo ( function LegendColor ( {
230179 symbol,
180+ interactive,
231181} : {
232182 symbol : LegendSymbol ;
183+ interactive ?: boolean ;
233184} ) {
234185 const { colors, getSegmentLabel } = useChartState ( ) as ColorsChartState ;
235186 const groups = useLegendGroups ( { labels : colors . domain ( ) } ) ;
@@ -240,6 +191,7 @@ export const LegendColor = memo(function LegendColor({
240191 getColor = { ( v ) => colors ( v ) }
241192 getLabel = { getSegmentLabel }
242193 symbol = { symbol }
194+ interactive = { interactive }
243195 />
244196 ) ;
245197} ) ;
@@ -282,13 +234,37 @@ const LegendColorContent = ({
282234 getColor,
283235 getLabel,
284236 symbol,
237+ interactive,
285238} : {
286239 groups : ReturnType < typeof useLegendGroups > ;
287240 getColor : ( d : string ) => string ;
288241 getLabel : ( d : string ) => string ;
289242 symbol : LegendSymbol ;
243+ interactive ?: boolean ;
290244} ) => {
291245 const classes = useStyles ( ) ;
246+ const [ state , dispatch ] = useInteractiveFilters ( ) ;
247+ const { categories } = state ;
248+
249+ const activeInteractiveFilters = useMemo ( ( ) => {
250+ return new Set ( Object . keys ( categories ) ) ;
251+ } , [ categories ] ) ;
252+
253+ const handleToggle : CheckboxProps [ "onChange" ] = useEvent ( ( ev ) => {
254+ const item = ev . target . value ;
255+ console . log ( { item } ) ;
256+ if ( activeInteractiveFilters . has ( item ) ) {
257+ dispatch ( {
258+ type : "REMOVE_INTERACTIVE_FILTER" ,
259+ value : item ,
260+ } ) ;
261+ } else {
262+ dispatch ( {
263+ type : "ADD_INTERACTIVE_FILTER" ,
264+ value : item ,
265+ } ) ;
266+ }
267+ } ) ;
292268
293269 return (
294270 < Flex
@@ -300,15 +276,19 @@ const LegendColorContent = ({
300276 { groups
301277 ? groups . map ( ( [ g , colorValues ] ) => {
302278 const headerLabelsArray = g . map ( ( n ) => n . label ) ;
303-
304279 return (
305280 < div
306281 className = { classes . legendGroup }
307282 key = { g . map ( ( n ) => n . label ) . join ( " > " ) }
308283 data-testid = "colorLegend"
309284 >
310285 { headerLabelsArray . length > 0 ? (
311- < Typography variant = "h5" display = "flex" alignItems = "center" >
286+ < Typography
287+ variant = "h5"
288+ display = "flex"
289+ alignItems = "center"
290+ className = { classes . groupHeader }
291+ >
312292 { interlace (
313293 g . map ( ( n ) => n . label ) ,
314294 < SvgIcChevronRight />
@@ -321,6 +301,11 @@ const LegendColorContent = ({
321301 item = { getLabel ( d ) }
322302 color = { getColor ( d ) }
323303 symbol = { symbol }
304+ interactive = { interactive }
305+ onToggle = { handleToggle }
306+ checked = {
307+ interactive && ! activeInteractiveFilters . has ( getLabel ( d ) )
308+ }
324309 />
325310 ) ) }
326311 </ div >
@@ -335,15 +320,36 @@ export const LegendItem = ({
335320 item,
336321 color,
337322 symbol,
323+ interactive,
324+ onToggle,
325+ checked,
338326} : {
339327 item : string ;
340328 color : string ;
341329 symbol : LegendSymbol ;
330+ interactive ?: boolean ;
331+ onToggle ?: CheckboxProps [ "onChange" ] ;
332+ checked ?: boolean ;
342333} ) => {
343334 const classes = useItemStyles ( { symbol, color } ) ;
344335 return (
345- < Flex data-testid = "legendItem" className = { classes . legendItem } >
346- { item }
347- </ Flex >
336+ < >
337+ { interactive && onToggle ? (
338+ < Checkbox
339+ label = { item }
340+ name = { item }
341+ value = { item }
342+ checked = { checked !== undefined ? checked : true }
343+ onChange = { onToggle }
344+ key = { item }
345+ color = { color }
346+ className = { classes . legendCheckbox }
347+ />
348+ ) : (
349+ < Flex data-testid = "legendItem" className = { classes . legendItem } >
350+ { item }
351+ </ Flex >
352+ ) }
353+ </ >
348354 ) ;
349355} ;
0 commit comments