Skip to content

Commit 900447b

Browse files
committed
Dashboard keynumbers improvement
1 parent 1e5a474 commit 900447b

File tree

5 files changed

+197
-136
lines changed

5 files changed

+197
-136
lines changed

src/Dashboard/KeyNumbers/KeyNumbers.js

Lines changed: 92 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -2,106 +2,100 @@ import React from 'react'
22
import clsx from 'clsx'
33
import PropTypes from 'prop-types'
44
import { makeStyles } from '@material-ui/core/styles'
5-
import { Paper, Grid, Typography } from '@material-ui/core'
5+
import { Paper, Box, Grid, Typography } from '@material-ui/core'
66
import { Line } from 'react-chartjs-2'
77

8-
import { subscriptionsTrendChart } from './data'
8+
import { generateTrendChartData } from './data'
9+
10+
const numbers = [
11+
{
12+
name: 'Monthly Revenue',
13+
value: '24350$',
14+
change: '+13%',
15+
trend: 'positive',
16+
chart: generateTrendChartData({
17+
name: 'Monthly Revenue',
18+
from: Math.round(24350 / 1.13),
19+
to: 24350,
20+
length: 15,
21+
}),
22+
},
23+
{
24+
name: 'Total Users',
25+
value: 48205,
26+
change: '+10%',
27+
trend: 'positive',
28+
chart: generateTrendChartData({
29+
name: 'Total Users',
30+
from: Math.round(48205 / 1.1),
31+
to: 48205,
32+
}),
33+
},
34+
{
35+
name: 'Subscriptions',
36+
value: 139,
37+
change: '-5%',
38+
trend: 'negative',
39+
chart: generateTrendChartData({
40+
name: 'Subscriptions',
41+
from: 139,
42+
to: Math.round(139 / 1.05),
43+
length: 15,
44+
}),
45+
},
46+
{
47+
name: 'Monthly Churn',
48+
value: 13,
49+
change: '-10%',
50+
trend: 'positive',
51+
chart: generateTrendChartData({
52+
name: 'Monthly Churn',
53+
from: 13,
54+
to: Math.random(13 / 1.1),
55+
length: 15,
56+
}),
57+
},
58+
]
959

1060
const KeyNumbers = props => {
1161
const classes = useStyles()
1262

1363
return (
1464
<>
15-
<Grid item xs={6} sm={3}>
16-
<Paper className={classes.paper}>
17-
<Grid container spacing={0}>
18-
<Grid item xs={6} md={12} lg={6}>
19-
<Typography variant="body2">Subscriptions</Typography>
20-
<Typography variant="body1" className={classes.value}>
21-
139 <sup className={clsx(classes.valueChange, classes.positive)}>+5%</sup>
22-
</Typography>
23-
</Grid>
24-
<Grid item xs={6} md={12} lg={6}>
25-
<div className={classes.chartContainer}>
26-
<div className={classes.chart}>
27-
<Line
28-
data={subscriptionsTrendChart.data}
29-
options={subscriptionsTrendChart.options}
30-
/>
31-
</div>
32-
</div>
33-
</Grid>
34-
</Grid>
35-
</Paper>
36-
</Grid>
37-
<Grid item xs={6} sm={3}>
38-
<Paper className={classes.paper}>
39-
<Grid container spacing={0}>
40-
<Grid item xs={6} md={12} lg={6}>
41-
<Typography variant="body2">Monthly Revenue</Typography>
42-
<Typography variant="body1" className={classes.value}>
43-
24350${' '}
44-
<sup className={clsx(classes.valueChange, classes.positive)}>+13%</sup>
45-
</Typography>
46-
</Grid>
47-
<Grid item xs={6} md={12} lg={6}>
48-
<div className={classes.chartContainer}>
49-
<div className={classes.chart}>
50-
<Line
51-
data={subscriptionsTrendChart.data}
52-
options={subscriptionsTrendChart.options}
53-
/>
54-
</div>
55-
</div>
65+
{numbers.map(({ name, value, change, trend, chart }) => (
66+
<Grid item xs={12} sm={6} md={3} key={name}>
67+
<Paper className={classes.paper}>
68+
<Grid container spacing={0}>
69+
<Grid item xs={6} sm={6} md={12} lg={6}>
70+
<Box p={2}>
71+
<Typography variant="body2" className={classes.name}>
72+
{name}
73+
</Typography>
74+
<Typography variant="body1" className={classes.value}>
75+
{value}{' '}
76+
<sup
77+
className={clsx(
78+
classes.valueChange,
79+
trend === 'positive' && classes.positive,
80+
trend === 'negative' && classes.negative,
81+
)}
82+
>
83+
{change}
84+
</sup>
85+
</Typography>
86+
</Box>
87+
</Grid>
88+
<Grid item xs={6} sm={6} md={12} lg={6}>
89+
<Box height="100%" position="relative" minHeight={70}>
90+
<div className={classes.chartContainer}>
91+
<Line data={chart.data} options={chart.options} />
92+
</div>
93+
</Box>
94+
</Grid>
5695
</Grid>
57-
</Grid>
58-
</Paper>
59-
</Grid>
60-
<Grid item xs={6} sm={3}>
61-
<Paper className={classes.paper}>
62-
<Grid container spacing={0}>
63-
<Grid item xs={6} md={12} lg={6}>
64-
<Typography variant="body2">Monthly Churn</Typography>
65-
<Typography variant="body1" className={classes.value}>
66-
13 <sup className={clsx(classes.valueChange, classes.negative)}>+10%</sup>
67-
</Typography>
68-
</Grid>
69-
<Grid item xs={6} md={12} lg={6}>
70-
<div className={classes.chartContainer}>
71-
<div className={classes.chart}>
72-
<Line
73-
data={subscriptionsTrendChart.data}
74-
options={subscriptionsTrendChart.options}
75-
/>
76-
</div>
77-
</div>
78-
</Grid>
79-
</Grid>
80-
</Paper>
81-
</Grid>
82-
<Grid item xs={6} sm={3}>
83-
<Paper className={classes.paper}>
84-
<Grid container spacing={0}>
85-
<Grid item xs={6} md={12} lg={6}>
86-
<Typography variant="body2">Total Users</Typography>
87-
<Typography variant="body1" className={classes.value}>
88-
48205{' '}
89-
<sup className={clsx(classes.valueChange, classes.positive)}>+30%</sup>
90-
</Typography>
91-
</Grid>
92-
<Grid item xs={6} md={12} lg={6}>
93-
<div className={classes.chartContainer}>
94-
<div className={classes.chart}>
95-
<Line
96-
data={subscriptionsTrendChart.data}
97-
options={subscriptionsTrendChart.options}
98-
/>
99-
</div>
100-
</div>
101-
</Grid>
102-
</Grid>
103-
</Paper>
104-
</Grid>
96+
</Paper>
97+
</Grid>
98+
))}
10599
</>
106100
)
107101
}
@@ -113,13 +107,19 @@ const useStyles = makeStyles(theme => ({
113107
flexGrow: 1,
114108
},
115109
paper: {
116-
padding: theme.spacing(2),
110+
// padding: theme.spacing(2),
117111
textAlign: 'left',
118112
color: theme.palette.text.secondary,
119113
height: '100%',
120114
},
115+
name: {
116+
whiteSpace: 'nowrap',
117+
overflow: 'hidden',
118+
textOverflow: 'ellipsis',
119+
},
121120
value: {
122121
fontWeight: 'bold',
122+
whiteSpace: 'nowrap',
123123
},
124124
valueChange: {},
125125
negative: {
@@ -129,11 +129,6 @@ const useStyles = makeStyles(theme => ({
129129
color: theme.palette.text.positive,
130130
},
131131
chartContainer: {
132-
width: '100%',
133-
position: 'relative',
134-
paddingBottom: '25%',
135-
},
136-
chart: {
137132
position: 'absolute',
138133
width: '100%',
139134
height: '100%',

src/Dashboard/KeyNumbers/data.js

Lines changed: 66 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,72 @@
1-
export const subscriptionsTrendChart = {
2-
data: {
3-
datasets: [
4-
{
5-
backgroundColor: '#ae59e3',
6-
borderColor: '#ae59e3',
7-
// backgroundColor: 'rgba(136, 151, 170, 0.1)',
8-
borderWidth: 2,
9-
label: 'Subscriptions',
10-
fill: false,
11-
data: [1545, 1350, 1270, 1830, 1955, 1865, 2034, 2544, 1956, 2211, 1540, 1670],
12-
},
13-
],
14-
labels: Array(12).fill(''),
15-
},
16-
options: {
17-
legend: {
18-
display: false,
19-
},
20-
scales: {
21-
xAxes: [
1+
import moment from 'moment'
2+
import theme from '../../_theme'
3+
import utilsService from '../../_services/utilsService'
4+
5+
export const generateTrendChartData = ({ name, from = 0, to = 1000, length = 30 }) => {
6+
return {
7+
data: {
8+
datasets: [
229
{
23-
display: false,
10+
backgroundColor: theme.palette.primary.main,
11+
borderColor: theme.palette.primary.main,
12+
borderWidth: 2,
13+
pointRadius: 1,
14+
pointHoverRadius: 3,
15+
label: name,
16+
fill: false,
17+
data: utilsService.generateRandomeChartDataArray({ from, to, length }),
2418
},
2519
],
26-
yAxes: [
27-
{
28-
display: false,
29-
},
30-
],
31-
},
32-
tooltips: {
33-
mode: 'index',
34-
intersect: false,
20+
labels: Array(length)
21+
.fill(null)
22+
.map((item, index) =>
23+
moment()
24+
.subtract(length - index, 'days')
25+
.format('ll'),
26+
),
3527
},
36-
hover: {
37-
mode: 'index',
38-
intersect: false,
28+
options: {
29+
layout: {
30+
padding: {
31+
left: 10,
32+
right: 10,
33+
top: 10,
34+
bottom: 10,
35+
},
36+
},
37+
legend: {
38+
display: false,
39+
},
40+
scales: {
41+
xAxes: [
42+
{
43+
display: false,
44+
},
45+
],
46+
yAxes: [
47+
{
48+
display: false,
49+
},
50+
],
51+
},
52+
tooltips: {
53+
mode: 'index',
54+
intersect: false,
55+
caretSize: 0,
56+
callbacks: {
57+
label: function(tooltipItem, data) {
58+
// var datasetLabel = ''
59+
// var label = data.labels[tooltipItem.index]
60+
return data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index]
61+
},
62+
},
63+
},
64+
hover: {
65+
mode: 'index',
66+
intersect: false,
67+
},
68+
responsive: true,
69+
maintainAspectRatio: false,
3970
},
40-
responsive: true,
41-
maintainAspectRatio: false,
42-
},
71+
}
4372
}

src/Dashboard/Subscriptions/data.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import theme from '../../_theme'
2+
13
export const subscriptionsItems = [
24
{ name: 'GitHub', ratio: 55.3, value: Math.round(55.3 * 144) },
35
{ name: 'MaterialUI', ratio: 25.7, value: Math.round(25.7 * 144) },
@@ -10,8 +12,8 @@ export const subscriptionsHistoryChart = {
1012
data: {
1113
datasets: [
1214
{
13-
backgroundColor: '#b1cc90',
14-
borderColor: '#8cd136',
15+
backgroundColor: theme.palette.secondary.main,
16+
borderColor: theme.palette.secondary.main,
1517
borderWidth: 2,
1618
label: 'Subscriptions',
1719
fill: false,

src/_layouts/DashboardLayout/DashboardLayout.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ const useStyles = makeStyles(theme => ({
167167
bottom: 0,
168168
flexDirection: 'row',
169169
width: theme.sidebar.width,
170+
flexShrink: 0,
170171
// [theme.breakpoints.up('md')]: {
171172
// width: theme.sidebar.width,
172173
// flexShrink: 0,

src/_services/utilsService.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import _random from 'lodash/random'
2+
3+
/**
4+
* Generates a nice random array for trend charts
5+
* with given from and to points
6+
*/
7+
export const generateRandomeChartDataArray = ({
8+
from = 0,
9+
to = 1000,
10+
length = 30,
11+
noize = 0.3,
12+
}) => {
13+
const getLineEquation = ({ x1, y1, x2, y2 }) => {
14+
return x => (x * (y2 - y1) + (x2 * y1 - x1 * y2)) / (x2 - x1)
15+
}
16+
const lineEquation = getLineEquation({ x1: 0, y1: from, x2: length - 1, y2: to })
17+
const getPointData = index => {
18+
const amplitude = Math.abs(Math.round(noize * (to - from)))
19+
const diff =
20+
index === 0 || index === length - 1
21+
? 0
22+
: amplitude * Math.sin((index * 2 * Math.PI) / length - 1) +
23+
_random(-amplitude, amplitude)
24+
return Math.max(0, Math.round(lineEquation(index) - diff))
25+
}
26+
27+
return Array(length)
28+
.fill(null)
29+
.map((item, index) => getPointData(index))
30+
}
31+
32+
export default {
33+
generateRandomeChartDataArray,
34+
}

0 commit comments

Comments
 (0)