bbgo_origin/frontend/components/TradingVolumeBar.js

153 lines
5.0 KiB
JavaScript
Raw Normal View History

2021-01-26 10:10:08 +00:00
import {ResponsiveBar} from '@nivo/bar';
import {queryTradingVolume} from '../api/bbgo';
import {useEffect, useState} from "react";
2021-01-28 10:51:35 +00:00
function toPeriodDateString(time, period) {
switch (period) {
case "day":
return time.getFullYear() + "-" + (time.getMonth() + 1) + "-" + time.getDate()
case "month":
return time.getFullYear() + "-" + (time.getMonth() + 1)
case "year":
return time.getFullYear()
2021-01-26 10:10:08 +00:00
2021-01-28 10:51:35 +00:00
}
return time.getFullYear() + "-" + (time.getMonth() + 1) + "-" + time.getDate()
}
function groupData(rows, period, segment) {
2021-01-26 10:10:08 +00:00
let dateIndex = {}
let startTime = null
let endTime = null
2021-01-28 10:51:35 +00:00
let keys = {}
2021-01-26 10:10:08 +00:00
rows.forEach((v) => {
const time = new Date(v.time)
if (!startTime) {
startTime = time
}
endTime = time
2021-01-28 10:51:35 +00:00
const dateStr = toPeriodDateString(time, period)
const key = v[segment]
keys[key] = true
2021-01-26 10:10:08 +00:00
const k = key ? key : "total"
const quoteVolume = Math.round(v.quoteVolume * 100) / 100
if (dateIndex[dateStr]) {
dateIndex[dateStr][k] = quoteVolume
} else {
dateIndex[dateStr] = {
date: dateStr,
year: time.getFullYear(),
month: time.getMonth() + 1,
day: time.getDate(),
[k]: quoteVolume,
}
}
})
let data = []
while (startTime < endTime) {
2021-01-28 10:51:35 +00:00
const dateStr = toPeriodDateString(startTime, period)
2021-01-26 10:10:08 +00:00
const groupData = dateIndex[dateStr]
if (groupData) {
data.push(groupData)
} else {
data.push({
date: dateStr,
year: startTime.getFullYear(),
month: startTime.getMonth() + 1,
day: startTime.getDate(),
total: 0,
})
}
2021-01-28 10:51:35 +00:00
switch (period) {
case "day":
startTime.setDate(startTime.getDate() + 1)
break
case "month":
startTime.setMonth(startTime.getMonth() + 1)
break
case "year":
startTime.setFullYear(startTime.getFullYear() + 1)
break
}
2021-01-26 10:10:08 +00:00
}
2021-01-28 10:51:35 +00:00
return [data, Object.keys(keys)]
2021-01-26 10:10:08 +00:00
}
2021-01-28 10:51:35 +00:00
export default function TradingVolumeBar(props) {
2021-01-26 10:10:08 +00:00
const [tradingVolumes, setTradingVolumes] = useState([])
2021-01-28 10:51:35 +00:00
const [period, setPeriod] = useState(props.period)
const [segment, setSegment] = useState(props.segment)
2021-01-26 10:10:08 +00:00
useEffect(() => {
2021-01-28 10:51:35 +00:00
if (props.period !== period) {
setPeriod(props.period);
}
if (props.segment !== segment) {
setSegment(props.segment);
}
queryTradingVolume({period: props.period, segment: props.segment }, (tradingVolumes) => {
2021-01-26 10:10:08 +00:00
setTradingVolumes(tradingVolumes)
})
2021-01-29 03:19:52 +00:00
}, [props.period, props.segment])
2021-01-26 10:10:08 +00:00
2021-01-28 10:51:35 +00:00
const [data, keys] = groupData(tradingVolumes, period, segment)
2021-01-26 10:10:08 +00:00
2021-01-28 10:51:35 +00:00
return <ResponsiveBar keys={keys}
2021-01-26 10:10:08 +00:00
data={data}
indexBy={"date"}
2021-01-28 10:51:35 +00:00
margin={{top: 50, right: 160, bottom: 100, left: 60}}
2021-01-26 10:10:08 +00:00
padding={0.3}
2021-01-28 10:51:35 +00:00
valueScale={{type: 'linear'}}
indexScale={{type: 'band', round: true}}
labelSkipWidth={30}
2021-01-29 03:19:52 +00:00
labelSkipHeight={20}
2021-01-26 10:10:08 +00:00
enableGridY={true}
2021-01-28 10:51:35 +00:00
colors={{scheme: 'paired'}}
axisBottom={{
tickRotation: -90,
legend: period,
legendPosition: 'middle',
legendOffset: 80
}}
2021-01-26 10:10:08 +00:00
legends={[
{
dataFrom: 'keys',
anchor: 'right',
direction: 'column',
justify: false,
translateX: 120,
translateY: 0,
itemsSpacing: 2,
itemWidth: 100,
itemHeight: 20,
itemDirection: 'left-to-right',
itemOpacity: 0.85,
symbolSize: 20,
effects: [
{
on: 'hover',
style: {
itemOpacity: 1
}
}
]
}
]}
animate={true}
motionStiffness={90}
motionDamping={15}
/>;
}