Skip to content
This repository was archived by the owner on Nov 8, 2022. It is now read-only.

Commit 36a0b3f

Browse files
committed
feat(user-heatmap): add number dashboard
1 parent 945a2c1 commit 36a0b3f

File tree

7 files changed

+167
-5
lines changed

7 files changed

+167
-5
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import React from 'react'
2+
import R from 'ramda'
3+
4+
// import { ICON_CMD } from '../../config'
5+
import DotDivider from 'components/DotDivider'
6+
import {
7+
Wrapper,
8+
SumWrapper,
9+
DetailText,
10+
DashboardListWrapper,
11+
DashItem,
12+
Divider,
13+
Title,
14+
Num,
15+
Chart,
16+
ChartBar,
17+
} from './styles/num_dashboard'
18+
19+
import { ToggleNumBashboard } from './logic'
20+
21+
export const sortByValue = source => R.sort((a, b) => b.value - a.value, source)
22+
23+
const NumDashboard = ({ total, geoData, expand }) => {
24+
if (R.isEmpty(geoData)) return null
25+
26+
const sortGeo = sortByValue(geoData) || []
27+
const maxValue = sortGeo[0].value || 0
28+
29+
return (
30+
<Wrapper expand={expand}>
31+
<SumWrapper>
32+
总人数: {total} <DotDivider />{' '}
33+
<DetailText onClick={ToggleNumBashboard}>
34+
{expand ? '收起' : '详情'}
35+
</DetailText>
36+
</SumWrapper>
37+
{expand && (
38+
<DashboardListWrapper>
39+
{sortGeo.map((item, idx) => (
40+
<div key={item.lant + item.long}>
41+
<DashItem>
42+
<Title active={idx <= 2}>{item.city}</Title>
43+
<DotDivider radius="3px" space="3px" />
44+
<Num>{item.value}</Num>
45+
<Chart>
46+
<ChartBar
47+
width={`${Math.floor((item.value / maxValue) * 100)}%`}
48+
active={idx <= 2}
49+
/>
50+
</Chart>
51+
</DashItem>
52+
<Divider show={idx === 2} />
53+
</div>
54+
))}
55+
</DashboardListWrapper>
56+
)}
57+
</Wrapper>
58+
)
59+
}
60+
61+
export default NumDashboard

containers/UsersThread/geo_data.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
//
22
/* import { fetch } from 'whatwg-fetch' */
3+
import { ASSETS_ENDPOINT } from 'config'
34
import fetch from 'isomorphic-fetch'
45
import { BStore } from 'utils'
56

6-
const endpoint = 'https://cps-oss.oss-cn-shanghai.aliyuncs.com/asia.geo.json'
7+
const endpoint = `${ASSETS_ENDPOINT}/asia.geo.json`
78
const bkey = 'asia.geo.data'
89

910
const fetchGeoData = () =>

containers/UsersThread/index.js

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@ import { inject, observer } from 'mobx-react'
99
import dynamic from 'next/dynamic'
1010

1111
import { makeDebugger, storePlug } from 'utils'
12+
13+
import NumDashboard from './NumDashboard'
1214
import MapLoading from './MapLoading'
1315

16+
import { Wrapper } from './styles'
1417
import * as logic from './logic'
1518

1619
/* eslint-disable-next-line */
@@ -52,18 +55,31 @@ class UsersThreadContainer extends React.Component {
5255

5356
render() {
5457
const { usersThread } = this.props
55-
const { geoInfosData, geoDataLoading, curTheme } = usersThread
58+
const {
59+
geoInfosData,
60+
geoDataLoading,
61+
curCommunity,
62+
curTheme,
63+
showNums,
64+
} = usersThread
5665

5766
const ready = GeoMapSSR !== null && !geoDataLoading
5867

5968
return (
60-
<React.Fragment>
69+
<Wrapper>
70+
{ready && (
71+
<NumDashboard
72+
expand={showNums}
73+
total={curCommunity.subscribersCount}
74+
geoData={geoInfosData}
75+
/>
76+
)}
6177
{ready ? (
6278
<GeoMapSSR markers={geoInfosData} curTheme={curTheme} />
6379
) : (
6480
<MapLoading />
6581
)}
66-
</React.Fragment>
82+
</Wrapper>
6783
)
6884
}
6985
}

containers/UsersThread/logic.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ export const loadGeoData = () => {
2525
sr71$.query(S.communityGeoInfo, { id })
2626
}
2727

28+
export const ToggleNumBashboard = () =>
29+
store.markState({ showNums: !store.showNums })
30+
2831
const markLoading = (maybe = true) => store.markState({ geoDataLoading: maybe })
2932
// ###############################
3033
// Data & Error handlers

containers/UsersThread/store.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const UsersThread = t
2222
geoInfos: t.optional(t.array(Geo), []),
2323
geoDataLoading: t.optional(t.boolean, false),
2424
// { city: '成都', value: 1, long: 104.06, lant: 30.67 }
25+
showNums: t.optional(t.boolean, false),
2526
})
2627
.views(self => ({
2728
get root() {

containers/UsersThread/styles/index.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ import styled from 'styled-components'
33
// import Img from 'components/Img'
44
// import { theme } from 'utils'
55

6-
export const Wrapper = styled.div``
6+
export const Wrapper = styled.div`
7+
width: 100%;
8+
position: relative;
9+
`
710
export const Title = styled.div``
811

912
export const MapWrapper = styled.div`
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import styled from 'styled-components'
2+
3+
// import Img from '../../../components/Img'
4+
import { theme, cs } from '../../../utils'
5+
6+
export const Wrapper = styled.div`
7+
${cs.flexColumn()};
8+
position: absolute;
9+
z-index: 1;
10+
top: 20px;
11+
left: 40px;
12+
background: ${theme('content.cardBg')};
13+
padding: 2px;
14+
border-radius: 5px;
15+
width: ${({ expand }) => (expand ? '200px' : '150px')};
16+
transition: width 0.2s linear;
17+
`
18+
19+
export const SumWrapper = styled.div`
20+
${cs.flex('align-both')};
21+
color: ${theme('thread.articleDigest')};
22+
`
23+
24+
export const DetailText = styled.div`
25+
color: ${theme('thread.articleDigest')};
26+
&:hover {
27+
color: ${theme('thread.articleTitle')};
28+
cursor: pointer;
29+
}
30+
`
31+
export const DashboardListWrapper = styled.div`
32+
background: ${theme('content.cardBg')};
33+
min-height: 200px;
34+
max-height: 60vh;
35+
margin-top: 3px;
36+
padding-top: 2px;
37+
padding-left: 4px;
38+
padding-right: 4px;
39+
padding-bottom: 5px;
40+
overflow-y: scroll;
41+
`
42+
export const DashItem = styled.div`
43+
${cs.flex('align-center')};
44+
`
45+
export const Title = styled.div`
46+
color: ${({ active }) =>
47+
active ? theme('banner.title') : theme('thread.articleDigest')};
48+
width: 60px;
49+
text-align: center;
50+
`
51+
52+
export const Divider = styled.div`
53+
display: ${({ show }) => (show ? 'block' : 'none')};
54+
border-bottom: 1px dashed;
55+
border-bottom-color: ${theme('thread.articleDigest')};
56+
margin-top: 4px;
57+
margin-bottom: 4px;
58+
width: 80%;
59+
margin-left: 8%;
60+
opacity: 0.5;
61+
`
62+
63+
export const Num = styled.div`
64+
color: ${theme('thread.articleDigest')};
65+
width: 50px;
66+
text-align: left;
67+
`
68+
export const Chart = styled.div`
69+
${cs.flexGrow()};
70+
`
71+
export const ChartBar = styled.div`
72+
height: ${({ active }) => (active ? '4px' : '3px')};
73+
74+
width: ${({ width }) => width};
75+
background: ${({ active }) =>
76+
active ? theme('geoMap.markerBg') : theme('thread.articleDigest')};
77+
`

0 commit comments

Comments
 (0)