Skip to content
Snippets Groups Projects
AxisBottom.tsx 3.7 KiB
Newer Older
  • Learn to ignore specific revisions
  • Hugo NOUTS's avatar
    Hugo NOUTS committed
    import React from 'react'
    import { ScaleBand } from 'd3-scale'
    import { IDataload, TimeStep } from 'services/dataConsumptionContracts'
    import { compareStepDate } from 'services/dateChartService'
    import { DateTime } from 'luxon'
    
    interface TextTypeProps {
      index: number
      dataload: IDataload
      timeStep: TimeStep
      width: number
      selectedDate: DateTime
    }
    
    function TextAxis(props: TextTypeProps) {
      const { index, dataload, timeStep, width, selectedDate } = props
      const isSelectedDate = compareStepDate(timeStep, selectedDate, dataload.date)
      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' })}
              </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' })}
              </tspan>
            </text>
          )
        case TimeStep.DAY:
          return (
            <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: '2-digit' })}
              </tspan>
            </text>
          )
        case TimeStep.HOUR:
          return (index + 1) % 2 ? (
            <text y="10" dy="0.71em" transform={`translate(${width})`}>
              <tspan className={style} textAnchor="middle">
                {dataload.date.hour}
              </tspan>
            </text>
          ) : null
        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">
                {'-'}
              </tspan>
            </text>
          )
      }
    }
    
    interface AxisBottomProps {
      data: IDataload[]
      timeStep: TimeStep
      xScale: ScaleBand<string>
      height: number
      marginLeft: number
      marginBottom: number
      selectedDate: DateTime
    }
    
    const AxisBottom = (props: AxisBottomProps) => {
      const {
        data,
        timeStep,
        xScale,
        height,
        marginLeft,
        marginBottom,
        selectedDate,
      } = props
      const dashArray = `${height / 30} ${height / 30}`
    
      return (
        <g
          className="axis x"
          transform={`translate(${marginLeft}, ${height - marginBottom})`}
        >
          {data.map((d, index) => (
            <g
              key={index}
              className="tick"
              opacity="1"
              transform={`translate(${xScale(
                d.date.toLocaleString(DateTime.DATETIME_SHORT)
              )}, 0)`}
            >
              <TextAxis
                index={index}
                dataload={d}
                timeStep={timeStep}
                width={xScale.bandwidth() / 2}
                selectedDate={selectedDate}
              />
              {compareStepDate(timeStep, DateTime.local(), d.date) ? (
                <line
                  stroke="white"
                  strokeLinecap="round"
                  strokeDasharray={dashArray}
                  x1={xScale.bandwidth() / 2}
                  x2={xScale.bandwidth() / 2}
                  y1="0"
                  y2={-(height - marginBottom)}
                ></line>
              ) : null}
            </g>
          ))}
        </g>
      )
    }
    
    export default AxisBottom