Skip to content

Commit 0390cf2

Browse files
Responsive design - chart
1 parent 47e185a commit 0390cf2

File tree

9 files changed

+89
-62
lines changed

9 files changed

+89
-62
lines changed

.eslintrc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010
"parserOptions": {
1111
"ecmaFeatures": {
1212
"jsx": true
13-
},
14-
"project": "./tsconfig.json"
13+
}
1514
},
1615
"plugins": [
1716
"@typescript-eslint",

jest.config.js

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1+
/* eslint-disable no-undef */
12
module.exports = {
2-
// Other configuration above...
3+
// Other configuration above...
34

4-
// Add the next three options if using TypeScript
5-
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json"],
6-
preset: "ts-jest",
7-
roots: ["<rootDir>/src"],
8-
transform: {
9-
"^.+\\.[t|j]sx?$": "ts-jest",
10-
"^.+\\.svg?$": "<rootDir>/transform.js",
11-
"^.+\\.scss?$": "<rootDir>/transform.js"
12-
},
13-
"testEnvironment": "jsdom",
14-
testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$",
5+
// Add the next three options if using TypeScript
6+
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json"],
7+
preset: "ts-jest",
8+
roots: ["<rootDir>/src"],
9+
transform: {
10+
"^.+\\.[t|j]sx?$": "ts-jest",
11+
"^.+\\.svg?$": "<rootDir>/transform.js",
12+
"^.+\\.scss?$": "<rootDir>/transform.js"
13+
},
14+
"testEnvironment": "jsdom",
15+
testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$"
1516
};

src/lib/dot-matrix/Chart.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import React from 'react';
22
import { v4 } from 'uuid';
33
import {
44
getNumberOfDots,
5-
getContainerWidth,
65
getStyles,
76
hasOverlapping
87
} from './utils/utils';
@@ -20,18 +19,25 @@ const Chart = (props: ChartProps) : JSX.Element => {
2019
styles,
2120
data,
2221
overlappingValues,
23-
total
22+
total,
23+
width
2424
} = props;
2525
const {
2626
rows = DEFAULT_ROWS,
2727
columns = DEFAULT_COLUMNS
2828
} = dimensions;
2929

30+
const getDotWidth = (): number => {
31+
let dotWidth = 35;
32+
if (width) {
33+
dotWidth = width / columns - 19;
34+
}
35+
return dotWidth;
36+
}
3037
return (
3138
<div
3239
className={classes.dotsContainer}
3340
style={{
34-
width: `${getContainerWidth(columns)}rem`,
3541
...getStyles(Elements.DotsContainer, styles)
3642
}}
3743
>
@@ -44,6 +50,8 @@ const Chart = (props: ChartProps) : JSX.Element => {
4450
className={classes.eachDot}
4551
style={{
4652
backgroundImage: `linear-gradient(to right, ${data[rowIndex - 1].color} 20%, ${dataItem?.color} 50%)`,
53+
width: `${getDotWidth()}px`,
54+
height: `${getDotWidth()}px`,
4755
...(getStyles(Elements.Dot, styles))
4856
}}
4957
/>
@@ -52,6 +60,8 @@ const Chart = (props: ChartProps) : JSX.Element => {
5260
className={classes.eachDot}
5361
style={{
5462
backgroundColor: dataItem?.color,
63+
width: `${getDotWidth()}px`,
64+
height: `${getDotWidth()}px`,
5565
...(getStyles(Elements.Dot, styles))
5666
}}
5767
key={v4()}

src/lib/dot-matrix/DotMatrix.tsx

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import React from "react";
1+
import React, { useEffect, useState } from "react";
22
import classes from './styles.module.scss';
33
import { DotMatrixPropType } from "./types";
44
import { useDotMatrix } from './custom-hooks/useDotMatrix';
55
import Chart from './Chart';
66
import Legend from './Legend';
7-
import { getLegendPosition, getStyles } from "./utils/utils";
7+
import { getLegendPosition, getStyles, findContainerWidth } from "./utils/utils";
88
import {
99
Elements,
1010
DEFAULT_COLUMNS,
@@ -23,28 +23,50 @@ const DotMatrix = (props: DotMatrixPropType): JSX.Element => {
2323
legendPosition = DEFAULT_LEGEND_POSITION
2424
} = props;
2525

26+
const [width, setWidth] = useState<number>(0);
2627
const [data, total, overlappingValues] = useDotMatrix(dataPoints, dimensions);
28+
29+
useEffect(() => {
30+
findChartContainerWidth();
31+
}, []);
32+
useEffect(() => {
33+
findChartContainerWidth();
34+
}, [showLegend, legendPosition]);
35+
const findChartContainerWidth = (): void => {
36+
const widthValue = findContainerWidth('dots-container');
37+
if (widthValue) setWidth(widthValue);
38+
}
39+
window.onresize = (): void => {
40+
findChartContainerWidth();
41+
};
2742
return (
28-
<div className={classes.container}>
43+
<div
44+
className={classes.container}
45+
>
2946
<div
3047
className={classes.dotsWithLegend}
3148
style={{
3249
...getStyles(Elements.Container, styles),
3350
...(getLegendPosition(legendPosition) as React.CSSProperties)
3451
}}
3552
>
36-
<Chart
37-
styles={styles}
38-
dimensions={dimensions}
39-
data={data}
40-
total={total}
41-
overlappingValues={overlappingValues}
42-
/>
43-
{showLegend && (
44-
<Legend
53+
<div id="dots-container">
54+
<Chart
4555
styles={styles}
56+
dimensions={dimensions}
4657
data={data}
58+
total={total}
59+
width={width}
60+
overlappingValues={overlappingValues}
4761
/>
62+
</div>
63+
{showLegend && (
64+
<div>
65+
<Legend
66+
styles={styles}
67+
data={data}
68+
/>
69+
</div>
4870
)}
4971
</div>
5072
</div>

src/lib/dot-matrix/constants.ts

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,13 @@
11
export const COLOR_PALATTE = [
2-
'#B8255F',
3-
'#96C3EB',
4-
'#DB4035',
5-
'#4073FF',
6-
'#FF9933',
7-
'#884DFF',
8-
'#FAD000',
9-
'#AF38EB',
10-
'#AFB83B',
11-
'#EB96EB',
12-
'#7ECC49',
13-
'#E05194',
14-
'#299438',
15-
'#FF8D85',
16-
'#6ACCBC',
17-
'#808080',
18-
'#158FAD',
19-
'#B8B8B8',
20-
'#14AAF5',
21-
'#CCAC93'
2+
'#fd7f6f',
3+
'#7eb0d5',
4+
'#b2e061',
5+
'#bd7ebe',
6+
'#ffb55a',
7+
'#ffee65',
8+
'#beb9db',
9+
'#fdcce5',
10+
'#8bd3c7'
2211
];
2312

2413
export enum Elements {
@@ -35,5 +24,3 @@ export const DEFAULT_ROWS = 5;
3524
export const DEFAULT_COLUMNS = 12;
3625

3726
export const DEFAULT_LEGEND_POSITION = 'right';
38-
39-
export const CONTAINER_WIDTH_CONVERSION_FACTOR = 2.6;

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
.container {
2-
margin: 10px;
3-
width: fit-content;
2+
padding: 10px;
3+
width: inherit;
44
.dotsWithLegend {
55
width: 100%;
66
display: flex;
7-
gap: 50px;
8-
justify-content: space-between;
7+
gap: 20px;
98
align-items: end;
109
}
1110
.dotsContainer {
1211
display: flex;
1312
flex-wrap: wrap;
1413
gap: 6px;
15-
width: 490px;
14+
width: calc(100% - 100px);
1615
.eachDot {
1716
border-radius: 50%;
1817
width: 2.2rem;
@@ -39,5 +38,6 @@
3938
gap: 5px;
4039
border: 1px solid gainsboro;
4140
padding: 7px;
41+
width: max-content;
4242
}
4343
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ export interface ChartProps {
88
styles: StyleProp,
99
data: DataPointType[],
1010
overlappingValues: number[],
11-
total: number
11+
total: number,
12+
width: number
1213
}
1314

1415
export type DimensionProp = {

src/lib/dot-matrix/utils/utils.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
import { DataPointType, StyleProp } from "../types";
2-
import { CONTAINER_WIDTH_CONVERSION_FACTOR, Elements } from '../constants';
2+
import { Elements } from '../constants';
33
export const getNumberOfDots = (point: DataPointType, rows: number, columns: number, total: number): number => {
44
const percentage = point.count / total;
55
return Math.floor(percentage * rows * columns);
66
}
77

8-
export const getContainerWidth = (columns: number): number => columns * CONTAINER_WIDTH_CONVERSION_FACTOR;
9-
108
export const isColorPresent = (dataPoints: DataPointType[], color: string, dataValues: DataPointType[] = []): boolean => {
119
const findColor = dataPoints?.find((e) => e.color === color);
1210
const colorInLocal = dataValues?.find((e) => e.color === color);
@@ -40,4 +38,13 @@ export const getStyles = (element: Elements, styles: StyleProp): object => {
4038

4139
export const hasOverlapping = (values: number[], indexRow: number, indexColumn: number): boolean => (
4240
indexColumn === 0 && indexRow > 0 && values[indexRow - 1] < 1 && values[indexRow - 1] !== 0
43-
);
41+
);
42+
43+
export const findContainerWidth = (id: string):number => {
44+
const element = document.getElementById(id);
45+
let value = 0;
46+
if (element) {
47+
value = element.clientWidth;
48+
}
49+
return value;
50+
}

src/lib/tests/dotMatrix.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ test("If the color is used in the Dot Matrix Chart", async () => {
5151
if (dom) {
5252
const dot = await getById(dom.container, "each-category-0-0");
5353
if (!dot) throw Error("Dot Absent");
54-
expect(dot.style._values).toEqual({ "background-color": `black` })
54+
expect(dot.style._values["background-color"]).toBe('black')
5555
} else {
5656
throw Error("No DOM Found");
5757
}

0 commit comments

Comments
 (0)