mirror of
https://github.com/nickzuber/meteorite.git
synced 2024-09-11 11:36:03 +03:00
Graph
This commit is contained in:
parent
88bb99ac0a
commit
5344bf8f46
149
package-lock.json
generated
149
package-lock.json
generated
@ -3939,6 +3939,11 @@
|
||||
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
|
||||
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
|
||||
},
|
||||
"decimal.js-light": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.0.tgz",
|
||||
"integrity": "sha512-b3VJCbd2hwUpeRGG3Toob+CRo8W22xplipNhP3tN7TSVB/cyMX71P1vM2Xjc9H74uV6dS2hDDmo/rHq8L87Upg=="
|
||||
},
|
||||
"decode-uri-component": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
|
||||
@ -4170,6 +4175,29 @@
|
||||
"utila": "~0.4"
|
||||
}
|
||||
},
|
||||
"dom-helpers": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz",
|
||||
"integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": {
|
||||
"version": "7.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.2.tgz",
|
||||
"integrity": "sha512-7Bl2rALb7HpvXFL7TETNzKSAeBVCPHELzc0C//9FCxN8nsiueWSJBqaF+2oIJScyILStASR/Cx5WMkXGYTiJFA==",
|
||||
"requires": {
|
||||
"regenerator-runtime": "^0.13.2"
|
||||
}
|
||||
},
|
||||
"regenerator-runtime": {
|
||||
"version": "0.13.2",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz",
|
||||
"integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"dom-serializer": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz",
|
||||
@ -8177,6 +8205,11 @@
|
||||
"lodash._reinterpolate": "~3.0.0"
|
||||
}
|
||||
},
|
||||
"lodash.throttle": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
|
||||
"integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ="
|
||||
},
|
||||
"lodash.uniq": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
|
||||
@ -8258,6 +8291,11 @@
|
||||
"object-visit": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"math-expression-evaluator": {
|
||||
"version": "1.2.17",
|
||||
"resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz",
|
||||
"integrity": "sha1-3oGf282E3M2PrlnGrreWFbnSZqw="
|
||||
},
|
||||
"math-random": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz",
|
||||
@ -12181,6 +12219,28 @@
|
||||
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
|
||||
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
|
||||
},
|
||||
"react-resize-detector": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-2.3.0.tgz",
|
||||
"integrity": "sha512-oCAddEWWeFWYH5FAcHdBYcZjAw9fMzRUK9sWSx6WvSSOPVRxcHd5zTIGy/mOus+AhN/u6T4TMiWxvq79PywnJQ==",
|
||||
"requires": {
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"lodash.throttle": "^4.1.1",
|
||||
"prop-types": "^15.6.0",
|
||||
"resize-observer-polyfill": "^1.5.0"
|
||||
}
|
||||
},
|
||||
"react-smooth": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-1.0.2.tgz",
|
||||
"integrity": "sha512-pIGzL1g9VGAsRsdZQokIK0vrCkcdKtnOnS1gyB2rrowdLy69lNSWoIjCTWAfgbiYvria8tm5hEZqj+jwXMkV4A==",
|
||||
"requires": {
|
||||
"lodash": "~4.17.4",
|
||||
"prop-types": "^15.6.0",
|
||||
"raf": "^3.4.0",
|
||||
"react-transition-group": "^2.5.0"
|
||||
}
|
||||
},
|
||||
"react-spring": {
|
||||
"version": "8.0.18",
|
||||
"resolved": "https://registry.npmjs.org/react-spring/-/react-spring-8.0.18.tgz",
|
||||
@ -12213,6 +12273,17 @@
|
||||
"prop-types": "^15.5.8"
|
||||
}
|
||||
},
|
||||
"react-transition-group": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.7.1.tgz",
|
||||
"integrity": "sha512-b0VJTzNRnXxRpCuxng6QJbAzmmrhBn1BZJfPPnHbH2PIo8msdkajqwtfdyGm/OypPXZNfAHKEqeN15wjMXrRJQ==",
|
||||
"requires": {
|
||||
"dom-helpers": "^3.3.1",
|
||||
"loose-envify": "^1.4.0",
|
||||
"prop-types": "^15.6.2",
|
||||
"react-lifecycles-compat": "^3.0.4"
|
||||
}
|
||||
},
|
||||
"read-pkg": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
|
||||
@ -12567,6 +12638,47 @@
|
||||
"util.promisify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"recharts": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/recharts/-/recharts-1.5.0.tgz",
|
||||
"integrity": "sha512-bsKJRvh4NepPJlXoI4L9oRKhrv59W7fjs6qTqk6le9MFAywe8EYiW/t07RDQHBVIj6icb+UdSFsHxEo8c5AcTg==",
|
||||
"requires": {
|
||||
"classnames": "~2.2.5",
|
||||
"core-js": "~2.5.1",
|
||||
"d3-interpolate": "~1.3.0",
|
||||
"d3-scale": "~2.1.0",
|
||||
"d3-shape": "~1.2.0",
|
||||
"lodash": "~4.17.5",
|
||||
"prop-types": "~15.6.0",
|
||||
"react-resize-detector": "~2.3.0",
|
||||
"react-smooth": "~1.0.0",
|
||||
"recharts-scale": "^0.4.2",
|
||||
"reduce-css-calc": "~1.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"d3-scale": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-2.1.2.tgz",
|
||||
"integrity": "sha512-bESpd64ylaKzCDzvULcmHKZTlzA/6DGSVwx7QSDj/EnX9cpSevsdiwdHFYI9ouo9tNBbV3v5xztHS2uFeOzh8Q==",
|
||||
"requires": {
|
||||
"d3-array": "^1.2.0",
|
||||
"d3-collection": "1",
|
||||
"d3-format": "1",
|
||||
"d3-interpolate": "1",
|
||||
"d3-time": "1",
|
||||
"d3-time-format": "2"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"recharts-scale": {
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.2.tgz",
|
||||
"integrity": "sha512-p/cKt7j17D1CImLgX2f5+6IXLbRHGUQkogIp06VUoci/XkhOQiGSzUrsD1uRmiI7jha4u8XNFOjkHkzzBPivMg==",
|
||||
"requires": {
|
||||
"decimal.js-light": "^2.4.1"
|
||||
}
|
||||
},
|
||||
"recompose": {
|
||||
"version": "0.30.0",
|
||||
"resolved": "https://registry.npmjs.org/recompose/-/recompose-0.30.0.tgz",
|
||||
@ -12588,6 +12700,38 @@
|
||||
"minimatch": "3.0.4"
|
||||
}
|
||||
},
|
||||
"reduce-css-calc": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz",
|
||||
"integrity": "sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=",
|
||||
"requires": {
|
||||
"balanced-match": "^0.4.2",
|
||||
"math-expression-evaluator": "^1.2.14",
|
||||
"reduce-function-call": "^1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"balanced-match": {
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
|
||||
"integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg="
|
||||
}
|
||||
}
|
||||
},
|
||||
"reduce-function-call": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.2.tgz",
|
||||
"integrity": "sha1-WiAL+S4ON3UXUv5FsKszD9S2vpk=",
|
||||
"requires": {
|
||||
"balanced-match": "^0.4.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"balanced-match": {
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
|
||||
"integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg="
|
||||
}
|
||||
}
|
||||
},
|
||||
"regenerate": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz",
|
||||
@ -12805,6 +12949,11 @@
|
||||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
|
||||
},
|
||||
"resize-observer-polyfill": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
|
||||
"integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz",
|
||||
|
@ -54,6 +54,7 @@
|
||||
"react-emotion": "^9.2.12",
|
||||
"react-spring": "^8.0.18",
|
||||
"react-svg-inline": "^2.1.1",
|
||||
"recharts": "^1.5.0",
|
||||
"recompose": "^0.30.0",
|
||||
"resolve": "1.8.1",
|
||||
"sass-loader": "7.1.0",
|
||||
|
@ -473,7 +473,14 @@ class NotificationsPage extends React.Component {
|
||||
lastNumbered = 0;
|
||||
}
|
||||
|
||||
const todayLastWeek = this.state.currentTime.clone().subtract(1, 'week');
|
||||
|
||||
const stagedTodayCount = this.props.storageApi.getStat('stagedCount')[0];
|
||||
const stagedTodayLastWeekCount = this.props.storageApi.getStat(
|
||||
'stagedCount',
|
||||
todayLastWeek,
|
||||
todayLastWeek.clone().add(1, 'day')
|
||||
)[0];
|
||||
const stagedStatistics = this.props.storageApi.getStat(
|
||||
'stagedCount',
|
||||
this.state.currentTime.clone().startOf('week').subtract(1, 'week'),
|
||||
@ -483,14 +490,15 @@ class NotificationsPage extends React.Component {
|
||||
return (
|
||||
<Scene
|
||||
currentTime={this.state.currentTime}
|
||||
stagedStatistics={stagedStatistics}
|
||||
readStatistics={stagedStatistics}
|
||||
isFirstTimeUser={this.state.isFirstTimeUser}
|
||||
setNotificationsPermission={this.setNotificationsPermission}
|
||||
notificationsPermission={notificationsPermission}
|
||||
unreadCount={queuedCount}
|
||||
readCount={stagedCount}
|
||||
archivedCount={closedCount}
|
||||
stagedTodayCount={stagedTodayCount || 0}
|
||||
readTodayCount={stagedTodayCount || 0}
|
||||
readTodayLastWeekCount={stagedTodayLastWeekCount || 0}
|
||||
first={firstNumbered}
|
||||
last={lastNumbered}
|
||||
lastPage={lastPage}
|
||||
|
@ -5,6 +5,15 @@ import moment from 'moment';
|
||||
import styled from '@emotion/styled';
|
||||
import {css, jsx, keyframes} from '@emotion/core';
|
||||
import {useSpring, useTransition, animated} from 'react-spring'
|
||||
import {
|
||||
LineChart,
|
||||
Line,
|
||||
XAxis,
|
||||
YAxis,
|
||||
CartesianGrid,
|
||||
Tooltip,
|
||||
Legend
|
||||
} from 'recharts';
|
||||
import Icon from '../../../components/Icon';
|
||||
import Logo from '../../../components/Logo';
|
||||
import LoadingIcon from '../../../components/LoadingIcon';
|
||||
@ -118,6 +127,24 @@ function createColorOfScore (min, max) {
|
||||
}
|
||||
}
|
||||
|
||||
function getPercentageDelta (n, o) {
|
||||
if (n === o) {
|
||||
return 0;
|
||||
} else if (n > o) {
|
||||
return (n - o) / o * 100;
|
||||
} else {
|
||||
return (o - n) / o * 100;
|
||||
}
|
||||
}
|
||||
|
||||
function prettify (n) {
|
||||
if (Math.floor(n) === n) {
|
||||
return n.toString();
|
||||
} else {
|
||||
return n.toFixed(1);
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// END OF 'MOVE TO A UTILS FILE'
|
||||
// ========================================================================
|
||||
@ -194,9 +221,10 @@ const CardSection = styled('div')`
|
||||
`;
|
||||
|
||||
const Card = styled('div')`
|
||||
position: relative;
|
||||
width: 250px;
|
||||
padding: 20px 24px;
|
||||
height: 100px;
|
||||
min-height: 100px;
|
||||
margin: 32px auto 0;
|
||||
background: ${WHITE};
|
||||
border: 1px solid #E5E6EB;
|
||||
@ -205,9 +233,22 @@ const Card = styled('div')`
|
||||
`;
|
||||
|
||||
const CardTitle = styled(Title)`
|
||||
line-height: 1.5em;
|
||||
font-size: 1.5em;
|
||||
`;
|
||||
|
||||
const CardSubTitle = styled(CardTitle)`
|
||||
font-size: 1.2em;
|
||||
color: #9d9b97;
|
||||
`;
|
||||
|
||||
const ScoreDiff = styled(CardTitle)`
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
right: 24px;
|
||||
color: ${props => props.under ? '#ef055f' : '#457cff'};
|
||||
`;
|
||||
|
||||
const IconContainer = styled('div')`
|
||||
position: relative;
|
||||
height: 72px;
|
||||
@ -223,7 +264,7 @@ const IconContainer = styled('div')`
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 3px;
|
||||
background: ${props => !props.noBorder && props.selected ? props.primary : WHITE};
|
||||
background: ${props => !props.noBorder && props.selected ? props.primary : 'transparent'};
|
||||
right: 0;
|
||||
top: 4px;
|
||||
bottom: 4px;
|
||||
@ -270,7 +311,7 @@ const SubTitleSection = styled('div')`
|
||||
margin: 8px 0;
|
||||
font-weight: 500;
|
||||
font-size: 1rem;
|
||||
color: #19223dab;
|
||||
color: #9d9b97;
|
||||
}
|
||||
`;
|
||||
|
||||
@ -715,6 +756,97 @@ function SortingItem ({children, selected, onChange, descending, setDescending,
|
||||
);
|
||||
}
|
||||
|
||||
function CustomTick ({x, y, stroke, payload}) {
|
||||
if (!payload) return null;
|
||||
return (
|
||||
<g transform={`translate(${x},${y})`}>
|
||||
<text
|
||||
x={0}
|
||||
y={0}
|
||||
dy={16}
|
||||
textAnchor="middle"
|
||||
fill="#BFC5D1"
|
||||
fontWeight="600"
|
||||
transform="scale(0.65)"
|
||||
>
|
||||
{payload.value.substring(0, 2)}
|
||||
</text>
|
||||
</g>
|
||||
);
|
||||
}
|
||||
|
||||
function ReadCountGraph ({data}) {
|
||||
return (
|
||||
<LineChart width={250} height={200} data={data}>
|
||||
<XAxis
|
||||
dataKey="name"
|
||||
interval={0}
|
||||
tickSize={5}
|
||||
tick={<CustomTick />}
|
||||
tickFormatter={tick => tick.substring(0, 2)}
|
||||
/>
|
||||
<Tooltip
|
||||
wrapperStyle={{
|
||||
opacity: 0.9
|
||||
}}
|
||||
contentStyle={{
|
||||
background: 'rgb(255,254,252)',
|
||||
border: '1px solid #E5E6EB',
|
||||
borderRadius: 6,
|
||||
boxShadow: 'rgba(84,70,35,0) 0px 2px 8px, rgba(84,70,35,0.15) 0px 1px 3px',
|
||||
minWidth: 100,
|
||||
padding: '6px 12px 8px'
|
||||
}}
|
||||
itemStyle={{
|
||||
fontSize: 12,
|
||||
fontWeight: '500',
|
||||
padding: 0,
|
||||
opacity: .75
|
||||
}}
|
||||
labelStyle={{
|
||||
color: 'rgb(55, 53, 47)',
|
||||
fontSize: 14,
|
||||
fontWeight: '600',
|
||||
padding: 0
|
||||
}}
|
||||
cursor={{
|
||||
stroke: '#BFC5D144',
|
||||
strokeWidth: 2
|
||||
}}
|
||||
animationDuration={400}
|
||||
formatter={(value, name) => {
|
||||
switch (name) {
|
||||
case 'cur':
|
||||
return [value, 'This week'];
|
||||
case 'prev':
|
||||
return [value, 'Last week'];
|
||||
default:
|
||||
return [value, name];
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Line
|
||||
type="monotone"
|
||||
dataKey="prev"
|
||||
stroke="#BFC5D166"
|
||||
strokeWidth="2"
|
||||
animationDuration={0}
|
||||
dot={{ stroke: '#00000000', fill: '#00000000', r: 0 }}
|
||||
activeDot={{ stroke: '#BFC5D166', fill: '#BFC5D166', r: 2 }}
|
||||
/>
|
||||
<Line
|
||||
type="monotone"
|
||||
dataKey="cur"
|
||||
stroke="#4880ff"
|
||||
strokeWidth="2"
|
||||
animationDuration={0}
|
||||
dot={{ stroke: '#00000000', fill: '#00000000', r: 0 }}
|
||||
activeDot={{ stroke: '#4880ff', fill: '#4880ff', r: 2 }}
|
||||
/>
|
||||
</LineChart>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Scene ({
|
||||
notifications,
|
||||
notificationsPermission,
|
||||
@ -747,20 +879,30 @@ export default function Scene ({
|
||||
setNotificationsPermission,
|
||||
onStageThread,
|
||||
onArchiveThread,
|
||||
readStatistics,
|
||||
readTodayCount,
|
||||
readTodayLastWeekCount,
|
||||
}) {
|
||||
const [menuOpen, setMenuOpen] = React.useState(false);
|
||||
const [dropdownOpen, setDropdownOpen] = React.useState(false);
|
||||
const [mode, setMode] = React.useState(Mode.ALL);
|
||||
const hasNotificationsOn = notificationsPermission === 'granted';
|
||||
|
||||
// @TODO move to index file
|
||||
if (sort === Sort.TITLE) {
|
||||
if (descending) {
|
||||
notifications.sort((a, b) => a.name.localeCompare(b.name));
|
||||
} else {
|
||||
notifications.sort((a, b) => b.name.localeCompare(a.name));
|
||||
}
|
||||
}
|
||||
readStatistics = readStatistics.map(n => parseInt(n, 10));
|
||||
const lastWeekStats = readStatistics.slice(0, 7).map(n => n || null);
|
||||
const thisWeekStats = readStatistics.slice(7).map(n => n || null);
|
||||
|
||||
const percentageDeltaToday = getPercentageDelta(readTodayCount, readTodayLastWeekCount);
|
||||
|
||||
const data = [
|
||||
{name: 'Sunday', cur: thisWeekStats[0], prev: lastWeekStats[0]},
|
||||
{name: 'Monday', cur: thisWeekStats[1], prev: lastWeekStats[1]},
|
||||
{name: 'Tuesday', cur: thisWeekStats[2], prev: lastWeekStats[2]},
|
||||
{name: 'Wednesday', cur: thisWeekStats[3], prev: lastWeekStats[3]},
|
||||
{name: 'Thursday', cur: thisWeekStats[4], prev: lastWeekStats[4]},
|
||||
{name: 'Friday', cur: thisWeekStats[5], prev: lastWeekStats[5]},
|
||||
{name: 'Saturday', cur: thisWeekStats[6], prev: lastWeekStats[6]},
|
||||
];
|
||||
|
||||
// const notificationTransitions = useTransition(notifications, item => item.id, {
|
||||
// from: {background: 'green', opacity: 0, transform: 'translate3d(50px, 0, 0)'},
|
||||
@ -881,7 +1023,14 @@ export default function Scene ({
|
||||
<ContentItem>
|
||||
<CardSection>
|
||||
<Card>
|
||||
<CardTitle>{currentTime.format('dddd, MMMM Do')}</CardTitle>
|
||||
<CardTitle>{currentTime.format('dddd')}</CardTitle>
|
||||
<CardSubTitle>{currentTime.format('MMMM Do, YYYY')}</CardSubTitle>
|
||||
<ScoreDiff under={readTodayLastWeekCount > readTodayCount}>
|
||||
{readTodayLastWeekCount > readTodayCount ? '-' : '+'}
|
||||
{prettify(percentageDeltaToday)}
|
||||
{'%'}
|
||||
</ScoreDiff>
|
||||
<ReadCountGraph data={data} />
|
||||
</Card>
|
||||
<Card />
|
||||
</CardSection>
|
||||
|
@ -90,6 +90,11 @@ div {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
line[stroke="#666"] {
|
||||
stroke-width: 2;
|
||||
stroke: #e5e7ea;
|
||||
}
|
||||
|
||||
.react-tooltip {
|
||||
z-index: 999999;
|
||||
pointer-events: none;
|
||||
|
Loading…
Reference in New Issue
Block a user