Skip to content

Commit

Permalink
Merge pull request #36 from alecsloan/dev
Browse files Browse the repository at this point in the history
v3.6.0
  • Loading branch information
alecsloan authored Jun 10, 2021
2 parents c27a587 + 10d9dc4 commit f2f2d5d
Show file tree
Hide file tree
Showing 16 changed files with 295 additions and 164 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"author": "Alec Sloan <sloan.alec@gmail.com> (https://alecsloan.codes/)",
"name": "cryptolio",
"version": "3.5.0",
"version": "3.6.0",
"private": true,
"dependencies": {
"@material-ui/core": "latest",
Expand Down
65 changes: 5 additions & 60 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import AssetCard from './Components/AssetCard.js'
import Header from './Components/Header.js'
import Hotkeys from 'react-hot-keys'
import React, { Component } from 'react'
Expand All @@ -8,48 +7,14 @@ import { createMuiTheme } from '@material-ui/core/styles'
import { ThemeProvider } from '@material-ui/styles'

import './styles/App.css'
import { CssBaseline, Grid, IconButton, Snackbar } from '@material-ui/core'
import { CssBaseline, IconButton, Snackbar } from '@material-ui/core'
import CloseIcon from '@material-ui/icons/Close'
import { Alert } from '@material-ui/lab'
import AssetPanel from './Components/AssetPanel'
import * as CoinGecko from './Util/CoinGecko'
import * as CoinMarketCap from './Util/CoinMarketCap'
import * as Theme from './Theme'
import AssetTable from './Components/AssetTable'
import PortfolioDonutChart from './Components/PortfolioDonutChart'
import PortfolioAreaStackChart from './Components/PortfolioAreaStackChart'

function CardRow (props) {
const cards = []

let assets = props.assets

if (!assets) { return null }

if (props.settings.sorting === 'price') {
assets = assets.sort((a, b) => b.price - a.price)
} else if (props.settings.sorting === 'market_cap') {
assets = assets.sort((a, b) => b.market_cap - a.market_cap)
} else if (props.settings.sorting === 'percent_change_1h') {
assets = assets.sort((a, b) => b.percent_change_1h - a.percent_change_1h)
} else if (props.settings.sorting === 'percent_change_24h') {
assets = assets.sort((a, b) => b.percent_change_24h - a.percent_change_24h)
} else if (props.settings.sorting === 'percent_change_7d') {
assets = assets.sort((a, b) => b.percent_change_7d - a.percent_change_7d)
} else {
assets = assets.sort((a, b) => ((b.holdings || 0.000001) * b.price) - ((a.holdings || 0.000001) * a.price))
}

assets.forEach(asset => {
cards.push(
<Grid item xs={12} sm={6} md={4} key={asset.symbol}>
<AssetCard asset={asset} key={asset.symbol} renderStyle={props.renderStyle} settings={props.settings} setAssetPanelShown={props.setAssetPanelShown.bind(this)} />
</Grid>
)
})

return <Grid container spacing={2}>{cards}</Grid>
}
import LayoutHandler from './Components/LayoutHandler'

class App extends Component {
constructor (props) {
Expand All @@ -63,13 +28,13 @@ class App extends Component {
balanceChangeTimeframe: 'percent_change_24h',
currency: 'USD',
datasource: 'coinmarketcap',
days: 7,
decimals2: 100,
decimals3: 1,
decimals4: null,
fetchInterval: 300000,
portfolioBreakdown: "none",
renderStyle: (window.innerWidth <= 500) ? 'table' : 'card:classic',
renderSubStyle: 'table',
show1hChange: true,
show24hChange: true,
show7dChange: true,
Expand Down Expand Up @@ -309,28 +274,8 @@ class App extends Component {
<CssBaseline />

<Header addCrypto={this.addCrypto.bind(this)} assets={this.state.data.assets} availableAssets={this.state.data.availableAssets} editSetting={this.editSetting.bind(this)} refreshData={this.fetchAssetData.bind(this)} settings={this.state.settings} toggleShowSettings={this.toggleShowSettings.bind(this)} updatingData={this.state.updatingData || false} />
<hr hidden={(this.state.settings.renderStyle === 'table' && window.innerWidth <= 500)} />
{
this.state.settings.portfolioBreakdown === "stacked_line"
? <PortfolioAreaStackChart assets={this.state.data.assets} days={this.state.settings.days || 7} settings={this.state.settings}/>
: null
}
<Grid container style={{ width: '99%' }}>
{
this.state.settings.portfolioBreakdown === "donut"
? <Grid item xs={12} md={2}>
<PortfolioDonutChart assets={this.state.data.assets} settings={this.state.settings} />
</Grid>
: null
}
<Grid item xs={12} md={this.state.settings.portfolioBreakdown === "donut" ? 10 : 12}>
{
(!this.state.settings.renderStyle || this.state.settings.renderStyle.includes('card'))
? <CardRow assets={this.state.data.assets} renderStyle={this.state.settings.renderStyle} settings={this.state.settings} setAssetPanelShown={this.setAssetPanelShown.bind(this)} />
: <AssetTable assets={this.state.data.assets} editSetting={this.editSetting.bind(this)} settings={this.state.settings} setAssetPanelShown={this.setAssetPanelShown.bind(this)} />
}
</Grid>
</Grid>
<hr hidden={window.innerWidth <= 500} />
<LayoutHandler assets={this.state.data.assets} editSetting={this.editSetting.bind(this)} settings={this.state.settings} setAssetPanelShown={this.setAssetPanelShown.bind(this)} />
<Settings data={this.state.data} editSetting={this.editSetting.bind(this)} settings={this.state.settings} showSettings={this.state.showSettings} theme={this.state.settings.theme} toggleShowSettings={this.toggleShowSettings.bind(this)} uploadData={this.uploadData.bind(this)} />
<AssetPanel asset={this.state.assetPanelShown} editSetting={this.editSetting.bind(this)} settings={this.state.settings} removeCrypto={this.removeCrypto.bind(this)} setAssetPanelShown={this.setAssetPanelShown.bind(this)} updateExitPlan={this.updateExitPlan.bind(this)} updateHoldings={this.updateHoldings.bind(this)} updateInterest={this.updateInterest.bind(this)} />
<Hotkeys
Expand Down
2 changes: 1 addition & 1 deletion src/Components/AssetCard.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class AssetCard extends Component {
}

render () {
const renderStyle = this.props.renderStyle.replace('card:', '')
const renderStyle = (this.props.renderStyle || this.props.settings.renderStyle).replace('card:', '')

const price = this.props.asset.price

Expand Down
38 changes: 38 additions & 0 deletions src/Components/LayoutHandler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react'
import CardGrid from '../Layouts/CardGrid'
import AssetTable from '../Layouts/AssetTable'
import PortfolioAreaStackChart from './PortfolioAreaStackChart'
import PortfolioDonutChart from './PortfolioDonutChart'

function LayoutHandler (props) {
let assets = props.assets

if (props.settings.sorting === 'price') {
assets = assets.sort((a, b) => b.price - a.price)
} else if (props.settings.sorting === 'market_cap') {
assets = assets.sort((a, b) => b.market_cap - a.market_cap)
} else if (props.settings.sorting === 'percent_change_1h') {
assets = assets.sort((a, b) => b.percent_change_1h - a.percent_change_1h)
} else if (props.settings.sorting === 'percent_change_24h') {
assets = assets.sort((a, b) => b.percent_change_24h - a.percent_change_24h)
} else if (props.settings.sorting === 'percent_change_7d') {
assets = assets.sort((a, b) => b.percent_change_7d - a.percent_change_7d)
} else {
assets = assets.sort((a, b) => ((b.holdings || 0.000001) * b.price) - ((a.holdings || 0.000001) * a.price))
}

switch (props.renderStyle || props.settings.renderStyle) {
case "card:classic":
case "card:compact":
return <CardGrid assets={assets} renderStyle={props.renderStyle || props.settings.renderStyle} settings={props.settings} setAssetPanelShown={props.setAssetPanelShown.bind(this)} />
case "portfolio:chart":
return <PortfolioAreaStackChart assets={assets} editSetting={props.editSetting.bind(this)} settings={props.settings} setAssetPanelShown={props.setAssetPanelShown.bind(this)} />
case "portfolio:donut":
return <PortfolioDonutChart assets={assets} editSetting={props.editSetting.bind(this)} settings={props.settings} setAssetPanelShown={props.setAssetPanelShown.bind(this)} />
case "table":
default:
return <AssetTable assets={assets} editSetting={props.editSetting.bind(this)} settings={props.settings} setAssetPanelShown={props.setAssetPanelShown.bind(this)} />
}
}

export default LayoutHandler
62 changes: 52 additions & 10 deletions src/Components/PortfolioAreaStackChart.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ import * as CoinMarketCap from '../Util/CoinMarketCap'
import * as CoinGecko from '../Util/CoinGecko'
import abbreviate from 'number-abbreviate'
import { Skeleton } from '@material-ui/lab'
import { Grid } from '@material-ui/core'
import TimeframeSelector from './TimeframeSelector'
import SortSelector from './SortSelector'
import LayoutHandler from './LayoutHandler'
import MobileAssetCardGallery from '../Layouts/MobileAssetCardGallery'

class PortfolioAreaStackChart extends Component {
constructor (props) {
Expand Down Expand Up @@ -69,14 +74,25 @@ class PortfolioAreaStackChart extends Component {
}

this.state = {
hasAssets: props.assets.filter(asset => asset.holdings > 0).length > 0,
option: option
}

this.getData(props.settings, props.assets);
}

async getData (settings, assets, days = 7) {
async getData (settings, assets) {
let days = 7

if (settings.balanceChangeTimeframe === "percent_change_1h") {
days = .0417
}
else if (settings.balanceChangeTimeframe === "percent_change_24h") {
days = 1
}
else {
days = Number(settings.balanceChangeTimeframe.replace(/[^0-9]/g, ''))
}

const currency = settings.currency
const assetsHeld = assets.filter(asset => asset.holdings > 0).sort((a, b) => (b.holdings * b.price) - (a.holdings * a.price))

Expand Down Expand Up @@ -110,7 +126,7 @@ class PortfolioAreaStackChart extends Component {

if (this.props.settings.datasource === 'coinmarketcap') {
for (let [key, value] of Object.entries(assetData)) {
const index = key
const i = key

if (assetsHeld.length > 1) {
key = value.timestamp
Expand All @@ -119,13 +135,24 @@ class PortfolioAreaStackChart extends Component {
value = value[currency][0]
}

let date = `${new Date(key).getMonth() + 1}/${new Date(key).getDate()}`;
if (days > 29) {
let date = `${new Date(key).getMonth() + 1}/${new Date(key).getDate()}`;

if (!dates.includes(date)) {
dates.push(date);
if (!dates.includes(date)) {
dates.push(date);
}
}
else if (index === 0) {
let date = new Date(key)
let min = date.getMinutes()

date.setMinutes(Math.ceil(min / 10) * 10)
date.setSeconds(0)

if (Number(index) === assetData.length - 1) {
dates.push(date.toLocaleString());
}

if (Number(i) === assetData.length - 1) {
values.push(asset.price * asset.holdings)
} else {
values.push(value * asset.holdings);
Expand All @@ -134,7 +161,6 @@ class PortfolioAreaStackChart extends Component {
}
else {
assetData.map((granularDataset) => {

if (index === 0) {
let date = new Date(granularDataset[0])
let min = date.getMinutes()
Expand Down Expand Up @@ -178,8 +204,8 @@ class PortfolioAreaStackChart extends Component {
UNSAFE_componentWillReceiveProps (nextProps, nextContext) {
const assetsHeld = nextProps.assets.filter(asset => asset.holdings > 0)

if (nextProps.days || assetsHeld.length === 0) {
this.getData(nextProps.settings, nextProps.assets, nextProps.days);
if (nextProps.settings || assetsHeld.length === 0) {
this.getData(nextProps.settings, nextProps.assets);
}
}

Expand All @@ -195,6 +221,22 @@ class PortfolioAreaStackChart extends Component {
style={{ height: '100%', minHeight: '300px' }}
/>
<Skeleton animation="wave" className="m-auto" hidden={this.state.option.series} height={300} width={'90%'} />

<Grid container>
<Grid item xs={6}>
<TimeframeSelector balanceChangeTimeframe={this.props.settings.balanceChangeTimeframe} editSetting={this.props.editSetting} />
</Grid>

<Grid item xs={6}>
<SortSelector editSetting={this.props.editSetting} sorting={this.props.settings.sorting} />
</Grid>
</Grid>

{
(window.innerWidth <= 500 && this.props.assets.length > 0)
? <MobileAssetCardGallery assets={this.props.assets} settings={this.props.settings} setAssetPanelShown={this.props.setAssetPanelShown.bind(this)} />
: <LayoutHandler assets={this.props.assets} editSetting={this.props.editSetting.bind(this)} renderStyle={this.props.settings.renderSubStyle || "card:classic"} settings={this.props.settings} setAssetPanelShown={this.props.setAssetPanelShown.bind(this)} />
}
</div>
)
}
Expand Down
18 changes: 15 additions & 3 deletions src/Components/PortfolioDonutChart.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import React from 'react'
import ReactECharts from 'echarts-for-react';
import * as Util from '../Util/index'
import { Grid } from '@material-ui/core'
import LayoutHandler from './LayoutHandler'
import MobileAssetTable from '../Layouts/MobileAssetTable'

function PortfolioDonutChart (props) {
const option = {
Expand Down Expand Up @@ -49,9 +52,18 @@ function PortfolioDonutChart (props) {
}

return (
props.settings.portfolioBreakdown === "donut"
? <ReactECharts option={option} style={{ height: '100%', minHeight: '300px' }} />
: null
<Grid container style={{ width: '99%' }}>
<Grid item xs={12} md={2}>
<ReactECharts option={option} style={{ height: '100%', minHeight: '300px' }} />
</Grid>
<Grid item xs={12} md={10}>
{
(window.innerWidth <= 500 && props.assets.length > 0)
? <MobileAssetTable {...props} />
: <LayoutHandler assets={props.assets} editSetting={props.editSetting.bind(this)} renderStyle={props.settings.renderSubStyle || "card:classic"} settings={props.settings} setAssetPanelShown={props.setAssetPanelShown.bind(this)} />
}
</Grid>
</Grid>
)
}

Expand Down
Loading

0 comments on commit f2f2d5d

Please sign in to comment.