diff --git a/app/charts/combo/chart-combo-line-single.tsx b/app/charts/combo/chart-combo-line-single.tsx index af763b7d0..49db67896 100644 --- a/app/charts/combo/chart-combo-line-single.tsx +++ b/app/charts/combo/chart-combo-line-single.tsx @@ -80,9 +80,16 @@ export const ChartComboLineSingleVisualization = ( export const ChartComboLineSingle = React.memo( (props: ChartProps) => { - const { chartConfig } = props; + const { chartConfig, measures } = props; const { interactiveFiltersConfig } = chartConfig; + const getLegendItemDimension = React.useCallback( + (label) => { + return measures.find((measure) => measure.label === label); + }, + [measures] + ); + return ( @@ -97,7 +104,11 @@ export const ChartComboLineSingle = React.memo( - + ); diff --git a/app/charts/shared/legend-color.tsx b/app/charts/shared/legend-color.tsx index 87da7d3d9..c9d76f663 100644 --- a/app/charts/shared/legend-color.tsx +++ b/app/charts/shared/legend-color.tsx @@ -10,6 +10,7 @@ import { rgbArrayToHex } from "@/charts/shared/colors"; import { getLegendGroups } from "@/charts/shared/legend-color-helpers"; import Flex from "@/components/flex"; import { Checkbox, CheckboxProps } from "@/components/form"; +import { OpenMetadataPanelWrapper } from "@/components/metadata-panel"; import { ChartConfig, DataSource, @@ -208,11 +209,16 @@ const useLegendGroups = ({ type LegendColorProps = { chartConfig: ChartConfig; symbol: LegendSymbol; + // If the legend is based on measures, this function can be used to get the + // corresponding measure to open the metadata panel. + getLegendItemDimension?: ( + dimensionLabel: string + ) => DimensionMetadataFragment | undefined; interactive?: boolean; }; export const LegendColor = memo(function LegendColor(props: LegendColorProps) { - const { chartConfig, symbol, interactive } = props; + const { chartConfig, symbol, getLegendItemDimension, interactive } = props; const { colors, getColorLabel } = useChartState() as ColorsChartState; const values = colors.domain(); const groups = useLegendGroups({ chartConfig, values }); @@ -222,6 +228,7 @@ export const LegendColor = memo(function LegendColor(props: LegendColorProps) { groups={groups} getColor={(v) => colors(v)} getLabel={getColorLabel} + getItemDimension={getLegendItemDimension} symbol={symbol} interactive={interactive} numberOfOptions={values.length} @@ -288,14 +295,24 @@ type LegendColorContentProps = { groups: ReturnType; getColor: (d: string) => string; getLabel: (d: string) => string; + getItemDimension?: ( + dimensionLabel: string + ) => DimensionMetadataFragment | undefined; symbol: LegendSymbol; interactive?: boolean; numberOfOptions: number; }; const LegendColorContent = (props: LegendColorContentProps) => { - const { groups, getColor, getLabel, symbol, interactive, numberOfOptions } = - props; + const { + groups, + getColor, + getLabel, + getItemDimension, + symbol, + interactive, + numberOfOptions, + } = props; const classes = useStyles(); const categories = useInteractiveFilters((d) => d.categories); const addCategory = useInteractiveFilters((d) => d.addCategory); @@ -358,6 +375,7 @@ const LegendColorContent = (props: LegendColorContentProps) => { key={`${d}_${i}`} item={label} color={getColor(d)} + dimension={getItemDimension?.(label)} symbol={symbol} interactive={interactive} onToggle={handleToggle} @@ -377,6 +395,7 @@ const LegendColorContent = (props: LegendColorContentProps) => { type LegendItemProps = { item: string; color: string; + dimension?: DimensionMetadataFragment; symbol: LegendSymbol; interactive?: boolean; onToggle?: CheckboxProps["onChange"]; @@ -389,6 +408,7 @@ export const LegendItem = (props: LegendItemProps) => { const { item, color, + dimension, symbol, interactive, onToggle, @@ -424,7 +444,14 @@ export const LegendItem = (props: LegendItemProps) => { ) : ( - {item} + {dimension ? ( + + {/* Account for the added space, to align the symbol and label. */} + {item} + + ) : ( + item + )} ); }; diff --git a/app/components/form.tsx b/app/components/form.tsx index 95bc68f7c..c47d400bf 100644 --- a/app/components/form.tsx +++ b/app/components/form.tsx @@ -463,7 +463,9 @@ const DisabledMessageIcon = (props: DisabledMessageIconProps) => { } placement="top" - componentsProps={{ tooltip: { sx: { width: 140, px: 2, py: 1 } } }} + componentsProps={{ + tooltip: { sx: { width: 140, px: 2, py: 1, lineHeight: 1.2 } }, + }} sx={{ opacity: 1, pointerEvents: "auto", ml: 1 }} > diff --git a/app/configurator/components/chart-controls/color-palette.tsx b/app/configurator/components/chart-controls/color-palette.tsx index c91c00cd4..a0218fa12 100644 --- a/app/configurator/components/chart-controls/color-palette.tsx +++ b/app/configurator/components/chart-controls/color-palette.tsx @@ -147,7 +147,7 @@ export const ColorPalette = ({ ))} {component && state.state === "CONFIGURING_CHART" && ( - - Reset color palette - + + + + + ); } else { return ; diff --git a/app/configurator/components/chart-controls/color-picker.tsx b/app/configurator/components/chart-controls/color-picker.tsx index 7f2a411b1..bef45f894 100644 --- a/app/configurator/components/chart-controls/color-picker.tsx +++ b/app/configurator/components/chart-controls/color-picker.tsx @@ -1,16 +1,8 @@ import { Trans } from "@lingui/macro"; -import { - Box, - Button, - Input, - Popover, - styled, - Theme, - Typography, -} from "@mui/material"; +import { Box, Button, Popover, styled, Theme, Typography } from "@mui/material"; import { makeStyles } from "@mui/styles"; import { color as d3Color } from "d3"; -import React, { MouseEventHandler, useCallback, useRef, useState } from "react"; +import { MouseEventHandler, useRef } from "react"; import useDisclosure from "@/components/use-disclosure"; import VisuallyHidden from "@/components/visually-hidden"; @@ -75,43 +67,9 @@ const useColorPickerStyles = makeStyles((theme: Theme) => ({ gap: 2, marginBottom: 2, }, - input: { - color: theme.palette.grey[700], - borderColor: theme.palette.divider, - backgroundColor: theme.palette.grey[100], - fontSize: "0.875rem", - "&:focus": { outline: "none", borderColor: theme.palette.primary.main }, - }, })); export const ColorPicker = ({ selectedColor, colors, onChange }: Props) => { - const [inputColorValue, setInputColorValue] = useState(selectedColor); - - const selectColor = useCallback( - (_color) => { - setInputColorValue(_color); - // Make sure onChange is only called with valid colors - const c = d3Color(_color); - - if (c) { - onChange?.(_color); - } - }, - [onChange, setInputColorValue] - ); - - const formatInputColor = useCallback( - (_color) => { - // Make sure onChange is only called with valid colors - const c = d3Color(_color); - - if (c) { - setInputColorValue(_color); - } - }, - [setInputColorValue] - ); - const classes = useColorPickerStyles(); return ( @@ -122,24 +80,10 @@ export const ColorPicker = ({ selectedColor, colors, onChange }: Props) => { key={color} color={color} selected={color === selectedColor} - onClick={() => { - selectColor(color); - }} + onClick={() => onChange?.(color)} /> ))} - - ) => { - selectColor(e.currentTarget.value); - }} - onBlur={(e) => { - formatInputColor(e.currentTarget.value); - }} - /> - ); }; diff --git a/app/configurator/components/chart-options-selector.tsx b/app/configurator/components/chart-options-selector.tsx index fc1b6955e..0502bc26b 100644 --- a/app/configurator/components/chart-options-selector.tsx +++ b/app/configurator/components/chart-options-selector.tsx @@ -924,7 +924,7 @@ const ChartComboLineColumnYField = ( sortOptions={false} label={t({ id: "controls.chart.combo.y.column-measure", - message: "Column measure", + message: "Left axis (column)", })} value={y.columnComponentIri} onChange={(e) => { @@ -939,32 +939,9 @@ const ChartComboLineColumnYField = ( }, }); }} + sx={{ mb: 2 }} /> - - - Axis orientation - - } - /> - - {[ - { value: "right", label: t({ id: "left", message: "Left" }) }, - { value: "left", label: t({ id: "right", message: "Right" }) }, - ].map((d) => ( - - ))} - - -