Skip to content
Snippets Groups Projects
Commit cafd4792 authored by Reinder Kraaij's avatar Reinder Kraaij :eye:
Browse files

Resolve TMSS-2875 "Part iii front end only"

parent 3f6197d1
No related branches found
No related tags found
1 merge request!1263Resolve TMSS-2875 "Part iii front end only"
import { Component } from 'react';
import flatpickr from 'flatpickr';
import "flatpickr/dist/flatpickr.css";
export default class CustomDateComponent extends Component {
constructor(props) {
super(props);
this.state = {
date: null,
};
}
isPopup() {
return true;
}
render() {
//Inlining styles to make simpler the component
return (
<div
className="ag-input-wrapper custom-date-filter"
role="presentation"
ref="flatpickr"
style={{ height: '50px', width: '90%' }}>
<input type="text" ref="eInput" data-input style={{ width: '100%',}} />
<a className="input-button" title="clear" data-clear>
<i className="pi pi-times"></i>
</a>
</div>
);
}
componentDidMount() {
this.picker = flatpickr(this.refs.flatpickr, {
onChange: this.onDateChanged.bind(this),
dateFormat: 'd-M-Y',
timeFormat: "h:m:d",
wrap: true,
showClearButton: false,
inlineHideInput: true,
defaultHour: 0,
defaultMinute: 1,
enableSeconds: true,
defaultSecond: 0,
hourIncrement: 1,
minuteIncrement: 1,
secondIncrement: 5,
time_24hr: true,
allowInput: true
});
this.eInput = this.refs.eInput;
this.picker.calendarContainer.classList.add('ag-custom-component-popup');
}
//*********************************************************************************
// METHODS REQUIRED BY AG-GRID
//*********************************************************************************
getDate() {
//ag-grid will call us here when in need to check what the current date value is hold by this
//component.
return this.state.date;
}
setDate(date) {
//ag-grid will call us here when it needs this component to update the date that it holds.
this.setState({ date });
this.picker.setDate(date);
}
//*********************************************************************************
// AG-GRID OPTIONAL METHODS
//*********************************************************************************
setInputPlaceholder(placeholder) {
this.eInput.setAttribute('placeholder', placeholder);
}
setInputAriaLabel(label) {
this.eInput.setAttribute('aria-label', label);
}
//*********************************************************************************
// LINKS THE INTERNAL STATE AND AG-GRID
//*********************************************************************************
updateAndNotifyAgGrid(date) {
this.setState(
{
date,
},
//Callback after the state is set. This is where we tell ag-grid that the date has changed so
//it will proceed with the filtering and we can then expect ag-Grid to call us back to getDate
this.props.onDateChanged
);
}
//*********************************************************************************
// LINKING THE UI, THE STATE AND AG-GRID
//*********************************************************************************
onDateChanged = (selectedDates) => {
this.props.context.componentParent.updateTime(
this.props.node.rowIndex,this.props.colDef.field,selectedDates[0]
);
// this.updateAndNotifyAgGrid(selectedDates[0]);
};
}
\ No newline at end of file
...@@ -113,3 +113,8 @@ ...@@ -113,3 +113,8 @@
left:5px; left:5px;
} }
} }
.chartbar {
height: 170px;
}
\ No newline at end of file
...@@ -73,7 +73,8 @@ const FailureBusinessPdf = { ...@@ -73,7 +73,8 @@ const FailureBusinessPdf = {
await addelement("chart6", 200, 120); await addelement("chart6", 200, 120);
pdf.addPage('l', 'mm', [297, 210]); pdf.addPage('l', 'mm', [297, 210]);
pdf.text(10, 10, 'Failure Report ' + title + " page 2"); pdf.text(10, 10, 'Failure Report ' + title + " page 2");
await addSizedElement("chart7", 0, 20, 2, 3); await addelement("chart8", 200, 20);
await addSizedElement("chart7", 20, 50, 2, 2);
pdf.setFontSize(5); pdf.setFontSize(5);
this.writeTable(pdf,failureReport); this.writeTable(pdf,failureReport);
pdf.save(`FailureReport_${title}.pdf`); pdf.save(`FailureReport_${title}.pdf`);
......
...@@ -23,6 +23,10 @@ const FailureBusinessTemplate = { ...@@ -23,6 +23,10 @@ const FailureBusinessTemplate = {
if (!data?.["issue_subtype(s)"]) return "" if (!data?.["issue_subtype(s)"]) return ""
return data["issue_subtype(s)"].filter((value, index, self) => { return self.indexOf(value) === index; }).join(", ") return data["issue_subtype(s)"].filter((value, index, self) => { return self.indexOf(value) === index; }).join(", ")
}, },
ProjectTemplate: function (data) {
if (!data?.["project"]) return <span></span>
return <a href={"/project/view/" + data["project"]} target="_blank" rel="noreferrer" >{data["project"]}</a>
},
......
export const HistoricData = { export const HistoricData = {
"lost_time_histogram_on_sky": { "lost_time_histogram_on_sky": {
"2017-01-01": 0.0,
"2017-02-01": 0,
"2017-03-01": 0,
"2017-04-01": 0,
"2017-05-01": 93, "2017-05-01": 93,
"2017-06-01": 85, "2017-06-01": 85,
"2017-07-01": 108, "2017-07-01": 108,
......
...@@ -5,7 +5,7 @@ import { Calendar } from 'primereact/calendar'; ...@@ -5,7 +5,7 @@ import { Calendar } from 'primereact/calendar';
import { Button } from 'primereact/button'; import { Button } from 'primereact/button';
import { ProgressBar } from 'primereact/progressbar'; import { ProgressBar } from 'primereact/progressbar';
import ReportService from '../../../services/report.service'; import ReportService from '../../../services/report.service';
import { HistoricData} from './failure.historic.data'
import { DataTable } from 'primereact/datatable'; import { DataTable } from 'primereact/datatable';
import { Column } from 'primereact/column'; import { Column } from 'primereact/column';
import PageHeader from '../../../layout/components/PageHeader'; import PageHeader from '../../../layout/components/PageHeader';
...@@ -29,6 +29,7 @@ export default function FailureReport() { ...@@ -29,6 +29,7 @@ export default function FailureReport() {
const [chartData_sub_Issue_total_duration_options, setChartData_sub_Issue_total_duration_options] = useState({}); const [chartData_sub_Issue_total_duration_options, setChartData_sub_Issue_total_duration_options] = useState({});
const [chartObservingTimeBarData, setChartObservingTimeBarData] = useState({}); const [chartObservingTimeBarData, setChartObservingTimeBarData] = useState({});
const [chartWallTimeData, setChartWallTimeData] = useState({}); const [chartWallTimeData, setChartWallTimeData] = useState({});
const [chartWallTimeMainData, setChartWallTimeMainData] = useState({});
const [chartWallTimeSubTypeData, setChartWallTimeSubTypeData] = useState({}); const [chartWallTimeSubTypeData, setChartWallTimeSubTypeData] = useState({});
const [chartOptions, setChartOptions] = useState({}); const [chartOptions, setChartOptions] = useState({});
...@@ -40,7 +41,7 @@ export default function FailureReport() { ...@@ -40,7 +41,7 @@ export default function FailureReport() {
} }
}, [dates]); }, [dates]);
const MakeChartData = (element, key, labelkey) => { const MakePieChartData = (element, key, labelkey) => {
const documentStyle = getComputedStyle(document.documentElement); const documentStyle = getComputedStyle(document.documentElement);
return { return {
labels: element?.map(item => item[labelkey]), labels: element?.map(item => item[labelkey]),
...@@ -78,9 +79,9 @@ export default function FailureReport() { ...@@ -78,9 +79,9 @@ export default function FailureReport() {
function MakePieChart(failureReport) { function MakePieChart(failureReport) {
let pieelement = failureReport?.system_event_summary?.by_issue_type; let pieelement = failureReport?.system_event_summary?.by_issue_type;
if (pieelement !== null) { if (pieelement !== null) {
setChartData_Issue_count(MakeChartData(pieelement, "count", "issue_type__value")); setChartData_Issue_count(MakePieChartData(pieelement, "count", "issue_type__value"));
setChartData_Issue_count_options(MakeChartOptions("Issue Type count")); setChartData_Issue_count_options(MakeChartOptions("Issue Type count per Primary failure category"));
setChartData_Issue_total_duration(MakeChartData(pieelement, "duration_lost_event", "issue_type__value")); setChartData_Issue_total_duration(MakePieChartData(pieelement, "duration_lost_event", "issue_type__value"));
setChartData_Issue_total_duration_options({ plugins: { legend: { display: false }, title: { text: "Issue Type Duration", display: true } } }); setChartData_Issue_total_duration_options({ plugins: { legend: { display: false }, title: { text: "Issue Type Duration", display: true } } });
} }
} }
...@@ -88,9 +89,9 @@ export default function FailureReport() { ...@@ -88,9 +89,9 @@ export default function FailureReport() {
function makeSubTypePieChart(failureReport) { function makeSubTypePieChart(failureReport) {
let piesubtypeelement = failureReport?.system_event_summary?.by_issue_subtype; let piesubtypeelement = failureReport?.system_event_summary?.by_issue_subtype;
if (piesubtypeelement !== null) { if (piesubtypeelement !== null) {
setChartData_sub_Issue_count(MakeChartData(piesubtypeelement, "count", "issue_subtype__value")); setChartData_sub_Issue_count(MakePieChartData(piesubtypeelement, "count", "issue_subtype__value"));
setChartData_sub_Issue_count_options(MakeChartOptions("Issue sub Type count")); setChartData_sub_Issue_count_options(MakeChartOptions("Issue sub Type per failure sub-category"));
setChartData_sub_Issue_total_duration(MakeChartData(piesubtypeelement, "duration_lost_event", "issue_subtype__value")); setChartData_sub_Issue_total_duration(MakePieChartData(piesubtypeelement, "duration_lost_event", "issue_subtype__value"));
setChartData_sub_Issue_total_duration_options({ plugins: { legend: { display: false }, title: { text: "Sub Issue Type Duration", display: true } } }); setChartData_sub_Issue_total_duration_options({ plugins: { legend: { display: false }, title: { text: "Sub Issue Type Duration", display: true } } });
} }
} }
...@@ -101,7 +102,9 @@ export default function FailureReport() { ...@@ -101,7 +102,9 @@ export default function FailureReport() {
MakePieChart(failureReport); MakePieChart(failureReport);
makeSubTypePieChart(failureReport); makeSubTypePieChart(failureReport);
MakeLostTimeBar(failureReport, documentStyle); MakeLostTimeBar(failureReport, documentStyle);
MakeOverallWallTimeTypeBar(failureReport, documentStyle);
MakeWallTimeIssueTypeBar(failureReport, documentStyle); MakeWallTimeIssueTypeBar(failureReport, documentStyle);
MakeWallTimeSubIssueBar(failureReport, documentStyle); MakeWallTimeSubIssueBar(failureReport, documentStyle);
}, [failureReport]); }, [failureReport]);
...@@ -112,13 +115,13 @@ export default function FailureReport() { ...@@ -112,13 +115,13 @@ export default function FailureReport() {
if (lostTimeHistogram) { if (lostTimeHistogram) {
let sortedKeys = Object.keys(lostTimeHistogram).sort((a, b) => a.localeCompare(b)) let sortedKeys = Object.keys(lostTimeHistogram).sort((a, b) => a.localeCompare(b))
let sortedValues = sortedKeys.map(key => Math.floor(lostTimeHistogram[key] / 3600)); let sortedValues = sortedKeys.map(key => Math.floor(lostTimeHistogram[key] ));
setChartObservingTimeBarData({ setChartObservingTimeBarData({
labels: sortedKeys, labels: sortedKeys,
datasets: [ datasets: [
{ {
label: 'Lost observing time in hours', label: 'Overview observing hours lost per month',
backgroundColor: documentStyle.getPropertyValue('--orange-500'), backgroundColor: documentStyle.getPropertyValue('--orange-500'),
data: sortedValues, data: sortedValues,
}, },
...@@ -126,12 +129,16 @@ export default function FailureReport() { ...@@ -126,12 +129,16 @@ export default function FailureReport() {
}); });
} }
} }
function MakeOverallWallTimeTypeBar(failureReport, documentStyle) {
setChartWallTimeMainData(MakeWallTimeBarWithType(failureReport, documentStyle, "by_issue_type", "Percentage Succes versus Failures ", "issue_type__value",true))
}
function MakeWallTimeIssueTypeBar(failureReport, documentStyle) { function MakeWallTimeIssueTypeBar(failureReport, documentStyle) {
setChartWallTimeData(MakeWallTimeBarWithType(failureReport, documentStyle, "by_issue_type", "Percentage Failures by issue type", "issue_type__value")) setChartWallTimeData(MakeWallTimeBarWithType(failureReport, documentStyle, "by_issue_type", "Percentage Failures by issue type", "issue_type__value",false))
} }
function MakeWallTimeSubIssueBar(failureReport, documentStyle) { function MakeWallTimeSubIssueBar(failureReport, documentStyle) {
setChartWallTimeSubTypeData(MakeWallTimeBarWithType(failureReport, documentStyle, "by_issue_subtype", "Percentage failures by sub issue type", "issue_subtype__value")) setChartWallTimeSubTypeData(MakeWallTimeBarWithType(failureReport, documentStyle, "by_issue_subtype", "Percentage failures by sub issue type", "issue_subtype__value",false))
} }
function Colors(documentStyle, subfix) { function Colors(documentStyle, subfix) {
...@@ -150,7 +157,7 @@ export default function FailureReport() { ...@@ -150,7 +157,7 @@ export default function FailureReport() {
] ]
} }
function MakeWallTimeBarWithType(failureReport, documentStyle, type, title, typelabel) { function MakeWallTimeBarWithType(failureReport, documentStyle, type, title, typelabel,isOnlyAggregration) {
let colors = Colors(documentStyle, "500"); let colors = Colors(documentStyle, "500");
if (failureReport?.system_event_summary) { if (failureReport?.system_event_summary) {
...@@ -158,15 +165,33 @@ export default function FailureReport() { ...@@ -158,15 +165,33 @@ export default function FailureReport() {
(item, index) => ({ (item, index) => ({
type: 'bar', type: 'bar',
label: item[typelabel], label: item[typelabel],
data: [item.percent_of_wall_time_lost_event], data: [item.percent_of_wall_time_lost_on_sky],
backgroundColor: colors[index] backgroundColor: colors[index]
})); }));
byIssueType.push({
console.log("Pre isonly" ,byIssueType);
if ( isOnlyAggregration)
{
let totalFailureSum = byIssueType.reduce((sum, item) => sum + item.data[0], 0)
let RemainingBar = {
type: 'bar', type: 'bar',
label: 'no failures', label: 'Success ' + parseFloat(100-totalFailureSum).toFixed(3) ,
data: [100 - byIssueType.reduce((sum, item) => sum + item.data[0], 0)], data: [100 - totalFailureSum],
backgroundColor: documentStyle.getPropertyValue('--green-500'), backgroundColor: documentStyle.getPropertyValue('--green-500'),
}); }
let FailureBar = {
type: 'bar',
label: 'Failure ' + parseFloat(totalFailureSum).toFixed(3),
data: [ totalFailureSum],
backgroundColor: documentStyle.getPropertyValue('--red-500'),
}
byIssueType = [FailureBar,RemainingBar]
console.log("with isOnlyAggregration", byIssueType);
}
return { return {
labels: [title], labels: [title],
datasets: byIssueType datasets: byIssueType
...@@ -185,6 +210,19 @@ export default function FailureReport() { ...@@ -185,6 +210,19 @@ export default function FailureReport() {
const generateReport = async () => { const generateReport = async () => {
setIsLoading(true); setIsLoading(true);
const requestedFailureReport = await ReportService.getFailureReport(formatDateToYYYYMMDD(dates[0]) + "T00:00:00Z", formatDateToYYYYMMDD(dates[1]) + "T23:59:59Z") const requestedFailureReport = await ReportService.getFailureReport(formatDateToYYYYMMDD(dates[0]) + "T00:00:00Z", formatDateToYYYYMMDD(dates[1]) + "T23:59:59Z")
console.log("HistoricData.lost_time_histogram_on_sky", HistoricData.lost_time_histogram_on_sky)
let filteredAndConvertedHistogram = Object.entries(requestedFailureReport.data.lost_time_histogram_on_sky)
.filter(([date]) => !date.startsWith("2022"))
.reduce((acc, [date, value]) => {
acc[date] = value / 3600;
return acc;
}, {});
requestedFailureReport.data.lost_time_histogram_on_sky = { ...filteredAndConvertedHistogram, ...HistoricData.lost_time_histogram_on_sky}
console.log(requestedFailureReport.data.lost_time_histogram_on_sky)
setFailureReport(requestedFailureReport?.data); setFailureReport(requestedFailureReport?.data);
setIsLoading(false); setIsLoading(false);
} }
...@@ -199,9 +237,13 @@ export default function FailureReport() { ...@@ -199,9 +237,13 @@ export default function FailureReport() {
const textColorSecondary = documentStyle.getPropertyValue('--text-color-secondary'); const textColorSecondary = documentStyle.getPropertyValue('--text-color-secondary');
const surfaceBorder = documentStyle.getPropertyValue('--surface-border'); const surfaceBorder = documentStyle.getPropertyValue('--surface-border');
const options = { const options = {
indexAxis: 'y',
maintainAspectRatio: false, maintainAspectRatio: false,
aspectRatio: 0.7, aspectRatio: 0.7,
labels:["Observing Failure Percentage"],
plugins: { plugins: {
title: { text: "Percentage Success/Failure", display: true },
tooltips: { tooltips: {
mode: 'index', mode: 'index',
intersect: false intersect: false
...@@ -220,17 +262,14 @@ export default function FailureReport() { ...@@ -220,17 +262,14 @@ export default function FailureReport() {
x: { x: {
barPercentage: 0.3, barPercentage: 0.3,
categoryPercentage: 0.3, categoryPercentage: 0.3,
stacked: true,
ticks: { ticks: {
color: textColorSecondary color: textColorSecondary
}, },
grid: { grid: {
color: surfaceBorder color: surfaceBorder
} },
}, },
y: { y: {
max: 100,
stacked: true,
ticks: { ticks: {
color: textColorSecondary, color: textColorSecondary,
callback: function (value) { callback: function (value) {
...@@ -265,19 +304,20 @@ export default function FailureReport() { ...@@ -265,19 +304,20 @@ export default function FailureReport() {
{isLoading && <ProgressBar mode="indeterminate" style={{ height: '6px' }} className='failureProgress'> </ProgressBar>} {isLoading && <ProgressBar mode="indeterminate" style={{ height: '6px' }} className='failureProgress'> </ProgressBar>}
{failureReport && <> {failureReport && <>
<div style={{ display: "flex", flexDirection: "row", marginTop: "10px" }} > <div style={{ display: "flex", flexDirection: "row", marginTop: "10px",flexWrap:"wrap" }} >
<div className='chartbox' style={{ display: "flex", flexDirection: "row" }}> <div className='chartbox' style={{ display: "flex", flexDirection: "row" ,flexWrap:"wrap"}}>
<Chart type="pie" data={chartData_Issue_count} options={chartData_Issue_count_options} style={{ position: 'relative', width: '450px' }} id="chart1" /> <Chart type="pie" data={chartData_Issue_count} options={chartData_Issue_count_options} style={{ position: 'relative', width: '450px' }} id="chart1" />
<Chart type="pie" data={chartData_Issue_total_duration} options={chartData_Issue_total_duration_options} style={{ position: 'relative', width: '450px' }} id="chart2" /> <Chart type="pie" data={chartData_Issue_total_duration} options={chartData_Issue_total_duration_options} style={{ position: 'relative', width: '450px' }} id="chart2" />
</div> </div>
<div className='chartbox' style={{ display: "flex", flexDirection: "row" }}> <div className='chartbox' style={{ display: "flex", flexDirection: "row" ,flexWrap:"wrap"}}>
<Chart type="pie" data={chartData_sub_Issue_count} options={chartData_sub_Issue_count_options} style={{ position: 'relative', width: '450px' }} id="chart3" /> <Chart type="pie" data={chartData_sub_Issue_count} options={chartData_sub_Issue_count_options} style={{ position: 'relative', width: '450px' }} id="chart3" />
<Chart type="pie" data={chartData_sub_Issue_total_duration} options={chartData_sub_Issue_total_duration_options} style={{ position: 'relative', width: '450px' }} id="chart4" /> </div> <Chart type="pie" data={chartData_sub_Issue_total_duration} options={chartData_sub_Issue_total_duration_options} style={{ position: 'relative', width: '450px' }} id="chart4" /> </div>
</div> </div>
<div style={{ display: "flex", flexDirection: "row" }} className='pdfPage'> <div style={{ display: "flex", flexDirection: "row", flexWrap:"wrap" }} className='pdfPage'>
<Chart type="bar" data={chartWallTimeData} options={chartOptions} style={{ position: 'relative', width: '400px' }} className='chartbox' id="chart5" /> <Chart type="bar" data={chartWallTimeMainData} options={chartOptions} style={{ position: 'relative', width: '400px', heigth: '100px' }} className='chartbox chartbar' id="chart8" />
<Chart type="bar" data={chartWallTimeSubTypeData} options={chartOptions} style={{ position: 'relative', width: '400px' }} className='chartbox' id="chart6" /> <Chart type="bar" data={chartWallTimeData} options={chartOptions} style={{ position: 'relative', width: '400px', heigth: '100px' }} className='chartbox ' id="chart5" />
<Chart type="bar" data={chartWallTimeSubTypeData} options={chartOptions} style={{ position: 'relative', width: '400px', heigth: '100px' }} className='chartbox' id="chart6" />
<div style={{ width: '990px' }} className='chartbox' > <div style={{ width: '990px' }} className='chartbox' >
<div className='yaxesrotate'>hours</div> <div className='yaxesrotate'>hours</div>
...@@ -289,7 +329,7 @@ export default function FailureReport() { ...@@ -289,7 +329,7 @@ export default function FailureReport() {
<DataTable value={failureReport?.failed_scheduling_units} className='chartbox' id="failuredatatable" pr_id_13=""> <DataTable value={failureReport?.failed_scheduling_units} className='chartbox' id="failuredatatable" pr_id_13="">
<Column sortable key="name" field="name" header="name" ></Column> <Column sortable key="name" field="name" header="name" ></Column>
<Column sortable key="project" field="project" header="project" ></Column> <Column sortable key="project" field="project" header="project" body={FailureBusinessTemplate.ProjectTemplate}></Column>
<Column sortable key="status" field="status" header="status" ></Column> <Column sortable key="status" field="status" header="status" ></Column>
<Column sortable key="on_sky_start_time" field="on_sky_start_time" header="on sky start time" body={FailureBusinessTemplate.on_sky_start_time_Template} ></Column> <Column sortable key="on_sky_start_time" field="on_sky_start_time" header="on sky start time" body={FailureBusinessTemplate.on_sky_start_time_Template} ></Column>
<Column sortable key="on_sky_duration" field="on_sky_duration" header="on sky duration" body={FailureBusinessTemplate.on_sky_duration_Template} ></Column> <Column sortable key="on_sky_duration" field="on_sky_duration" header="on sky duration" body={FailureBusinessTemplate.on_sky_duration_Template} ></Column>
......
Source diff could not be displayed: it is too large. Options to address this: view the blob.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment