import React, {useState} from 'react'
import { useHistory, useLocation} from 'react-router';
import useFetch from '../hooks/use-fetch';
import { useTranslation } from 'react-i18next';
import { Line } from 'react-chartjs-2'
import './pages.css'
/**
* This is the page used to display more details of the history of values of a particular sensor or Thing.
* It is shown when a {@link SingleTimeSeries} in any {@link ThingTile} is clicked.
* It contains buttons for selecting how much interval of history should be shown. Either for
* one day, one month or one year and retrieves the value history for the thing that corresponds to the
* selected time interval.
* It can only be viewed by clicking on a {@link MultipleTimeSeries} otherwise the page
* redirects to an {@link ErrorPage} instead.
*
* @category Pages
* @component
*/
const SingleChartPage = () => {
const { t, } = useTranslation();
const location = useLocation();
const history = useHistory();
if (location.state === undefined) {
history.push('/error');
}
const intervals = [t("one_day"), t("one_month"), t("one_year")]
const intervalValues = [86400, 2592000, 31104000]
let now = parseInt(Date.now()/1000);
const [state, setState] = useState({intervalIndex: 0, endTime: now, startTime: now - intervalValues[0]})
let body = JSON.stringify({
"start": state.startTime,
"end": state.endTime
});
const {isLoading, isError, data} = useFetch(location.state.url, 'POST', body, null, state.startTime, state.endTime, location.state.type);
const handleIntervalChange = (index) => {
let now = parseInt(Date.now()/1000)
setState({
intervalIndex: index,
endTime: now,
startTime: now - intervalValues[index]
})
}
if (isLoading){
return <div className="ml-3">{t("loading")}...</div>;
}
if (isError){
return <div className="ml-3">{t("error")}...</div>;
}
console.log("data: " + data)
return (
<div className="detailChart p-2">
{
intervals.map((interval, index) => {
return <button key={index}
className={`btn btn-primary text-white rounded-0 border border-primary
${index === state.intervalIndex && 'bg-white text-primary'}`}
onClick={() => handleIntervalChange(index)}>
{interval}
</button>
})
}
<SingleChartPanel
description={location.state.description}
isBinary={location.state.isBinary}
xAxesLabelString={location.state.xAxesLabelString}
yAxesLabelString={location.state.yAxesLabelString}
type={location.state.type}
dataSet={data}/>
</div>
);
}
const SingleChartPanel = ({description, isBinary, xAxesLabelString, yAxesLabelString, dataSet, type}) => {
const data = {
labels: [],
datasets: [
{
type: 'line',
backgroundColor: "#C96D4288", // Options: 00555588 C96D4288 8E9D4DBB
borderColor: "#4e73df",
fill: true,
borderWidth: 2,
data: Array.isArray(dataSet) ? getChartData(dataSet, type): null,
steppedLine: isBinary,
pointRadius: 0
}
]
}
const options = {
animation: false,
responsive : true,
maintainAspectRatio: false,
title:{
display:true,
text: description
},
legend:{
display:false,
},
elements: {
line: {
tension: 0
}
},
scales: {
yAxes: [{
ticks: {
fontSize: 8
},
scaleLabel : {
display: true,
labelString: yAxesLabelString
}
}],
xAxes: [{
ticks: {
fontSize: 8
},
type: 'time',
distribution: 'linear',
scaleLabel : {
display: true,
labelString: xAxesLabelString
}
}]
}
}
return (
<div className="w-100 h-100 p-2">
<Line data={data} options={options}/>
</div>
)
}
const getChartData = (dataSet, type) => {
const chartData = dataSet.map((data) => {
return {
x: data['time'],
y: data[type] ?? data['value']
}
});
return chartData;
}
export default SingleChartPage
Source