Skip to content

Commit

Permalink
Add Pie chart (#593)
Browse files Browse the repository at this point in the history
* WIP

* clean up
  • Loading branch information
morewings authored Dec 28, 2022
1 parent b1cad40 commit 0b308e2
Show file tree
Hide file tree
Showing 17 changed files with 329 additions and 43 deletions.
3 changes: 2 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_size = 2
indent_style = space
insert_final_newline = true
max_line_length = 110
Expand All @@ -16,6 +16,7 @@ ij_visual_guides = none
ij_wrap_on_typing = false

[*.css]
indent_size = 2
ij_css_align_closing_brace_with_properties = false
ij_css_blank_lines_around_nested_selector = 1
ij_css_blank_lines_between_blocks = 1
Expand Down
3 changes: 3 additions & 0 deletions .stylelintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
"custom-properties",
"declarations"
],
"custom-property-pattern": ["^[a-z][a-zA-Z0-9]+$", {
"message": "Expected \"%s\" variable name to be lower camelCase"
}],
"order/properties-alphabetical-order": true,
"selector-pseudo-class-no-unknown": [true, {
"ignorePseudoClasses": ["global"]
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"react-dom": "18.2.0",
"react-modal": "^3.16.1",
"react-redux": "^8.0.5",
"recharts": "^2.2.0",
"redux": "^4.2.0",
"the-new-css-reset": "^1.8.2"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import React from 'react';
import PropTypes from 'prop-types';

import classes from './Stats.module.css';
import classes from './Ancestry.module.css';

const Stats = ({completion, nodeChildrenAmount, tier}) => (
<div className={classes.stats}>
<h3>Stats</h3>
<div className={classes.chart}>{completion}</div>
export const Ancestry = ({nodeChildrenAmount, tier}) => (
<div className={classes.ancestry}>
<h3>Ancestry</h3>
<div>
<div className={classes.tier}>
<h4>Tier</h4>
Expand All @@ -20,10 +19,7 @@ const Stats = ({completion, nodeChildrenAmount, tier}) => (
</div>
);

Stats.propTypes = {
Ancestry.propTypes = {
nodeChildrenAmount: PropTypes.number.isRequired,
completion: PropTypes.number.isRequired,
tier: PropTypes.number.isRequired,
};

export default Stats;
Original file line number Diff line number Diff line change
@@ -1,32 +1,19 @@
.stats {
.ancestry {
display: flex;
flex-wrap: wrap;
padding: var(--baseUnit) calc(2 * var(--baseUnit)) calc(4 * var(--baseUnit));
padding: var(--baseUnit) calc(2 * var(--baseUnit)) calc(2 * var(--baseUnit));

& h3 {
color: var(--darkColor);
font-size: 16px;
font-weight: 300;
letter-spacing: 1px;
margin-bottom: var(--baseUnit);
text-align: center;
text-align: left;
text-transform: uppercase;
width: 100%;
}

& .chart {
--size: calc(16 * var(--baseUnit));

background: var(--iconColor);
border-radius: var(--size);
color: white;
height: var(--size);
line-height: var(--size);
margin-right: calc(2 * var(--baseUnit));
text-align: center;
width: var(--size);
}

& .tier,
& .ancestors {
align-items: center;
Expand Down
1 change: 1 addition & 0 deletions src/components/Node/Ancestry/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {Ancestry} from './Ancestry';
1 change: 1 addition & 0 deletions src/components/Node/Description/Description.module.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.description {
padding: var(--baseMargin) calc(2 * var(--baseUnit));
width: 100%;

& h3 {
color: var(--darkColor);
Expand Down
8 changes: 6 additions & 2 deletions src/components/Node/Node.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import {useDeleteNodeModal, useEditNodeModal} from '@/components/ModalManager';
import {useNodeData, useChildrenCompletion} from '@/features/structure';
import {Button} from '@/ui/Button';
import {FooterSeparator} from '@/ui/FooterSeparator';
import {PieChart} from '@/components/PieChart';

import Stats from './Stats';
import {Ancestry} from './Ancestry';
import Description from './Description';
import NodeHeader from './NodeHeader';
import NodeActions from './NodeActions';
Expand Down Expand Up @@ -69,7 +70,10 @@ const Node = ({id, toggleNode, activeNode}) => {
{isOpen && (
<main>
{description && <Description text={description} />}
<Stats completion={completion} tier={generation} nodeChildrenAmount={childNodes.length} />
<div className={classes.stats}>
<PieChart color={color} completion={completion} />
<Ancestry tier={generation} nodeChildrenAmount={childNodes.length} />
</div>
<NodeActions deleteNode={handleDelete} />
</main>
)}
Expand Down
4 changes: 4 additions & 0 deletions src/components/Node/Node.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
overflow: hidden;
position: relative;

& .stats {
display: flex;
}

& main,
& .header {
background-color: var(--backgroundHighColor);
Expand Down
1 change: 0 additions & 1 deletion src/components/Node/Stats/index.js

This file was deleted.

45 changes: 45 additions & 0 deletions src/components/PieChart/PieChart.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from 'react';
import PropTypes from 'prop-types';
import {Cell, Pie, PieChart as PieChartGeneric} from 'recharts';
import {useVariable} from 'css-vars-hook';

import {useChartData} from './useChartData';
import classes from './PieChart.module.css';

const normalizeColor = color => {
return color === '' ? '#4a90e2' : color;
};

export const PieChart = ({completion, color}) => {
const chartData = useChartData(completion);
const {setRef} = useVariable('color', color);
return (
<div className={classes.chart}>
<PieChartGeneric width={96} height={96}>
<Pie
data={chartData}
dataKey="value"
nameKey="name"
cx="50%"
cy="50%"
innerRadius={24}
outerRadius={48}
stroke="none"
label={false}>
{chartData.map((entry, index) => {
const segmentColor = index === 0 ? normalizeColor(color) : 'rgba(66, 66, 66, 0.33)';
return <Cell key={`cell-${index}`} fill={segmentColor} />;
})}
</Pie>
</PieChartGeneric>
<div ref={setRef} className={classes.completion}>
{completion}%
</div>
</div>
);
};

PieChart.propTypes = {
completion: PropTypes.number.isRequired,
color: PropTypes.string.isRequired,
};
23 changes: 23 additions & 0 deletions src/components/PieChart/PieChart.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.chart {
--size: calc(16 * var(--baseUnit));

height: var(--size);
margin-left: calc(2 * var(--baseUnit));
margin-right: calc(2 * var(--baseUnit));
position: relative;
width: var(--size);
}

.completion {
--size: var(--chartLabelFontSize);
--color: black;

color: var(--color);
font-size: var(--size);
height: var(--size);
left: 50%;
line-height: var(--size);
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
}
1 change: 1 addition & 0 deletions src/components/PieChart/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {PieChart} from './PieChart';
17 changes: 17 additions & 0 deletions src/components/PieChart/useChartData.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* React hook converts completion to chart compatible format
* @param {Number} completion
* @return {Array.<{name: String, value: Number}>}
*/
export const useChartData = completion => {
return [
{
name: 'Completed',
value: completion,
},
{
name: 'Non-completed',
value: 100 - completion,
},
];
};
25 changes: 13 additions & 12 deletions src/ui/ThemeProvider/rootTheme.css
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
:root {
--name: 'default';
--name: "default";
--baseUnit: 6px;
--bgColor: #4a90e2;
--accentColor: #cc8110;
--secondaryColor: rgba(255, 211, 110, 0.33);
--secondaryColor: rgb(255 211 110 / 33%);
--darkColor: #424242;
--dangerColor: #f23005;
--actionColor: rgba(46, 56, 255, 1);
--actionColor: rgb(46 56 255 / 100%);
--confirmColor: #639423;
--modalBgColor: rgba(66, 66, 66, 0.66);
--iconColor: rgba(66, 66, 66, 0.66);
--iconLightColor: rgba(66, 66, 66, 0.33);
--modalBgColor: rgb(66 66 66 / 66%);
--iconColor: rgb(66 66 66 / 66%);
--iconLightColor: rgb(66 66 66 / 33%);
--headerHeight: 56px;
--footerHeight: calc(6 * var(--baseUnit));
--columnHeight: calc(100 * var(--baseUnit));
--baseMargin: 12px;
--baseBorderRadius: 6px;
--backgroundLowColor: rgba(242, 242, 242, 0.8);
--backgroundMiddleColor: rgba(242, 242, 242, 0.66);
--backgroundMiddleColorHover: rgba(242, 242, 242, 1);
--backgroundHighColor: rgba(255, 255, 255, 0.66);
--backgroundFullColor: rgba(242, 242, 242, 1);
--backgroundLowColor: rgb(242 242 242 / 80%);
--backgroundMiddleColor: rgb(242 242 242 / 66%);
--backgroundMiddleColorHover: rgb(242 242 242 / 100%);
--backgroundHighColor: rgb(255 255 255 / 66%);
--backgroundFullColor: rgb(242 242 242 / 100%);
--headerFontSize: 16px;
--modalWidth: calc(66 * var(--baseUnit));
--modalButtonColor: rgba(230, 230, 230, 1);
--modalButtonColor: rgb(230 230 230 / 100%);
--imageTitleColor: var(--iconColor);
--chartLabelFontSize: 14px;
}
1 change: 1 addition & 0 deletions src/ui/ThemeProvider/theme.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ export const theme = {
modalWidth: 'calc(66 * var(--baseUnit))',
modalButtonColor: 'rgba(230, 230, 230, 1)',
imageTitleColor: 'var(--iconColor)',
chartLabelFontSize: '14px',
};
Loading

1 comment on commit 0b308e2

@vercel
Copy link

@vercel vercel bot commented on 0b308e2 Dec 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

structure – ./

structure-morewings.vercel.app
structure-git-master-morewings.vercel.app
structure.ninja

Please sign in to comment.