Skip to content

Commit b5e4dfb

Browse files
Legend(render prop) And Chart component separation
1 parent bbf9c44 commit b5e4dfb

File tree

6 files changed

+174
-76
lines changed

6 files changed

+174
-76
lines changed

src/lib/dot-matrix/Chart.tsx

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import React from 'react';
2+
import { v4 } from 'uuid';
3+
import { getNumberOfDots, getContainerWidth } from './utils/utils';
4+
import {
5+
Elements,
6+
DEFAULT_COLUMNS,
7+
DEFAULT_ROWS
8+
} from "./constants";
9+
import { ChartProps, DataPointType } from './types';
10+
import classes from './styles.module.scss';
11+
12+
const Chart = (props: ChartProps) : JSX.Element => {
13+
const {
14+
dimensions = {},
15+
getStyles,
16+
data,
17+
overlappingValues,
18+
total
19+
} = props;
20+
const {
21+
rows = DEFAULT_ROWS,
22+
columns = DEFAULT_COLUMNS
23+
} = dimensions;
24+
return (
25+
<div
26+
className={classes.dotsContainer}
27+
style={{
28+
width: `${getContainerWidth(columns)}rem`,
29+
...getStyles(Elements.DotsContainer)
30+
}}
31+
>
32+
{data?.map((eachPoint: DataPointType, rowIndex: number) => (
33+
<React.Fragment key={v4()}>
34+
{eachPoint && Array.apply(null, Array(getNumberOfDots(eachPoint, rows, columns, total))).map((item: null, columnIndex: number) => (
35+
<div id="dot-matrix-dots" key={v4()}>
36+
{(columnIndex === 0 && rowIndex > 0 && overlappingValues[rowIndex - 1] < 1 && overlappingValues[rowIndex - 1] !== 0 && (
37+
<div
38+
className={classes.eachDot}
39+
style={{
40+
backgroundImage: `linear-gradient(to right, ${data[rowIndex - 1].color} 20%, ${eachPoint?.color} 50%)`,
41+
...(getStyles(Elements.Dot))
42+
}}
43+
/>
44+
)) || (
45+
<div
46+
className={classes.eachDot}
47+
style={{
48+
backgroundColor: eachPoint?.color,
49+
...(getStyles(Elements.Dot))
50+
}}
51+
key={v4()}
52+
id={`each-category-${rowIndex}-${columnIndex}`}
53+
/>
54+
)}
55+
</div>
56+
))}
57+
</React.Fragment>
58+
))}
59+
</div>
60+
)
61+
};
62+
export default Chart;

src/lib/dot-matrix/DotMatrix.tsx

Lines changed: 47 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,27 @@
11
import React from "react";
2-
import { v4 } from 'uuid';
32
import classes from './styles.module.scss';
4-
import { DotMatrixPropType, DataPointType } from "./types";
3+
import { DotMatrixPropType } from "./types";
54
import { useDotMatrix } from './custom-hooks/useDotMatrix';
5+
import Chart from './Chart';
6+
import Legend from './Legend';
67
import {
78
Elements,
89
DEFAULT_COLUMNS,
9-
DEFAULT_ROWS
10+
DEFAULT_ROWS,
11+
DEFAULT_LEGEND_POSITION
1012
} from "./constants";
11-
import { getNumberOfDots, getContainerWidth } from './utils/utils';
1213
const DotMatrix = (props: DotMatrixPropType): JSX.Element => {
1314
const {
1415
dataPoints,
1516
dimensions = {
1617
rows: DEFAULT_ROWS,
1718
columns: DEFAULT_COLUMNS
1819
},
19-
styles = {}
20+
styles = {},
21+
showLegend,
22+
legendPosition = DEFAULT_LEGEND_POSITION
2023
} = props;
2124

22-
const {
23-
rows = DEFAULT_ROWS,
24-
columns = DEFAULT_ROWS
25-
} = dimensions;
26-
2725
const [data, total, overlappingValues] = useDotMatrix(dataPoints, dimensions);
2826
const getStyles = (element: Elements): object => {
2927
const getElementStyle = styles[element];
@@ -34,71 +32,52 @@ const DotMatrix = (props: DotMatrixPropType): JSX.Element => {
3432
};
3533

3634

35+
const getLegendPosition = (): {flexDirection: string, alignItems: string} => {
36+
let flexDirection = '';
37+
let alignItems = 'end';
38+
switch (legendPosition) {
39+
case 'left':
40+
flexDirection = 'row-reverse';
41+
break;
42+
case 'right':
43+
flexDirection = 'row';
44+
break;
45+
case 'top':
46+
flexDirection = 'column-reverse';
47+
alignItems = 'center';
48+
break;
49+
case 'bottom':
50+
flexDirection = 'column';
51+
alignItems = 'center';
52+
break;
53+
default:
54+
flexDirection = 'row'
55+
break;
56+
}
57+
return { flexDirection, alignItems};
58+
}
3759
return (
3860
<div className={classes.container}>
3961
<div
4062
className={classes.dotsWithLegend}
4163
style={{
42-
...getStyles(Elements.Container)
64+
...getStyles(Elements.Container),
65+
...(getLegendPosition() as React.CSSProperties)
4366
}}
4467
>
45-
<div
46-
className={classes.dotsContainer}
47-
style={{
48-
width: `${getContainerWidth(columns)}rem`,
49-
...getStyles(Elements.DotsContainer)
50-
}}
51-
>
52-
{data?.map((eachPoint: DataPointType, rowIndex: number) => (
53-
<React.Fragment key={v4()}>
54-
{eachPoint && Array.apply(null, Array(getNumberOfDots(eachPoint, rows, columns, total))).map((item: null, columnIndex: number) => (
55-
<div id="dot-matrix-dots" key={v4()}>
56-
{(columnIndex === 0 && rowIndex > 0 && overlappingValues[rowIndex - 1] < 1 && overlappingValues[rowIndex - 1] !== 0 && (
57-
<div
58-
className={classes.eachDot}
59-
style={{
60-
backgroundImage: `linear-gradient(to right, ${data[rowIndex - 1].color} 20%, ${eachPoint?.color} 50%)`,
61-
...(getStyles(Elements.Dot))
62-
}}
63-
/>
64-
)) || (
65-
<div
66-
className={classes.eachDot}
67-
style={{
68-
backgroundColor: eachPoint?.color,
69-
...(getStyles(Elements.Dot))
70-
}}
71-
key={v4()}
72-
id={`each-category-${rowIndex}-${columnIndex}`}
73-
/>
74-
)}
75-
</div>
76-
))}
77-
</React.Fragment>
78-
))}
79-
</div>
80-
<div
81-
className={classes.legends}
82-
style={{ ...getStyles(Elements.LegendContainer)}}
83-
>
84-
{data?.map((point: DataPointType) => (
85-
<div className={classes.legend} key={v4()}>
86-
<div
87-
className={classes.legendDot}
88-
style={{
89-
backgroundColor: point?.color,
90-
...(getStyles(Elements.LegendDot))
91-
}}
92-
/>
93-
<div
94-
className={classes.name}
95-
style={{ ...getStyles(Elements.LegendName)}}
96-
>
97-
{point.name}
98-
</div>
99-
</div>
100-
))}
101-
</div>
68+
<Chart
69+
getStyles={getStyles}
70+
dimensions={dimensions}
71+
data={data}
72+
total={total}
73+
overlappingValues={overlappingValues}
74+
/>
75+
{showLegend && (
76+
<Legend
77+
getStyles={getStyles}
78+
data={data}
79+
/>
80+
)}
10281
</div>
10382
</div>
10483
)

src/lib/dot-matrix/Legend.tsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import React from 'react';
2+
import { v4 } from 'uuid';
3+
import { DataPointType, LegendProps } from "./types";
4+
import {
5+
Elements
6+
} from './constants';
7+
import classes from './styles.module.scss';
8+
9+
const Legend = (props: LegendProps): JSX.Element => {
10+
const {
11+
getStyles,
12+
data
13+
} = props;
14+
return (
15+
<div
16+
className={classes.legends}
17+
style={{ ...getStyles(Elements.LegendContainer)}}
18+
>
19+
{data?.map((point: DataPointType) => (
20+
<div className={classes.legend} key={v4()}>
21+
<div
22+
className={classes.legendDot}
23+
style={{
24+
backgroundColor: point?.color,
25+
...(getStyles(Elements.LegendDot))
26+
}}
27+
/>
28+
<div
29+
className={classes.name}
30+
style={{ ...getStyles(Elements.LegendName)}}
31+
>
32+
{point.name}
33+
</div>
34+
</div>
35+
))}
36+
</div>
37+
)
38+
};
39+
40+
export default Legend;

src/lib/dot-matrix/constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,6 @@ export const DEFAULT_ROWS = 5;
3434

3535
export const DEFAULT_COLUMNS = 12;
3636

37+
export const DEFAULT_LEGEND_POSITION = 'right';
38+
3739
export const CONTAINER_WIDTH_CONVERSION_FACTOR = 2.6;

src/lib/dot-matrix/styles.module.scss

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@
1515
width: 490px;
1616
.eachDot {
1717
border-radius: 50%;
18-
width: 35px;
19-
height: 35px;
18+
width: 2.2rem;
19+
height: 2.2rem;
2020
}
2121
}
2222
.legendDot {
2323
border-radius: 50%;
24-
width: 25px;
25-
height: 25px;
24+
width: 1.6rem;
25+
height: 1.6rem;
2626
}
2727
.legend {
2828
display: flex;

src/lib/dot-matrix/types.d.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,28 @@ export interface DataPointType {
33
count: number,
44
color?: string
55
}
6+
export interface ChartProps {
7+
dimensions?: DimensionProp,
8+
getStyles: (string) => {},
9+
data: DataPointType[],
10+
overlappingValues: number[],
11+
total: number
12+
}
13+
14+
export type DimensionProp = {
15+
rows?: number;
16+
columns?: number
17+
}
618

19+
export interface LegendProps {
20+
getStyles: (string) => {},
21+
data: DataPointType[]
22+
}
723
export interface DotMatrixPropType {
824
dataPoints: DataPointType[],
9-
dimensions?: {
10-
rows?: number,
11-
columns?: number
12-
}
25+
dimensions?: DimensionProp,
26+
showLegend?: boolean,
27+
legendPosition?: 'left' | 'right' | 'top' | 'bottom'
1328
styles?: {
1429
Dot?: () => {},
1530
DotsContainer?: () => {},

0 commit comments

Comments
 (0)