Аннотации не отображаются на диаграмме JS - Реакция - PullRequest
0 голосов
/ 27 марта 2020

Наборы данных отображаются на моем линейном графике нормально, но я пытаюсь отобразить вертикальные линии на графике, используя chartjs-plugin-annotation. Из этих вопросов и ответов:

Я думал, что у меня правильная конфигурация, но строки не отображаются.

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',
                        type: type,
                        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',
                        type: type,
                        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),
                        borderWidth: 2,
                        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',
                    fontColor: rgbaColor('#cccccc', 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,
                            fontColor: rgbaColor('#cccccc', 0.7)
                        },
                        ticks: {
                            callback: () => '',
                            fontColor: rgbaColor('#cccccc', 0.7),
                            fontStyle: 600
                        }
                    }
                ],
                yAxes: [
                    {
                        display: true,
                        id: 'y-axis-0',
                        scaleLabel: {
                            display: true,
                            labelString: 'Balance (£)',
                            fontSize: 14,
                            fontColor: rgbaColor('#cccccc', 0.7)
                        },
                        ticks: {
                            min: 0,
                            fontColor: rgbaColor('#cccccc', 0.7),
                            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, 0.8)",
                    "borderWidth": 2,
                    "label": {
                        "content": "BETFAIR ~ DEPOSIT ~ 22",
                        "enabled": true,
                        "position": "top"
                    }
                },
                {
                    "type": "line",
                    "mode": "vertical",
                    "drawTime": "afterDatasetDraw",
                    "scaleID": "x-axis-0",
                    "value": "03/03/2020 @ 23:04",
                    "borderColor": "rgba(119, 0, 255, 0.8)",
                    "borderWidth": 2,
                    "label": {
                        "content": "BETDAQ ~ DEPOSIT ~ 26.57",
                        "enabled": true,
                        "position": "top"
                    }
                },
                {
                    "type": "line",
                    "mode": "vertical",
                    "drawTime": "afterDatasetDraw",
                    "scaleID": "x-axis-0",
                    "value": "19/03/2020 @ 17:57",
                    "borderColor": "rgba(68, 254, 59, 0.8)",
                    "borderWidth": 2,
                    "label": {
                        "content": "SMARKETS ~ DEPOSIT ~ 21",
                        "enabled": true,
                        "position": "top"
                    }
                },
                {
                    "type": "line",
                    "mode": "vertical",
                    "drawTime": "afterDatasetDraw",
                    "scaleID": "x-axis-0",
                    "value": "27/03/2020 @ 12:55",
                    "borderColor": "rgba(239, 131, 0, 0.8)",
                    "borderWidth": 2,
                    "label": {
                        "content": "BETFAIR ~ WITHDRAWAL ~ -10",
                        "enabled": true,
                        "position": "top"
                    }
                },
                {
                    "type": "line",
                    "mode": "vertical",
                    "drawTime": "afterDatasetDraw",
                    "scaleID": "x-axis-0",
                    "value": "27/03/2020 @ 13:02",
                    "borderColor": "rgba(119, 0, 255, 0.8)",
                    "borderWidth": 2,
                    "label": {
                        "content": "BETDAQ ~ WITHDRAWAL ~ -10",
                        "enabled": true,
                        "position": "top"
                    }
                },
                {
                    "type": "line",
                    "mode": "vertical",
                    "drawTime": "afterDatasetDraw",
                    "scaleID": "x-axis-0",
                    "value": "01/03/2020 @ 09:45",
                    "borderColor": "rgba(68, 254, 59, 0.8)",
                    "borderWidth": 2,
                    "label": {
                        "content": "SMARKETS ~ WITHDRAWAL ~ -26.57",
                        "enabled": true,
                        "position": "top"
                    }
                }
            ]
        }
    },
    "responsive": true,
    "title": {
        "display": true,
        "text": "Balances",
        "fontSize": 20,
        "fontStyle": "bold",
        "lineHeight": 2.5,
        "fontColor": "rgba(204,204,204,0.7)"
    },
    "legend": {
        "labels": {
            "fontSize": 16,
            "fontStyle": "italic",
            "fontColor": "rgba(204,204,204,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,
                    "fontColor": "rgba(204,204,204,0.7)"
                },
                "ticks": {
                    "fontColor": "rgba(204,204,204,0.7)",
                    "fontStyle": 600
                }
            }
        ],
        "yAxes": [
            {
                "display": true,
                "id": "y-axis-0",
                "scaleLabel": {
                    "display": true,
                    "labelString": "Balance (£)",
                    "fontSize": 14,
                    "fontColor": "rgba(204,204,204,0.7)"
                },
                "ticks": {
                    "min": 0,
                    "fontColor": "rgba(204,204,204,0.7)",
                    "fontStyle": 600
                }
            }
        ]
    }
}

Я не могу понять, почему это не работает, как предполагалось. getXAxis гарантирует, что временные метки строк аннотаций также добавляются к оси X. Я потерян для идей

...