Skip to content
Snippets Groups Projects
AxisBottom.tsx 5.11 KiB
Newer Older
  • Learn to ignore specific revisions
  • Hugo NOUTS's avatar
    Hugo NOUTS committed
    import { ScaleBand } from 'd3-scale'
    
    import { TimeStep } from 'enums'
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    import { capitalize } from 'lodash'
    import { DateTime } from 'luxon'
    
    Yoan VALLET's avatar
    Yoan VALLET committed
    import { Dataload } from 'models'
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    import React from 'react'
    
    import DateChartService from 'services/dateChart.service'
    
    import { useAppSelector } from 'store/hooks'
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    
    interface TextTypeProps {
      index: number
    
    Yoan VALLET's avatar
    Yoan VALLET committed
      dataload: Dataload
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
      timeStep: TimeStep
      width: number
      selectedDate: DateTime
    
      displayAllDays?: boolean
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    }
    
    
    function TextAxis({
      index,
      dataload,
      timeStep,
      width,
      selectedDate,
    
    }: TextTypeProps) {
    
      const dateChartService = new DateChartService()
      const isSelectedDate = dateChartService.compareStepDate(
        timeStep,
        selectedDate,
        dataload.date
      )
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
      const style = isSelectedDate
        ? 'tick-text tick-text-selected chart-ticks-x-text'
        : 'tick-text chart-ticks-x-text'
      switch (timeStep) {
        case TimeStep.YEAR:
          return (
            <text y="10" dy="0.71em" transform={`translate(${width})`}>
              <tspan className={style} textAnchor="middle">
    
                {dataload.date.toLocaleString({ year: 'numeric' })}
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
              </tspan>
            </text>
          )
        case TimeStep.MONTH:
          return (
            <text y="10" dy="0.71em" transform={`translate(${width})`}>
              <tspan className={style} textAnchor="middle">
    
                {dataload.date.toLocaleString({ month: 'narrow' })}
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
              </tspan>
            </text>
          )
    
        case TimeStep.DAY: {
          const renderText = () => {
            if (displayAllDays) {
              return (
    
                <>
                  <tspan className={style} x="0" textAnchor="middle">
    
                    {dataload.date.toLocaleString({ weekday: 'narrow' })}
    
                  </tspan>
                  <tspan className={style} x="0" dy="1.2em" textAnchor="middle">
    
                    {dataload.date.toLocaleString({ day: 'numeric' })}
    
                  </tspan>
                </>
    
              )
            } else if (dataload.date.weekday === 1) {
              return (
    
                <>
                  <tspan className={style} x="0" textAnchor="middle">
    
    Yoan VALLET's avatar
    Yoan VALLET committed
                    {capitalize(
                      dataload.date
                        .toLocaleString({ weekday: 'short' })
                        .substring(0, 3)
                    )}
    
                  </tspan>
                  <tspan className={style} x="0" dy="1.2em" textAnchor="middle">
    
                    {dataload.date.toLocaleString({ day: 'numeric' })}
    
              )
            }
            return null
          }
          return (
            <text y="10" dy="0.71em" transform={`translate(${width})`}>
              {renderText()}
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
            </text>
          )
    
        case TimeStep.WEEK:
          return (
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
            <text y="10" dy="0.71em" transform={`translate(${width})`}>
    
              <tspan className={style} x="0" textAnchor="middle">
    
                {dataload.date.toLocaleString({ weekday: 'narrow' })}
    
              </tspan>
              <tspan className={style} x="0" dy="1.2em" textAnchor="middle">
    
                {dataload.date.toLocaleString({ day: 'numeric' })}
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
              </tspan>
            </text>
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
        case TimeStep.HALF_AN_HOUR:
          return !(index % 4) ? (
            <text x={width} y="10" dy="0.71em">
              <tspan className={style} textAnchor="middle">
                {dataload.date.hour}
              </tspan>
            </text>
          ) : null
        default:
          return (
            <text x={width} y="10" dy="0.71em">
              <tspan className={style} textAnchor="middle">
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
              </tspan>
            </text>
          )
      }
    }
    
    interface AxisBottomProps {
    
    Yoan VALLET's avatar
    Yoan VALLET committed
      data: Dataload[]
    
      timeStep: TimeStep
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
      xScale: ScaleBand<string>
      height: number
      marginLeft: number
      marginBottom: number
    
    Rémi PAPIN's avatar
    Rémi PAPIN committed
      isDuel?: boolean
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
    }
    
    
    const AxisBottom = ({
    
      xScale,
      height,
      marginLeft,
      marginBottom,
    
    }: AxisBottomProps) => {
    
      const { selectedDate } = useAppSelector(state => state.ecolyo.chart)
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
      const dashArray = `${height / 30} ${height / 30}`
    
      const dateChartService = new DateChartService()
    
      const displayAllDays = isDuel && data.length <= 15
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
      return (
        <g
          className="axis x"
          transform={`translate(${marginLeft}, ${height - marginBottom})`}
        >
          {data.map((d, index) => (
            <g
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
              key={d.date.toISO()}
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
              className="tick"
              opacity="1"
              transform={`translate(${xScale(
                d.date.toLocaleString(DateTime.DATETIME_SHORT)
              )}, 0)`}
            >
              <TextAxis
                index={index}
                dataload={d}
    
                timeStep={timeStep}
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
                width={xScale.bandwidth() / 2}
                selectedDate={selectedDate}
    
                displayAllDays={displayAllDays}
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
              />
    
              {dateChartService.compareStepDate(
    
                DateTime.local().setZone('utc', {
                  keepLocalTime: true,
                }),
    
    Rémi PAPIN's avatar
    Rémi PAPIN committed
              ) && !isDuel ? (
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
                <line
                  stroke="white"
                  strokeLinecap="round"
                  strokeDasharray={dashArray}
                  x1={xScale.bandwidth() / 2}
                  x2={xScale.bandwidth() / 2}
                  y1="0"
                  y2={-(height - marginBottom)}
    
    Hugo NOUTS's avatar
    Hugo NOUTS committed
              ) : null}
            </g>
          ))}
        </g>
      )
    }
    
    export default AxisBottom