Newer
Older
import React, { useContext, useEffect } from 'react'
import { scaleBand, ScaleBand, scaleLinear, ScaleLinear } from 'd3-scale'
import {
IDataload,
IChartData,
TimeStep,
ITimePeriod,
} from 'services/dataConsumptionContracts'
import { FluidType } from 'enum/fluid.enum'
import Bar from 'components/ContentComponents/Charts/Bar'
import Hash from 'components/ContentComponents/Charts/Hash'
import AxisBottom from 'components/ContentComponents/Charts/AxisBottom'
import AxisRight from 'components/ContentComponents/Charts/AxisRight'
import { DateTime } from 'luxon'
import { AppContext } from 'components/Contexts/AppContextProvider'
export interface BarChartProps {
chartData: IChartData
fluidTypes: FluidType[]
timeStep: TimeStep
multiFluid: boolean
selectedDate: DateTime
showCompare: boolean
challengePeriod: ITimePeriod | null
handleClickData: (
dataload: IDataload,
compareDataload: IDataload | null
) => void
width?: number
height?: number
marginLeft?: number
marginRight?: number
marginTop?: number
marginBottom?: number
}
interface DefaultProps {
width: number
height: number
marginLeft: number
marginRight: number
marginTop: number
marginBottom: number
}
type PropsWithDefaults = BarChartProps & DefaultProps
const BarChart: React.FC<BarChartProps> = (props: BarChartProps) => {
const {
chartData,
fluidTypes,
timeStep,
multiFluid,
selectedDate,
showCompare,
challengePeriod,
handleClickData,
width,
height,
marginLeft,
marginRight,
marginTop,
marginBottom,
const { setChartIsLoaded, maxLoads } = useContext(AppContext)
const getContentWidth = () => {
return width - marginLeft - marginRight
}
const getContentHeight = () => {
return height - marginTop - marginBottom
}
const getMaxLoad = () => {
(timeStep === TimeStep.DAY && !showCompare) ||
timeStep === TimeStep.HALF_AN_HOUR
const actualMonth = selectedDate.startOf('week').month
const actualYear = selectedDate.startOf('week').year
const key = `${actualMonth}/${actualYear}-${isHome}-${fluidTypes
.sort()
if (DateTime.local() < selectedDate && !maxLoads[key]) {
maxLoads[key] = 15
}
return maxLoads[key] > 0 ? maxLoads[key] : 15
} else {
let max = chartData.actualData
? Math.max(...chartData.actualData.map(d => d.value))
: 0
const maxCompare = chartData.comparisonData
? Math.max(...chartData.comparisonData.map(d => d.value))
: 0
max = max <= 0 ? 15 : max
return showCompare ? Math.max(max, maxCompare) : max
}
}
const xScale: ScaleBand<string> = scaleBand()
.domain(
chartData.actualData.map(d =>
d.date.toLocaleString(DateTime.DATETIME_SHORT)
)
)
.range([0, getContentWidth()])
.padding(0.2)
const xScaleWithoutPadding: ScaleBand<string> = scaleBand()
.domain(
chartData.actualData.map(d =>
d.date.toLocaleString(DateTime.DATETIME_SHORT)
)
)
.range([0, getContentWidth()])
const yScale: ScaleLinear<number, number> = scaleLinear()
.domain([0, getMaxLoad()])
.range([getContentHeight(), 0])
useEffect(() => {
setChartIsLoaded(true)
}, [])
{timeStep === TimeStep.DAY && (
<g transform={`translate(${marginLeft},${marginTop})`}>
<Hash
challengePeriod={challengePeriod}
multiFluid={multiFluid}
xScale={xScale}
padding={
(xScaleWithoutPadding.bandwidth() - xScale.bandwidth()) / 2
}
width={getContentWidth()}
height={getContentHeight()}
chartData={chartData}
/>
</g>
)}
<AxisRight
fluidTypes={fluidTypes}
yScale={yScale}
width={width}
marginRight={marginRight}
marginTop={marginTop}
/>
<g transform={`translate(${marginLeft},${marginTop})`}>
{chartData.actualData.map((d, index) => (
<Bar
key={index}
index={index}
dataload={d}
compareDataload={
chartData.comparisonData ? chartData.comparisonData[index] : null
}
fluidTypes={fluidTypes}
timeStep={timeStep}
multiFluid={multiFluid}
selectedDate={selectedDate}
showCompare={showCompare}
handleClickData={handleClickData}
xScale={xScale}
yScale={yScale}
height={getContentHeight()}
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
/>
))}
</g>
<AxisBottom
data={chartData.actualData}
timeStep={timeStep}
xScale={xScale}
height={height}
marginLeft={marginLeft}
marginBottom={marginBottom}
selectedDate={selectedDate}
/>
</svg>
)
}
BarChart.defaultProps = {
width: 600,
height: 400,
marginLeft: 10,
marginRight: 60,
marginTop: 20,
marginBottom: 50,
}
export default BarChart