Fix Mobile Vertical Bar Graph Labels (Closes #50) (#83)
continuous-integration/drone/push Build is passing Details

* Add alternating label functionality to vertical bar graphs when the width of the graph reaches its `minWidth`
* Add `minWidth` prop to horizontal and vertical bar graphs, by default, set to 500 (make a PR to contain these default prop values)
* Add overflow scroll on mobile for horizontal and vertical bar graphs

https://fix-mobile-bug-labels-csc-class-profile-stag-snedadah.k8s.csclub.cloud/
Co-authored-by: e26chiu <e26chiu@csc.uwaterloo.ca>
Co-authored-by: shahanneda <shahan.neda@gmail.com>
Reviewed-on: #83
Reviewed-by: Shahan Nedadahandeh <snedadah@csclub.uwaterloo.ca>
This commit is contained in:
Mark Chiu 2022-11-13 18:36:34 -05:00
parent fb9c5243ab
commit aa25b8451b
5 changed files with 48 additions and 13 deletions

View File

@ -43,6 +43,16 @@ interface BarGraphProps {
valueAxisLabelSize?: number; valueAxisLabelSize?: number;
/** Controls the distance between the value axis label and the value axis. */ /** Controls the distance between the value axis label and the value axis. */
valueAxisLabelOffset?: number; valueAxisLabelOffset?: number;
/** 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;
} }
interface BarGraphData { interface BarGraphData {
@ -54,11 +64,11 @@ const DEFAULT_LABEL_SIZE = 16;
export function BarGraphHorizontal(props: BarGraphProps) { export function BarGraphHorizontal(props: BarGraphProps) {
const { const {
width,
height, height,
margin, margin,
data, data,
className, className,
minWidth = 500,
categoryTickLabelSize = DEFAULT_LABEL_SIZE, categoryTickLabelSize = DEFAULT_LABEL_SIZE,
valueTickLabelSize = DEFAULT_LABEL_SIZE, valueTickLabelSize = DEFAULT_LABEL_SIZE,
hoverLabelSize, hoverLabelSize,
@ -68,8 +78,9 @@ export function BarGraphHorizontal(props: BarGraphProps) {
valueAxisLabel, valueAxisLabel,
valueAxisLabelSize = DEFAULT_LABEL_SIZE, valueAxisLabelSize = DEFAULT_LABEL_SIZE,
valueAxisLabelOffset = 0, valueAxisLabelOffset = 0,
defaultLabelDy = "0",
} = props; } = props;
const width = props.width < minWidth ? minWidth : props.width; // Ensuring graph's width >= minWidth
const barPadding = 0.4; const barPadding = 0.4;
const categoryMax = height - margin.top - margin.bottom; const categoryMax = height - margin.top - margin.bottom;
@ -163,8 +174,6 @@ export function BarGraphHorizontal(props: BarGraphProps) {
return { return {
...leftTickLabelProps(), ...leftTickLabelProps(),
className: styles.tickLabel, className: styles.tickLabel,
dx: "-0.5rem",
dy: "0.25rem",
fontSize: `${categoryTickLabelSize / 16}rem`, fontSize: `${categoryTickLabelSize / 16}rem`,
}; };
}} }}
@ -186,7 +195,7 @@ export function BarGraphHorizontal(props: BarGraphProps) {
return { return {
...bottomTickLabelProps(), ...bottomTickLabelProps(),
className: styles.tickLabel, className: styles.tickLabel,
dy: "0.25rem", dy: defaultLabelDy,
fontSize: `${valueTickLabelSize / 16}rem`, fontSize: `${valueTickLabelSize / 16}rem`,
}; };
}} }}
@ -203,11 +212,11 @@ export function BarGraphHorizontal(props: BarGraphProps) {
export function BarGraphVertical(props: BarGraphProps) { export function BarGraphVertical(props: BarGraphProps) {
const { const {
width,
height, height,
margin, margin,
data, data,
className, className,
minWidth = 500,
categoryTickLabelSize = DEFAULT_LABEL_SIZE, categoryTickLabelSize = DEFAULT_LABEL_SIZE,
valueTickLabelSize = DEFAULT_LABEL_SIZE, valueTickLabelSize = DEFAULT_LABEL_SIZE,
hoverLabelSize, hoverLabelSize,
@ -217,12 +226,20 @@ export function BarGraphVertical(props: BarGraphProps) {
valueAxisLabel, valueAxisLabel,
valueAxisLabelSize = DEFAULT_LABEL_SIZE, valueAxisLabelSize = DEFAULT_LABEL_SIZE,
valueAxisLabelOffset = 0, valueAxisLabelOffset = 0,
widthAlternatingLabel = 600,
alternatingLabelSpace = 80,
defaultLabelDy = `0px`,
lowerLabelDy = `30px`,
} = props; } = props;
const width = props.width < minWidth ? minWidth : props.width; // Ensuring graph's width >= minWidth
const barPadding = 0.4; const barPadding = 0.4;
const alternatingLabel = width <= widthAlternatingLabel;
const final_margin_bottom = alternatingLabel
? margin.bottom + alternatingLabelSpace
: margin.bottom;
const categoryMax = width - margin.left - margin.right; 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: BarGraphData) => d.category; const getCategory = (d: BarGraphData) => d.category;
const getValue = (d: BarGraphData) => d.value; const getValue = (d: BarGraphData) => d.value;
@ -308,11 +325,12 @@ export function BarGraphVertical(props: BarGraphProps) {
left={margin.left} left={margin.left}
hideAxisLine hideAxisLine
hideTicks hideTicks
tickLabelProps={() => { tickLabelProps={(value, index) => {
const alternatingDy = index % 2 == 0 ? defaultLabelDy : lowerLabelDy;
return { return {
...bottomTickLabelProps(), ...bottomTickLabelProps(),
className: styles.tickLabel, className: styles.tickLabel,
dy: "-0.25rem", dy: alternatingLabel ? alternatingDy : defaultLabelDy,
fontSize: `${categoryTickLabelSize / 16}rem`, fontSize: `${categoryTickLabelSize / 16}rem`,
width: categoryScale.bandwidth(), width: categoryScale.bandwidth(),
verticalAnchor: "start", verticalAnchor: "start",

View File

@ -45,7 +45,10 @@
.wrapperNoBodyText { .wrapperNoBodyText {
flex-direction: column; flex-direction: column;
align-items: center; }
.wrapperNoBodyText .internalWrapper {
text-align: center;
} }
@media screen and (max-width: 900px) { @media screen and (max-width: 900px) {
@ -61,6 +64,10 @@
.wrapperCenter { .wrapperCenter {
padding: 0; padding: 0;
} }
.horizontalScrollOnMobile {
overflow: scroll;
}
} }
.internalWrapper { .internalWrapper {

View File

@ -37,7 +37,11 @@ export function ComponentWrapper({
<h3>{heading}</h3> <h3>{heading}</h3>
{bodyText ? <p>{bodyText}</p> : null} {bodyText ? <p>{bodyText}</p> : null}
</div> </div>
<div className={styles.internalWrapper}>{children}</div> <div
className={`${styles.internalWrapper} ${styles.horizontalScrollOnMobile}`}
>
{children}
</div>
</div> </div>
); );
} }

View File

@ -2,6 +2,10 @@ html {
scroll-behavior: smooth; scroll-behavior: smooth;
} }
html, body {
overflow-x: hidden;
}
body { body {
/* Theme colours */ /* Theme colours */
--pink: #EF839D; --pink: #EF839D;
@ -68,6 +72,7 @@ body {
color: var(--primary-text); color: var(--primary-text);
font-family: "Inconsolata", monospace; font-family: "Inconsolata", monospace;
margin: 0; margin: 0;
position: relative;
/* Font styling for body */ /* Font styling for body */
font-size: calc(18rem / 16); font-size: calc(18rem / 16);

View File

@ -124,6 +124,7 @@ export default function Demographics() {
width={defaultGraphWidth} width={defaultGraphWidth}
height={defaultGraphHeight} height={defaultGraphHeight}
margin={defaultBarGraphMargin} margin={defaultBarGraphMargin}
widthAlternatingLabel={700}
/> />
</ComponentWrapper> </ComponentWrapper>
@ -189,7 +190,7 @@ export default function Demographics() {
data={D11} data={D11}
width={defaultGraphWidth} width={defaultGraphWidth}
height={defaultGraphHeight} height={defaultGraphHeight}
margin={{ ...defaultBarGraphMargin, ...{ left: 200 } }} margin={{ ...defaultBarGraphMargin, ...{ left: 220 } }}
/> />
</ComponentWrapper> </ComponentWrapper>