diff --git a/components/GroupedBarGraph.module.css b/components/GroupedBarGraph.module.css index 96ab995..4e6dcd0 100644 --- a/components/GroupedBarGraph.module.css +++ b/components/GroupedBarGraph.module.css @@ -1,5 +1,6 @@ .wrapper { display: flex; + flex-direction: column; align-items: center; width: min-content; } @@ -35,4 +36,5 @@ .legend { display: flex; margin: calc(16rem / 16); + justify-content: center; } diff --git a/components/GroupedBarGraph.tsx b/components/GroupedBarGraph.tsx index 28ef034..bce8fdf 100644 --- a/components/GroupedBarGraph.tsx +++ b/components/GroupedBarGraph.tsx @@ -49,7 +49,18 @@ interface GroupedBarGraphProps { valueAxisLabelSize?: number; /** Controls the distance between the value axis label and the value axis. */ valueAxisLabelOffset?: number; - legendProps?: LegendProps; + /** Margin for each item in the legend */ + itemMargin?: string; + /** Minimum width of the graph. */ + minWidth?: number; + /** Breakpoint width of graph where alernating labels are displayed. Only for Vertical graphs */ + widthAlternatingLabel?: number; + /** Space added to the bottom of the graph to show overflowing labels. Only for Vertical graphs */ + alternatingLabelSpace?: number; + /** Default position of labels in x-axis, in px. */ + defaultLabelDy?: string; + /** Position of lower labels in x-axis, in px. Only for Vertical graphs */ + lowerLabelDy?: string; } // Best format for props @@ -66,38 +77,21 @@ interface BarGroupData { [key: string]: string | number; } -interface LegendProps { - /** Position of the legend, relative to the graph. */ - position?: "top" | "right"; - /** Font size of the labels in the legend, in pixels. Default is 16px. */ - itemLabelSize?: number; - /** Gap between items in the legend, in pixels. */ - itemGap?: number; - /** Distance between the legend and other adjacent elements, in pixels. */ - margin?: { - top?: number; - bottom?: number; - left?: number; - right?: number; - }; -} - // BAR_PADDING must be in the range [0, 1) const BAR_PADDING = 0.2; const BAR_TEXT_PADDING = 12; const DEFAULT_LABEL_SIZE = 16; -const DEFAULT_LEGEND_GAP = 16; export function GroupedBarGraphVertical(props: GroupedBarGraphProps) { const { data: propsData, barColors, barHoverColorsMap, - width, height, margin, className, + minWidth = 500, categoryTickLabelSize = DEFAULT_LABEL_SIZE, valueTickLabelSize = DEFAULT_LABEL_SIZE, hoverLabelSize, @@ -107,15 +101,17 @@ export function GroupedBarGraphVertical(props: GroupedBarGraphProps) { valueAxisLabel, valueAxisLabelSize = DEFAULT_LABEL_SIZE, valueAxisLabelOffset = 0, - legendProps, + itemMargin = "0 0 0 15px", + widthAlternatingLabel = 600, + alternatingLabelSpace = 80, + defaultLabelDy = `0px`, + lowerLabelDy = `30px`, } = props; - - const { - position: legendPosition = "right", - itemLabelSize: legendLabelSize = DEFAULT_LABEL_SIZE, - itemGap: legendItemGap = DEFAULT_LEGEND_GAP, - margin: legendMargin = {}, - } = legendProps ?? {}; + const width = props.width < minWidth ? minWidth : props.width; // Ensuring graph's width >= minWidth + const alternatingLabel = width <= widthAlternatingLabel; + const final_margin_bottom = alternatingLabel + ? margin.bottom + alternatingLabelSpace + : margin.bottom; const data: BarGroupData[] = propsData.map((datum: GroupedBarGraphData) => { return { category: datum.category, ...datum.values }; @@ -139,7 +135,7 @@ export function GroupedBarGraphVertical(props: GroupedBarGraphProps) { .flat(); const categoryMax = width - margin.left - margin.right; - const valueMax = height - margin.top - margin.bottom; + const valueMax = height - margin.top - final_margin_bottom; const getCategory = (d: BarGroupData) => d.category; @@ -168,10 +164,15 @@ export function GroupedBarGraphVertical(props: GroupedBarGraphProps) { return (