Created
April 5, 2021 13:45
-
-
Save alyson-b69/f82f35b627e7d64cd0f1189d325b8fbf to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { SimpleEndCustomer, TrackerLogs } from 'redux/types'; | |
import moment from 'moment'; | |
import { colorUsage } from 'stylesheet'; | |
import { InjectedIntl } from 'react-intl'; | |
interface DataItem { | |
y: number; | |
x?: any; | |
z?: any; | |
label?: string; | |
color: string; | |
lineColor: string; | |
lineDashType?: string; | |
} | |
interface Result { | |
name: string; | |
type: string; | |
xValueType?: string; | |
showInLegend: boolean; | |
dataPoints: DataItem[]; | |
color?: string; | |
} | |
// eslint-disable-next-line complexity | |
export const renderCanvasChart = ( | |
dataLogs: TrackerLogs[], | |
dataType: string, | |
endCustomer: SimpleEndCustomer | null, | |
darkMode: boolean, | |
intl: InjectedIntl, | |
// eslint-disable-next-line max-params | |
) => { | |
const isTemperature = dataType === 'temperature'; | |
const thresholdMax: number = isTemperature | |
? endCustomer | |
? endCustomer.high_temperature_threshold_setting | |
: 30 | |
: endCustomer | |
? endCustomer.humidity_threshold | |
: 30; | |
const thresholdMin: number = isTemperature | |
? endCustomer | |
? endCustomer.low_temperature_threshold_setting | |
: -5 | |
: -5; | |
const result: Result[] = [ | |
{ | |
name: intl.formatMessage({ | |
id: isTemperature ? 'tracking.logs.temperatureMin' : 'tracking.logs.humidityMin', | |
}), | |
type: 'spline', | |
xValueType: 'dateTime', | |
showInLegend: true, | |
dataPoints: [], | |
color: colorUsage.chartBlue, | |
}, | |
{ | |
name: intl.formatMessage({ | |
id: isTemperature ? 'tracking.logs.temperatureAverage' : 'tracking.logs.humidityAverage', | |
}), | |
type: 'spline', | |
xValueType: 'dateTime', | |
showInLegend: true, | |
dataPoints: [], | |
color: colorUsage.chartGreen, | |
}, | |
{ | |
name: intl.formatMessage({ | |
id: isTemperature ? 'tracking.logs.temperatureMax' : 'tracking.logs.humidityMax', | |
}), | |
type: 'spline', | |
xValueType: 'dateTime', | |
showInLegend: true, | |
dataPoints: [], | |
color: colorUsage.chartRedBackground, | |
}, | |
{ | |
name: 'min', | |
type: 'spline', | |
xValueType: 'dateTime', | |
showInLegend: isTemperature, | |
dataPoints: [], | |
color: colorUsage.chartDarkBlue, | |
}, | |
{ | |
name: 'max', | |
type: 'spline', | |
xValueType: 'dateTime', | |
showInLegend: true, | |
dataPoints: [], | |
color: colorUsage.chartRed, | |
}, | |
]; | |
dataLogs.map(data => { | |
const minValue = isTemperature ? data.temperature_min : data.humidity_min; | |
const maxValue = isTemperature ? data.temperature_max : data.humidity_max; | |
const avgValue = isTemperature ? data.temperature_avg : data.humidity_avg; | |
if ( | |
(minValue || minValue === 0) && | |
(maxValue || maxValue === 0) && | |
(avgValue || avgValue === 0) | |
) { | |
const dateTime = moment(data.timestamp).format('DD/MM - HH:mm'); | |
const minValueData = { | |
x: moment(data.timestamp).format('x'), | |
y: minValue, | |
label: dateTime, | |
color: | |
minValue < thresholdMin | |
? colorUsage.chartDarkBlue | |
: minValue > thresholdMax | |
? colorUsage.chartRed | |
: colorUsage.chartBlue, | |
lineColor: colorUsage.chartBlue, | |
}; | |
const averageValueData = { | |
x: moment(data.timestamp).format('x'), | |
y: avgValue, | |
label: dateTime, | |
color: | |
avgValue < thresholdMin | |
? colorUsage.chartDarkBlue | |
: avgValue > thresholdMax | |
? colorUsage.chartRed | |
: colorUsage.chartGreen, | |
lineColor: colorUsage.chartGreen, | |
}; | |
const maxValueData = { | |
x: moment(data.timestamp).format('x'), | |
y: maxValue, | |
label: dateTime, | |
color: | |
maxValue < thresholdMin | |
? colorUsage.chartDarkBlue | |
: maxValue > thresholdMax | |
? colorUsage.chartRed | |
: colorUsage.chartRedBackground, | |
lineColor: colorUsage.chartRedBackground, | |
}; | |
const minData = { | |
x: moment(data.timestamp).format('x'), | |
y: thresholdMin, | |
label: dateTime, | |
color: 'transparent', | |
lineColor: colorUsage.chartDarkBlue, | |
lineDashType: 'dash', | |
}; | |
const maxData = { | |
x: moment(data.timestamp).format('x'), | |
y: thresholdMax, | |
label: dateTime, | |
color: 'transparent', | |
lineColor: colorUsage.chartRed, | |
lineDashType: 'dash', | |
}; | |
result[0].dataPoints.push(minValueData); | |
result[1].dataPoints.push(averageValueData); | |
result[2].dataPoints.push(maxValueData); | |
result[3].dataPoints.push(maxData); | |
result[4].dataPoints.push(minData); | |
} | |
return null; | |
}); | |
let labelMax = Math.max(...result[3].dataPoints.map(i => i.y)); | |
if (isTemperature) { | |
labelMax += 5; | |
} | |
const labelMin = Math.min(...result[0].dataPoints.map(i => i.y)) - 5; | |
return { | |
animationEnabled: true, | |
theme: darkMode ? 'dark1' : 'light1', | |
zoomEnabled: true, | |
height: window.innerHeight / 3.5, | |
axisX: { | |
minimum: moment(dataLogs[0].timestamp).format('x'), | |
maximum: moment(dataLogs[dataLogs.length - 1].timestamp).format('x'), | |
}, | |
axisY: { | |
title: dataType, | |
tickLength: 0, | |
interval: 10, | |
minimum: labelMin, | |
maximum: labelMax, | |
}, | |
legend: { | |
horizontalAlign: 'left', | |
verticalAlign: 'top', | |
}, | |
toolTip: { | |
shared: true, | |
borderColor: 'rgba(126, 178, 121, 1)', | |
borderThickness: 2, | |
backgroundColor: '#ffffff', | |
contentFormatter: function(e: any) { | |
let content = `<h3 class="center">${e.entries[0].dataPoint.label}</h3><br/>`; | |
content += `<span class='legend' style='background-color: ${ | |
e.entries[2].dataPoint.color | |
}'></span><span>${e.entries[2].dataSeries.name} : ${Math.round( | |
e.entries[2].dataPoint.y * 100, | |
) / 100}${isTemperature ? '°C' : ''}</span><br />`; | |
content += `<span class='legend' style='background-color: ${ | |
e.entries[1].dataPoint.color | |
}'></span><span>${e.entries[1].dataSeries.name} : ${Math.round( | |
e.entries[1].dataPoint.y * 100, | |
) / 100}${isTemperature ? '°C' : ''}</span><br />`; | |
content += `<span class='legend' style='background-color: ${ | |
e.entries[0].dataPoint.color | |
}'></span><span>${e.entries[0].dataSeries.name} : ${Math.round( | |
e.entries[0].dataPoint.y * 100, | |
) / 100}${isTemperature ? '°C' : ''}</span><br />`; | |
return content; | |
}, | |
}, | |
data: result, | |
}; | |
}; | |
export const renderShockCanvasChart = ( | |
dataLogs: TrackerLogs[], | |
endCustomer: SimpleEndCustomer | null, | |
darkMode: boolean, | |
intl: InjectedIntl, | |
) => { | |
const result: Result[] = [ | |
{ | |
name: intl.formatMessage({ | |
id: 'tracking.logs.shocks', | |
}), | |
type: 'column', | |
xValueType: 'dateTime', | |
showInLegend: true, | |
dataPoints: [], | |
color: colorUsage.chartGreen, | |
}, | |
]; | |
let shockArray: DataItem[] = []; | |
dataLogs.map((item, index) => { | |
const dateTime = moment(item.timestamp).format('DD/MM - HH:mm'); | |
if (index === 0 || (index === dataLogs.length - 1 && !item.shock_intensity)) { | |
const shockData: DataItem = { | |
x: moment(item.timestamp).format('x'), | |
y: 0, | |
label: dateTime, | |
color: colorUsage.chartGreen, | |
lineColor: colorUsage.chartGreen, | |
}; | |
shockArray.push(shockData); | |
} else if (item.shock_intensity) { | |
const shockData: DataItem = { | |
x: moment(item.timestamp).format('x'), | |
y: item.shock_intensity, | |
label: dateTime, | |
color: colorUsage.chartGreen, | |
lineColor: colorUsage.chartGreen, | |
}; | |
shockArray.push(shockData); | |
} | |
return null; | |
}); | |
let shockDataItem: DataItem = { | |
x: '', | |
y: 0, | |
z: [], | |
label: '', | |
color: colorUsage.chartGreen, | |
lineColor: colorUsage.chartGreen, | |
}; | |
shockArray.map((item, index) => { | |
if (index !== 0) { | |
let thisTime = moment(item.x, 'x').format('L'); | |
let prevTime = moment(shockArray[index - 1].x, 'x').format('L'); | |
if (thisTime === prevTime) { | |
shockDataItem = { | |
x: item.x, | |
y: shockDataItem.y + 1, | |
z: [...shockDataItem.z, { intensity: item.y, date: moment(item.x, 'x').format('HH:mm') }], | |
label: moment(item.x, 'x').format('DD/MM/YYYY'), | |
color: colorUsage.chartGreen, | |
lineColor: colorUsage.chartGreen, | |
}; | |
} else { | |
if (shockDataItem.y === 0) { | |
shockDataItem = { | |
x: item.x, | |
y: 1, | |
z: [{ intensity: item.y, date: moment(item.x, 'x').format('HH:mm') }], | |
label: moment(item.x, 'x').format('DD/MM/YYYY'), | |
color: colorUsage.chartGreen, | |
lineColor: colorUsage.chartGreen, | |
}; | |
} else { | |
result[0].dataPoints.push(shockDataItem); | |
shockDataItem = { | |
x: item.x, | |
y: 1, | |
z: [{ intensity: item.y, date: moment(item.x, 'x').format('HH:mm') }], | |
label: moment(item.x, 'x').format('DD/MM/YYYY'), | |
color: colorUsage.chartGreen, | |
lineColor: colorUsage.chartGreen, | |
}; | |
} | |
} | |
} | |
return null; | |
}); | |
return { | |
animationEnabled: true, | |
theme: darkMode ? 'dark1' : 'light1', | |
zoomEnabled: true, | |
height: window.innerHeight / 3.5, | |
axisX: { | |
minimum: moment(dataLogs[0].timestamp).format('x'), | |
maximum: moment(dataLogs[dataLogs.length - 1].timestamp).format('x'), | |
}, | |
axisY: { | |
title: intl.formatMessage({ | |
id: 'tracking.logs.shocksNumber', | |
}), | |
tickLength: 0, | |
interval: 1, | |
minimum: 0, | |
}, | |
legend: { | |
horizontalAlign: 'center', | |
verticalAlign: 'top', | |
}, | |
toolTip: { | |
shared: true, | |
borderColor: 'rgba(126, 178, 121, 1)', | |
borderThickness: 2, | |
backgroundColor: '#ffffff', | |
contentFormatter: function(e: any) { | |
let content = `<h3 class="center">${e.entries[0].dataPoint.label} - ${ | |
e.entries[0].dataPoint.y | |
} ${intl.formatMessage({ | |
id: 'tracking.logs.shock', | |
})}${e.entries[0].dataPoint.y > 1 ? 's' : ''}</h3><br/>`; | |
e.entries[0].dataPoint.z.map((item: any) => { | |
return (content += `<span class='legend' style='background-color: ${ | |
e.entries[0].dataPoint.color | |
}'></span><span>${item.date} - ${intl.formatMessage({ | |
id: 'tracking.logs.intensity', | |
})} : ${Math.round(item.intensity * 100) / 100}</span><br/>`); | |
}); | |
return content; | |
}, | |
}, | |
data: result, | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment