0

Situation: I get multiple datasets from my server, each dataset is loaded into a state and then split into data with keys and values([{x:'2021-10-25', y:20},...]).
My goal is to display the correct chronology for the dataLabels ('x' values) which match with the 'y' values for each dataset. Problems:

  1. now my code work perfectly for one dataset, but when I select two or more I get wrong chronology of dateLabels as in a link here: https://prnt.sc/26phbi5

  2. I have tried to solve this problem through options and chartjs-adapter-date-fns or luxon but I get error: 'Error: This method is not implemented: Check that a complete date adapter is provided.'

I'll get old solving this problem soon, please, can anyone help me with this?

here is my code:

import React, { useState, useEffect } from 'react'
import { CCard, CCardBody, CCol, CButton, CButtonGroup, CRow, CFormFeedback } from '@coreui/react'
import { CChartLine } from '@coreui/react-chartjs'
import { Line } from 'react-chartjs-2'
import axios from 'axios'
import { format } from 'date-fns'
import DatePicker from 'react-datepicker'
import 'react-datepicker/dist/react-datepicker.css'
import AsyncSelect from 'react-select/async'
import Chart from 'chart.js/auto'
import 'chartjs-adapter-date-fns'
import { enUS } from 'date-fns/locale'

let token = localStorage.getItem('token')
const headers = {
  headers: {
    Authorization: `Bearer ${token}`,
    'Content-Type': 'application/json',
    Accept: '*/*',
  },
}

const SalesByClubsCharts = () => {
  const [period, setPeriod] = useState('day')
  const [startDate, setStartDate] = useState(null)
  const [endDate, setEndDate] = useState(null)
  const [selectedGroup, setSelectedGroup] = useState('')
  const [selectedGroupId, setSelectedGroupId] = useState(null)
  const [chartData, setChartData] = useState({})

  // handle selection
  const handleChange = (value) => {
    let groupsId = value.map((i) => i.id).join(', ')
    setSelectedGroupId(groupsId)
    setSelectedGroup(value)
  }

  // fetch the options for showing in select field
  const loadOptions = async (inputText) => {
    const response = await fetch(
      `${process.env.REACT_APP_BASE_URL}admin/group/simple?search=${inputText}`,
      {
        method: 'GET',
        mode: 'cors',
        headers: headers.headers,
      },
    )
    const json = await response.json()
    return json
  }
  // creating colors for datasets
  const dynamicColors = function () {
    let r = Math.floor(Math.random() * 255)
    let g = Math.floor(Math.random() * 255)
    let b = Math.floor(Math.random() * 255)
    return 'rgb(' + r + ',' + g + ',' + b + ')'
  }

  useEffect(() => {
    let isCancelled = false
    const fetchChartData = async () => {
      let selectStart = startDate === null ? '' : `&selectStart=${startDate.toISOString()}`
      let selectEnd = endDate === null ? '' : `&selectEnd=${endDate.toISOString()}`
      let selectedIds = selectedGroupId === null ? '' : `groups=${selectedGroupId}&`
      let datasets = []
      await axios
        .get(
          `${process.env.REACT_APP_BASE_URL}admin/charts/sales?${selectedIds}period=${period}${selectStart}${selectEnd}`,
          headers,
        )
        .then((response) => {
          if (!isCancelled) {
            let groupsValues = Object.values(response.data.groups)
            let groupsData = Object.entries(response.data.groups)
            console.log('groupsValues', groupsValues)
            console.log('groupsData:', groupsData)
            // check if any groupID is selected otherwise it displays all groups
            if (/\d/.test(selectedIds)) {
              groupsData.forEach((group) => {
                let x_y_data = group[1].map((i) => ({
                  y: i.sales.toString().slice(0, -2),
                  x: format(new Date(i.date), 'yyyy-MM-dd'),
                }))
                console.log('x_y_data:', x_y_data)
                let color = dynamicColors()
                const newDataset = {
                  label: group[0].toString(),
                  backgroundColor: color,
                  borderColor: color,
                  data: x_y_data,
                }
                datasets.push(newDataset)
                console.log('datasets:', datasets)
              })
              setChartData({
                datasets,
              })
            }
          }
        })
        .catch((error) => console.log(error))
    }

    fetchChartData()
    return () => (isCancelled = true)
  }, [period, startDate, endDate, selectedGroupId])

  return (
    <CCard className="mb-4">
      <CCardBody>
        <CRow>
          <CCol sm={2}>
            <h5 id="traffic" className="card-title mb-0">
              Sales by Clubs
            </h5>
            <div className="small text-medium-emphasis"></div>
          </CCol>
          <CCol sm={4}>
            <AsyncSelect
              isMulti
              cacheOptions
              defaultOptions
              placeholder={'Select groups to compare'}
              value={selectedGroup}
              getOptionLabel={(e) => e.name + ' id: ' + e.id}
              getOptionValue={(e) => e.id}
              loadOptions={loadOptions}
              onChange={handleChange}
            />
          </CCol>
          <CCol sm={3}>
            <DatePicker
              placeholderText="Select a period"
              dateFormat="yyyy-MM-dd"
              minDate={new Date('2021-10-01')}
              selected={startDate}
              onChange={(dates) => {
                const [start, end] = dates
                setStartDate(start)
                setEndDate(end)
              }}
              startDate={startDate}
              endDate={endDate}
              selectsRange
            />
            <CFormFeedback invalid>Please provide a valid date.</CFormFeedback>
          </CCol>
          <CCol sm={3} className="d-none d-md-block">
            <CButtonGroup className="float-end me-3">
              {['day', 'week', 'month'].map((value) => (
                <CButton
                  color="outline-secondary"
                  key={value}
                  className="mx-0"
                  onClick={() => {
                    setPeriod(value)
                  }}
                >
                  {value}
                </CButton>
              ))}
            </CButtonGroup>
          </CCol>
        </CRow>
        <div>
          <Line data={chartData} />
        </div>
      </CCardBody>
    </CCard>
  )
}

export default SalesByClubsCharts

and here is a chunk of my data example for two datasets:

 [
 {y: '2', x: '2021-10-14'}, {y: '50', x: '2021-10-16'}, {y: '115', x: '2021-10-18'},
 {y: '105', x: '2021-10-19'}, {y: '90', x: '2021-10-20'}, {y: '65', x: '2021-10-21'},
 {y: '100', x: '2021-10-22'}, {y: '200', x: '2021-10-23'}, {y: '440', x: '2021-11-02'},
 {y: '2185', x: '2021-11-03'}, {y: '1695', x: '2021-11-04'}, {y: '1095', x: '2021-11-08'}, 
 {y: '1730', x: '2021-11-09'}, {y: '1905', x: '2021-11-10'} 
]
[
 {y: '20', x: '2021-10-14'}, {y: '520', x: '2021-10-15'}, {y: '1115', x: '2021-10-18'},
 {y: '1035', x: '2021-10-19'}, {y: '900', x: '2021-10-20'}, {y: '655', x: '2021-10-21'},
 {y: '510', x: '2021-10-22'}, {y: '65', x: '2021-10-24'}, {y: '1375', x: '2021-10-25'}, 
 {y: '925', x: '2021-10-26'}, {y: '1240', x: '2021-10-27'}, {y: '855', x: '2021-10-28'}, 
 {y: '640', x: '2021-11-02'}, {y: '218', x: '2021-11-03'}, {y: '1500', x: '2021-11-05'}, 
 {y: '1010', x: '2021-11-08'}, {y: '1250', x: '2021-11-09'}, {y: '1905', x: '2021-11-10'} ]
Gev
  • 1
  • 1

0 Answers0