Skip to content
This repository has been archived by the owner on Nov 4, 2024. It is now read-only.

Commit

Permalink
Merge branch 'develop' into release/2.66.0
Browse files Browse the repository at this point in the history
  • Loading branch information
VWSCoronaDashboard27 authored and VWSCoronaDashboard27 committed Jan 12, 2023
2 parents d04d5ad + 6353953 commit 5447cca
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 222 deletions.
103 changes: 55 additions & 48 deletions packages/app/src/components/interactive-legend.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import styled from 'styled-components';
import { isDefined } from 'ts-is-present';
import { BoldText } from '~/components/typography';
import { useIntl } from '~/intl';
import { space } from '~/style/theme';
import { Box } from './base';

export interface SelectOption<T = string> {
metricProperty: T;
label: string;
color: string;
shape?: 'line' | 'circle' | 'square' | 'gapped-area';
shape?: 'line' | 'circle' | 'square' | 'gapped-area' | 'dashed';
legendAriaLabel?: string;
}

Expand All @@ -22,13 +23,7 @@ interface InteractiveLegendProps<T = string> {
onReset?: () => void;
}

export function InteractiveLegend<T = string>({
helpText,
selectOptions,
selection,
onToggleItem,
onReset,
}: InteractiveLegendProps<T>) {
export function InteractiveLegend<T = string>({ helpText, selectOptions, selection, onToggleItem, onReset }: InteractiveLegendProps<T>) {
const { commonTexts } = useIntl();

const hasSelection = selection.length !== 0;
Expand All @@ -42,19 +37,17 @@ export function InteractiveLegend<T = string>({
const isSelected = selection.includes(item.metricProperty);
return (
<Item key={item.label}>
<StyledLabel
htmlFor={`checkboxgroup-${item.label}`}
isActive={hasSelection && isSelected}
borderColor={item.color}
data-text={item.label}
>
<StyledLabel htmlFor={`checkboxgroup-${item.label}`} isActive={hasSelection && isSelected} borderColor={item.color} data-text={item.label}>
{item.label}
{item.shape === 'line' && <Line color={item.color} />}
{item.shape === 'dashed' && (
<DashedContainer>
<Dashed color={item.color} />
</DashedContainer>
)}
{item.shape === 'circle' && <Circle color={item.color} />}
{item.shape === 'square' && <Square color={item.color} />}
{item.shape === 'gapped-area' && (
<GappedArea color={item.color} />
)}
{item.shape === 'gapped-area' && <GappedArea color={item.color} />}
</StyledLabel>
<StyledInput
type="checkbox"
Expand Down Expand Up @@ -89,16 +82,16 @@ const Legend = styled.div(
const List = styled.ul(
css({
listStyle: 'none',
px: 0,
m: 0,
mt: 2,
paddingX: 0,
margin: 0,
marginTop: space[2],
})
);

const Item = styled.li(
css({
mb: 2,
mr: 2,
marginBottom: space[2],
marginRight: space[2],
position: 'relative',
display: 'inline-block',
})
Expand All @@ -120,13 +113,11 @@ const StyledLabel = styled.label<{
cursor: 'pointer',
position: 'relative',
display: 'inline-flex',
pr: 13,
pl: 33,
py: 1,
paddingRight: '13px',
paddingLeft: '33px',
paddingY: space[1],
borderRadius: '5px',
boxShadow: `inset 0px 0px 0px ${
isActive ? `3px ${borderColor}` : `1px ${colors.gray4}`
}`,
boxShadow: `inset 0px 0px 0px ${isActive ? `3px ${borderColor}` : `1px ${colors.gray4}`}`,
fontWeight: 'normal',
fontFamily: 'inherit',
fontSize: 1,
Expand Down Expand Up @@ -189,7 +180,7 @@ const ResetButton = styled.button<{ isVisible: boolean }>(({ isVisible }) =>
backgroundColor: 'transparent',
cursor: 'pointer',
color: 'blue8',
py: '6px',
paddingY: '6px',
border: 'none',
fontFamily: 'inherit',
visibility: isVisible ? 'visible' : 'hidden',
Expand All @@ -200,26 +191,49 @@ const ResetButton = styled.button<{ isVisible: boolean }>(({ isVisible }) =>
})
);

const Line = styled.div<{ color: string }>(({ color }) =>
const DashedContainer = styled(Box)`
svg {
display: block;
left: 13px;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
`;

interface DashedProps {
color: string;
}

export const Dashed = ({ color }: DashedProps) => {
return (
<svg width={15} height={15} viewBox={`0 0 ${15} ${15}`}>
<line stroke={color} strokeWidth={3} strokeDasharray={4} strokeLinecap="round" strokeLinejoin="round" x1={2} y1={15 / 2} x2={15 - 2} y2={15 / 2} />
</svg>
);
};

const Shape = styled.div<{ color: string }>((x) =>
css({
display: 'block',
position: 'absolute',
left: 13,
backgroundColor: x.color,
})
);

const Line = styled(Shape)(
css({
top: '50%',
transform: 'translateY(-50%)',
width: '15px',
height: '3px',
borderRadius: '2px',
display: 'block',
position: 'absolute',
left: 13,
backgroundColor: color,
})
);

const Circle = styled.div<{ color: string }>(({ color }) =>
const Circle = styled(Shape)(
css({
display: 'block',
position: 'absolute',
left: 13,
backgroundColor: color,
top: '50%',
transform: 'translateY(-50%)',
width: '10px',
Expand All @@ -228,12 +242,8 @@ const Circle = styled.div<{ color: string }>(({ color }) =>
})
);

const Square = styled.div<{ color: string }>(({ color }) =>
const Square = styled(Shape)(
css({
display: 'block',
position: 'absolute',
left: 13,
backgroundColor: color,
top: '50%',
transform: 'translateY(-50%)',
width: '11px',
Expand All @@ -242,11 +252,8 @@ const Square = styled.div<{ color: string }>(({ color }) =>
})
);

const GappedArea = styled.div<{ color: string }>(({ color }) =>
const GappedArea = styled(Shape)<{ color: string }>(({ color }) =>
css({
display: 'block',
position: 'absolute',
left: 13,
backgroundColor: `${color}30`,
borderTop: `2px solid ${color}`,
top: '50%',
Expand Down
79 changes: 24 additions & 55 deletions packages/app/src/components/legend.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,9 @@ import { colors } from '@corona-dashboard/common';
import css, { SystemStyleObject } from '@styled-system/css';
import { ReactNode } from 'react';
import styled from 'styled-components';
import { space } from '~/style/theme';

type LegendShape =
| 'line'
| 'square'
| 'circle'
| 'dotted-square'
| 'outlined-square';
type LegendShape = 'line' | 'square' | 'circle' | 'dotted-square' | 'outlined-square';
type LegendLineStyle = 'solid' | 'dashed';

export type LegendItem = {
Expand Down Expand Up @@ -44,15 +40,9 @@ export function Legend({ items, columns }: LegendProps) {
<Item key={i}>
{item.label}
{item.shape === 'square' && <Square color={item.color} />}
{item.shape === 'outlined-square' && (
<OutlinedSquare color={item.color} />
)}
{item.shape === 'dotted-square' && (
<DottedSquare color={item.color} />
)}
{item.shape === 'line' && (
<Line color={item.color} lineStyle={item.style ?? 'solid'} />
)}
{item.shape === 'outlined-square' && <OutlinedSquare color={item.color} />}
{item.shape === 'dotted-square' && <DottedSquare color={item.color} />}
{item.shape === 'line' && <Line color={item.color} lineStyle={item.style ?? 'solid'} />}
{item.shape === 'circle' && <Circle color={item.color} />}
</Item>
);
Expand All @@ -64,8 +54,8 @@ export function Legend({ items, columns }: LegendProps) {
const List = styled.ul<{ columns?: number }>(({ columns }) =>
css({
listStyle: 'none',
px: 0,
m: 0,
paddingX: 0,
margin: 0,
fontSize: 1,
color: 'gray7',
columns,
Expand All @@ -75,11 +65,11 @@ const List = styled.ul<{ columns?: number }>(({ columns }) =>

const Item = styled.li(
css({
my: 1,
mr: 3,
marginY: space[1],
marginRight: space[3],
position: 'relative',
display: 'inline-block',
pl: '25px', // alignment with shape
paddingLeft: '25px', // alignment with shape
})
);

Expand Down Expand Up @@ -109,31 +99,14 @@ const Shape = styled.div<{ color: string }>((x) =>
function DottedSquare({ color }: { color: string }) {
return (
<Shape color="white" css={css({ top: '3px' })}>
<svg width={16} height={16} viewBox={`0 0 ${16} ${16}`}>
<svg width={'16px'} height={'16px'} viewBox={`0 0 ${16} ${16}`}>
<defs>
<pattern
id="dotted_legend"
width="4"
height="4"
patternUnits="userSpaceOnUse"
>
<line
x1="0"
y1="4"
x2="0"
y2="0"
style={{ stroke: color, strokeWidth: 4, strokeDasharray: 2 }}
/>
<pattern id="dotted_legend" width="4" height="4" patternUnits="userSpaceOnUse">
<line x1="0" y1="4" x2="0" y2="0" style={{ stroke: color, strokeWidth: 4, strokeDasharray: 2 }} />
</pattern>
</defs>
<g>
<rect
x={0}
y={0}
fill={`url(#dotted_legend)`}
width={16}
height={16}
/>
<rect x={0} y={0} fill={`url(#dotted_legend)`} width={'16px'} height={'16px'} />
</g>
</svg>
</Shape>
Expand Down Expand Up @@ -170,18 +143,14 @@ const Circle = styled(Shape)(
})
);

const Line = styled.div<{ color: string; lineStyle: LegendLineStyle }>(
({ color, lineStyle }) =>
css({
display: 'block',
position: 'absolute',
borderTopColor: color as SystemStyleObject,
borderTopStyle: lineStyle,
borderTopWidth: '3px',
top: '10px',
width: '15px',
height: 0,
borderRadius: '2px',
left: 0,
})
const Line = styled(Shape)<{ color: string; lineStyle: LegendLineStyle }>(({ color, lineStyle }) =>
css({
borderTopColor: color as SystemStyleObject,
borderTopStyle: lineStyle,
borderTopWidth: '3px',
top: '10px',
width: '15px',
height: '0',
borderRadius: '2px',
})
);
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export function useLegendItems<T extends TimestampedValue>(
const legendItems = config
.filter(isVisible)
.filter((configItem) => !configItem?.hideInLegend)

.map<LegendItem | undefined>((x) => {
switch (x.type) {
case 'split-area':
Expand Down Expand Up @@ -111,7 +112,6 @@ export function useLegendItems<T extends TimestampedValue>(
* legend when there's at least two items.
*/
const isLegendRequired = forceLegend || legendItems.length + splitLegendGroups.length > 1;

return {
legendItems: isLegendRequired ? legendItems : undefined,
splitLegendGroups: splitLegendGroups.length > 0 ? splitLegendGroups : undefined,
Expand Down
Loading

0 comments on commit 5447cca

Please sign in to comment.