数据集可以在折线图上很好地绘制,但是我试图使用chartjs-plugin-annotation
使垂直线显示在图表上。通过查看以下问题和答案:
- SOLVED : ChartJS annotation not displaying
- https://github.com/chartjs/chartjs-plugin-annotation/issues/209
- react-chartjs-2 vertical line when hovering over chart
- Chart.js — drawing an arbitrary vertical line
我以为我的配置正确,但是没有出现行。
LineChart.js
import 'chartjs-plugin-annotation'
import React,{ useContext } from 'react'
import { Card,CardBody } from 'reactstrap'
import { Line } from 'react-chartjs-2'
import flatten from 'lodash/flatten'
import { rgbaColor,exchangeChartColors,capitalize,exchanges } from '../../helpers/utils'
import AppContext from '../../context/Context'
import dayjs from 'dayjs'
function getDepositsAndWithdrawals(activity) {
return ['DEPOSIT','WITHDRAWAL'].reduce((acc,type) => {
if (activity) {
if (activity.betfair) {
acc[type].betfair = activity.betfair.filter(s => {
return s.legacyData.marketName === type
}).map(s => {
return {
exchange: 'BETFAIR',type: type,amount: s.amount,date: getFormattedDate(s.itemDate)
}
})
}
if (activity.betdaq) {
acc[type].betdaq = activity.betdaq.filter(s => {
return s.PostingCategory === 3 && s.Description.toUpperCase().includes(`${type}:`)
}).map(s => {
return {
exchange: 'BETDAQ',amount: s.Amount,date: getFormattedDate(s.PostedAt)
}
})
}
if (activity.smarkets) {
const typeToGet = (type === 'DEPOSIT') ? 'deposit' : 'withdraw'
acc[type].smarkets = activity.smarkets.filter(s => {
return s.source === typeToGet
}).map(s => {
return {
exchange: 'SMARKETS',amount: parseFloat(s.money_change),date: getFormattedDate(s.timestamp)
}
})
}
}
return acc
},{
DEPOSIT: {},WITHDRAWAL: {}
})
}
function getFormattedDate(date) {
const parsed = dayjs(date)
const day = parsed
.date()
.toString()
.padStart(2,'0')
// Unsure why have to add 1 but don't care really
const mnth = (parsed
.month() + 1)
.toString()
.padStart(2,'0')
const yr = parsed
.year()
.toString()
.padStart(2,'0')
const hr = parsed
.hour()
.toString()
.padStart(2,'0')
const min = parsed
.minute()
.toString()
.padStart(2,'0')
return `${day}/${mnth}/${yr} @ ${hr}:${min}`
}
function getXAxis(balances,annotations) {
const balanceDates = balances.map(entry => {
return getFormattedDate(entry.date)
})
const annotationDates = annotations.map(ann => {
return ann.value
})
return [
...balanceDates,...annotationDates
]
}
const ProfitsLineChart = props => {
const { isDark } = useContext(AppContext)
const depositsAndWithdrawals = getDepositsAndWithdrawals(props.activity)
const annotations = Object.values(depositsAndWithdrawals).reduce((acc,exs) => {
const newEntries = Object.values(exs).map(entries => {
return entries.map(entry => {
return {
type: 'line',mode: 'vertical',drawTime: 'afterDatasetDraw',scaleID: 'x-axis-0',value: entry.date,borderColor: isDark
? exchangeChartColors.dark[entry.exchange.toLowerCase()]
: exchangeChartColors.light[entry.exchange.toLowerCase()],borderWidth: 2,label: {
content: `${entry.exchange} ~ ${entry.type} ~ ${entry.amount}`,enabled: true,position: 'top'
}
}
})
})
return [
...acc,...flatten(newEntries)
]
},[])
const config = {
data(canvas) {
let datasets = exchanges.map(exchange => {
return {
exchange,data: props.balances.reduce((acc,entry) => {
const entryForExchange = entry.balances.find(balance => {
return balance.exchange.toUpperCase() === exchange.toUpperCase()
})
if (entryForExchange) {
acc.push({
date: entry.date,balance: entryForExchange.balance
})
}
return acc
},[])
}
})
let labels = getXAxis(props.balances,annotations)
// If not specified time period,only show most recent (30) entries
if (!props.start && !props.end) {
datasets = datasets.map(ds => {
return {
...ds,data: ds.data.slice(ds.data.length - 50,ds.data.length)
}
})
labels = labels.slice(labels.length - 50,labels.length)
}
return {
labels,datasets: datasets.map(set => {
return {
label: capitalize(set.exchange),fill: false,data: set.data.map(s => s.balance.toFixed(2)),borderColor: isDark ? exchangeChartColors.dark[set.exchange.toLowerCase()] : exchangeChartColors.light[set.exchange.toLowerCase()],backgroundColor: isDark ? exchangeChartColors.dark[set.exchange.toLowerCase()] : exchangeChartColors.light[set.exchange.toLowerCase()]
}
})
}
},options: {
annotation: {
annotations
},responsive: true,title: {
display: true,text: 'Balances',fontSize: 20,fontStyle: 'bold',lineHeight: 2.5,fontColor: rgbaColor('#cccccc',0.7)
},legend: {
labels: {
fontSize: 16,fontStyle: 'italic',0.7)
},display: true,position: 'bottom'
},tooltips: {
mode: 'index',displayColors: true
},hover: {
mode: 'label'
},scales: {
xAxes: [
{
display: true,id: 'x-axis-0',scaleLabel: {
display: true,labelString: 'Time',fontSize: 12,0.7)
},ticks: {
callback: () => '',0.7),fontStyle: 600
}
}
],yAxes: [
{
display: true,id: 'y-axis-0',labelString: 'Balance (£)',fontSize: 14,ticks: {
min: 0,fontStyle: 600
}
}
]
}
}
}
return !props.balances.length ? (
<Card classname="text-center mb-3">
<CardBody classname="p-5">
<div classname="display-2 text-200">No Data</div>
<p classname="lead mt-4 text-800 text-sans-serif font-weight-semi-bold">There are no balances to display.</p>
<hr />
<p>Please edit your time period search (or remove it altogether) to see data</p>
</CardBody>
</Card>
) : (
<Card classname="mb-3">
<CardBody classname="rounded-soft bg-gradient">
<Line data={config.data} options={config.options} />
</CardBody>
</Card>
)
}
export default ProfitsLineChart
这是图表正在使用的配置:
{
"options": {
"annotation": {
"annotations": [
{
"type": "line","mode": "vertical","drawTime": "afterDatasetDraw","scaleID": "x-axis-0","value": "08/03/2020 @ 14:47","borderColor": "rgba(239,131,0.8)","borderWidth": 2,"label": {
"content": "BETFAIR ~ DEPOSIT ~ 22","enabled": true,"position": "top"
}
},{
"type": "line","value": "03/03/2020 @ 23:04","borderColor": "rgba(119,255,"label": {
"content": "BETDAQ ~ DEPOSIT ~ 26.57","value": "19/03/2020 @ 17:57","borderColor": "rgba(68,254,59,"label": {
"content": "SMARKETS ~ DEPOSIT ~ 21","value": "27/03/2020 @ 12:55","label": {
"content": "BETFAIR ~ WITHDRAWAL ~ -10","value": "27/03/2020 @ 13:02","label": {
"content": "BETDAQ ~ WITHDRAWAL ~ -10","value": "01/03/2020 @ 09:45","label": {
"content": "SMARKETS ~ WITHDRAWAL ~ -26.57","position": "top"
}
}
]
}
},"responsive": true,"title": {
"display": true,"text": "Balances","fontSize": 20,"fontStyle": "bold","lineHeight": 2.5,"fontColor": "rgba(204,204,0.7)"
},"legend": {
"labels": {
"fontSize": 16,"fontStyle": "italic",0.7)"
},"display": true,"position": "bottom"
},"tooltips": {
"mode": "index","displayColors": true
},"hover": {
"mode": "label"
},"scales": {
"xAxes": [
{
"display": true,"id": "x-axis-0","scaleLabel": {
"display": true,"labelString": "Time","fontSize": 12,0.7)"
},"ticks": {
"fontColor": "rgba(204,0.7)","fontStyle": 600
}
}
],"yAxes": [
{
"display": true,"id": "y-axis-0","labelString": "Balance (£)","fontSize": 14,"ticks": {
"min": 0,"fontStyle": 600
}
}
]
}
}
我想不出为什么这没有按预期进行。 getXAxis
确保将注释的字符串时间戳也添加到X轴。我迷失了主意