Commit 3ce01500 authored by Guillaume Jimenez's avatar Guillaume Jimenez

Added Failure Rate Reports

parent 6b8f564b
......@@ -19,7 +19,8 @@
<script src="//cdnjs.cloudflare.com/ajax/libs/Sortable/1.6.0/Sortable.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/Vue.Draggable/2.14.1/vuedraggable.min.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<!-- <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> -->
<script src="https://unpkg.com/vue-router@3.1.3/dist/vue-router.js"></script>
<script src="https://unpkg.com/vuetify@1.5.16/dist/vuetify.min.js"></script>
......@@ -36,7 +37,7 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.min.js"></script>
<script src="https://unpkg.com/vue-chartjs/dist/vue-chartjs.min.js"></script>
<script src="https://cdn.zingchart.com/zingchart.min.js"></script>
<!-- <script src="https://cdn.zingchart.com/zingchart.min.js"></script> -->
<c:forEach var = "componentFile" items="${componentFiles}">
<script src="${pageContext.request.contextPath}/resources/js/components/${componentFile}?timestamp=${timestamp}"></script>
......
......@@ -6,7 +6,7 @@
background-color: rgb(25, 118, 210);
}
.list__tile .avatar, .list__tile__action {
.v-list__tile .avatar, .v-list__tile__action {
min-width: 25px;
}
......@@ -21,7 +21,7 @@ th, td {
tr:nth-child(even) {background-color: #fafafa}
.dense-tiles .list__tile {
.dense-tiles .v-list__tile {
height: fit-content;
}
......@@ -50,7 +50,7 @@ a {
height: calc(100%);
}
.toolbar__title {
.v-toolbar__title {
overflow: visible;
}
......@@ -115,7 +115,7 @@ table.table tbody td:first-child, table.table tbody td:not(:first-child), table.
margin: unset;
}
.input-group--text-field.input-group--textarea:not(.input-group--full-width) .input-group__input {
.input-group--text-field.input-group--textarea:not(.input-group--full-width) .v-input-group__input {
padding: 10px 5px 10px 5px;
}
......@@ -129,7 +129,7 @@ table.table tbody td:first-child, table.table tbody td:not(:first-child), table.
} */
/* remove padding underneath checkboxes */
.no-height > .input-group__details {
.no-height > .v-input-group__details {
min-height: auto !important;
}
......@@ -141,7 +141,7 @@ table.table tbody td:first-child, table.table tbody td:not(:first-child), table.
cursor: move;
}
.draggable > .chip__content {
.draggable > .v-chip__content {
cursor: move;
}
......@@ -178,7 +178,7 @@ table.table tbody td:first-child, table.table tbody td:not(:first-child), table.
padding-bottom: 0px;
}
.toolbar__title {
.v-toolbar__title {
overflow: visible;
}
......
......@@ -41,6 +41,7 @@ const Home = {
<v-tab href="#tab-tat-samples" @click="activeTab = 'tab-tat-samples'">TAT Per Sample</v-tab>
<v-tab href="#tab-timesTaken" @click="activeTab = 'tab-timesTaken'">Order Time Span</v-tab>
<v-tab href="#tab-alignment" @click="activeTab = 'tab-alignment'">Alignment</v-tab>
<v-tab href="#tab-reports" @click="activeTab = 'tab-reports'">Reports</v-tab>
</v-tabs>
<v-spacer></v-spacer>
<v-menu lazy :close-on-content-click="false" v-model="monthVisible" transition="scale-transition" offset-y
......@@ -66,7 +67,7 @@ const Home = {
<data-table ref="monthlySamples" :fixed="false" :fetch-on-created="false" @need-manual-data="getMonthlySummary('monthlySamples', 'getMonthlySampleSummary')"
expanded-data-url="./getSampleDetailsTableExpansionAjaxVuetify"
:table-title="tableTitle + selectedMonthFormatted" :initial-sort="'limsId'" no-data-text="No Data" class="pt-2">
:table-title="tableTitle + selectedMonthFormatted" :initial-sort="'limsId'" no-data-text="No Data" class="pt-2" :disable-sticky-header="true">
</data-table>
</v-tab-item>
......@@ -76,7 +77,7 @@ const Home = {
</div>
<data-table ref="tatSamplesTable" :fixed="false" :fetch-on-created="true" @need-manual-data="getTATPerSampleTableData('tatSamplesTable', 'getTATPerSampleData')"
:table-title="tatPerSampleChartTitle" :initial-sort="'limsId'" no-data-text="No Data" class="pt-2">
:table-title="tatPerSampleChartTitle" :initial-sort="'limsId'" no-data-text="No Data" class="pt-2" :disable-sticky-header="true">
</data-table>
</v-tab-item>
......@@ -88,15 +89,53 @@ const Home = {
<v-tab-item value="tab-alignment">
<data-table ref="monthlyDnaAlignment" :fixed="false" :fetch-on-created="false" @need-manual-data="getMonthlySummary('monthlyDnaAlignment', 'getMonthlyDnaAlignmentSummary')"
:table-title="dnaAlignmentTableTitle + selectedMonthFormatted" :initial-sort="'limsId'" no-data-text="No Data"
:table-title="dnaAlignmentTableTitle + selectedMonthFormatted" :initial-sort="'limsId'" no-data-text="No Data" :disable-sticky-header="true"
class="pt-2">
</data-table>
<data-table ref="monthlyRnaAlignment" :fixed="false" :fetch-on-created="false" @need-manual-data="getMonthlySummary('monthlyRnaAlignment', 'getMonthlyRnaAlignmentSummary')"
:table-title="rnaAlignmentTableTitle + selectedMonthFormatted" :initial-sort="'limsId'" no-data-text="No Data"
:table-title="rnaAlignmentTableTitle + selectedMonthFormatted" :initial-sort="'limsId'" no-data-text="No Data" :disable-sticky-header="true"
class="pt-2">
</data-table>
</v-tab-item>
<v-tab-item value="tab-reports">
<v-container grid-list-md>
<v-layout row wrap>
<v-flex xs12 lg12 xl8 offset-xl2>
<data-table ref="yearOnlyFailureRate" :fixed="false" :fetch-on-created="false" @need-manual-data="getFailureRateSummary('yearOnlyFailureRate', 'getYearOnlyFailureRates')"
:table-title="failureRateYearOnlyTitle" :initial-sort="'year'" no-data-text="No Data" :export-enabled="true" :disable-sticky-header="true" :show-pagination="false"
class="pt-2">
</data-table>
</v-flex>
<v-flex xs12 lg12 xl10 offset-xl1>
<data-table ref="dnaDinFailureRate" :fixed="false" :fetch-on-created="false" @need-manual-data="getFailureRateSummary('dnaDinFailureRate', 'getDnaDinFailureRates')"
:table-title="failureRateDnaDINTitle" :initial-sort="'year'" no-data-text="No Data" :export-enabled="true" :disable-sticky-header="true" :show-pagination="false"
class="pt-2">
</data-table>
</v-flex>
<v-flex xs12 lg12 xl10 offset-xl1>
<data-table ref="dnaYieldFailureRate" :fixed="false" :fetch-on-created="false" @need-manual-data="getFailureRateSummary('dnaYieldFailureRate', 'getDnaYieldFailureRates')"
:table-title="failureRateDnaYieldTitle" :initial-sort="'year'" no-data-text="No Data" :export-enabled="true" :disable-sticky-header="true" :show-pagination="false"
class="pt-2">
</data-table>
</v-flex>
<v-flex xs12 lg12 xl10 offset-xl1>
<data-table ref="rna200FailureRate" :fixed="false" :fetch-on-created="false" @need-manual-data="getFailureRateSummary('rna200FailureRate', 'getRna200FailureRates')"
:table-title="failureRateRna200Title" :initial-sort="'year'" no-data-text="No Data" :export-enabled="true" :disable-sticky-header="true" :show-pagination="false"
class="pt-2">
</data-table>
</v-flex>
<v-flex xs12 lg12 xl10 offset-xl1>
<data-table ref="rnaYieldFailureRate" :fixed="false" :fetch-on-created="false" @need-manual-data="getFailureRateSummary('rnaYieldFailureRate', 'getRnaYieldFailureRates')"
:table-title="failureRateRnaYieldTitle" :initial-sort="'year'" no-data-text="No Data" :export-enabled="true" :disable-sticky-header="true" :show-pagination="false"
class="pt-2">
</data-table>
</v-flex>
</v-layout>
</v-container>
</v-tab-item>
</v-tabs-items>
</div>`, data() { return { loading: false,
......@@ -126,6 +165,11 @@ const Home = {
tableTitle: "Metrics for Samples Received in ",
dnaAlignmentTableTitle: "DNA Alignment for ",
rnaAlignmentTableTitle: "RNA Alignment for ",
failureRateDnaDINTitle: "Success Rate DNA DIN",
failureRateDnaYieldTitle: "Success Rate DNA Yield",
failureRateRna200Title: "Success Rate RNA DV 200",
failureRateRnaYieldTitle: "Success Rate RNA Yield",
failureRateYearOnlyTitle: "Success Rate Per Threshold"
}
......@@ -192,6 +236,9 @@ const Home = {
fontSize: this.chartFontSize
}
},
plotarea:{ margin: 'dynamic dynamic dynamic dynamic',
marginBottomOffset: 80
},
preview: {
// adjustLayout: true,
// y: "60%"
......@@ -268,6 +315,9 @@ const Home = {
fontSize: this.chartFontSize
}
},
plotarea:{ margin: 'dynamic dynamic dynamic dynamic',
marginBottomOffset: 80
},
preview: {
// adjustLayout: true,
// y: "60%"
......@@ -369,6 +419,9 @@ const Home = {
fontSize: this.chartFontSize
}
},
plotarea:{ margin: 'dynamic dynamic dynamic dynamic',
marginBottomOffset: 80
},
preview: {
// adjustLayout: true,
// y: "60%"
......@@ -423,6 +476,31 @@ const Home = {
console.log(error);
});
},
getFailureRateSummary(refName, ajaxUrl) {
this.loading = true;
this.$refs[refName].startLoading();
axios.get(webAppRoot + "/" + ajaxUrl, {
params: {
refName: refName,
doExport: this.$refs[refName].doExport
}
})
.then(response => {
if (response.data.isAllowed) {
this.$refs[response.data.refName].manualData(response);
}
else {
this.handleDialogs(response, this.getFailureRateSummary.bind(null, refName, ajaxUrl));
}
this.loading = false;
this.$refs[response.data.refName].stopLoading();
})
.catch(error => {
this.loading = false;
this.$refs[refName].stopLoading();
console.log(error);
});
},
handleDialogs(response, callback) {
if (response.data.isXss) {
bus.$emit("xss-error", [this, response.data.reason]);
......@@ -461,6 +539,11 @@ const Home = {
this.getTATChartData();
this.getTimeTakenChartData();
this.getTATPerSampleChartData();
this.getFailureRateSummary('dnaDinFailureRate', 'getDnaDinFailureRates');
this.getFailureRateSummary('dnaYieldFailureRate', 'getDnaYieldFailureRates');
this.getFailureRateSummary('rna200FailureRate', 'getRna200FailureRates');
this.getFailureRateSummary('rnaYieldFailureRate', 'getRnaYieldFailureRates');
this.getFailureRateSummary('yearOnlyFailureRate', 'getYearOnlyFailureRates')
},
destroyed: function () {
zingchart.exec(this.tatChartId, 'destroy');
......
......@@ -93,7 +93,7 @@ const OrderDetails = {
<v-card>
<v-card-text>
<v-tooltip bottom>
<div class="subheading" slot="activator">Order Turn-Around Times: {{ orderTAT }}
<div class="subheading" slot="activator">Order Turn-Around Time: {{ orderTAT }}
<span v-show="orderTAT">days</span>
</div>
<span>TAT from latest Accession to Analysis</span>
......@@ -240,8 +240,8 @@ const OrderDetails = {
</v-tooltip>
<span v-if="!isValueTooLong(header.value)">
<span v-html="formattedItem(header, sample[header.value])"></span>
<v-icon class="mb-1" color="green" v-if="showPassFlag(header, sample)">check_circle</v-icon>
<v-icon class="mb-1" color="red" v-if="showFailFlag(header, sample)">cancel</v-icon>
<v-icon color="green" v-if="showPassFlag(header, sample)">check_circle</v-icon>
<v-icon color="red" v-if="showFailFlag(header, sample)">cancel</v-icon>
</span>
</v-list-tile-title>
......
......@@ -292,7 +292,8 @@ const QMetrics = {
}
},
title: {
text: this.getQMPlotTitle(response.data.fieldType)
text: this.getQMPlotTitle(response.data.fieldType),
adjustLayout: true,
},
legend: {
adjustLayout: true,
......@@ -343,6 +344,9 @@ const QMetrics = {
fontSize: this.chartFontSize
}
},
plotarea:{ margin: 'dynamic dynamic dynamic dynamic',
marginBottomOffset: 80
},
preview: {
// adjustLayout: true,
// y: "60%"
......
This diff is collapsed.
......@@ -20,6 +20,9 @@ import org.springframework.web.bind.annotation.ResponseBody;
import com.fasterxml.jackson.core.JsonProcessingException;
import utsw.bicf.nucliavault.clarity.api.utils.TypeUtils;
import utsw.bicf.nucliavault.controller.serialization.vuetify.FailureRateTableSummary;
import utsw.bicf.nucliavault.controller.serialization.vuetify.FailureRateYearOnlyTableSummary;
import utsw.bicf.nucliavault.controller.serialization.vuetify.Header;
import utsw.bicf.nucliavault.controller.serialization.vuetify.MonthlyDnaAlignmentTableSummary;
import utsw.bicf.nucliavault.controller.serialization.vuetify.MonthlyRnaAlignmentTableSummary;
import utsw.bicf.nucliavault.controller.serialization.vuetify.SampleDetailsTableSummary;
......@@ -29,6 +32,8 @@ import utsw.bicf.nucliavault.controller.serialization.zingchart.TATOrdersByMonth
import utsw.bicf.nucliavault.controller.serialization.zingchart.TimeTakenPerOrderZingChartData;
import utsw.bicf.nucliavault.dao.ModelDAO;
import utsw.bicf.nucliavault.dao.SampleDAO;
import utsw.bicf.nucliavault.model.Threshold;
import utsw.bicf.nucliavault.model.hybrid.FailureRateYearOnlyTable;
import utsw.bicf.nucliavault.model.hybrid.MonthlySampleTAT;
import utsw.bicf.nucliavault.model.hybrid.SampleTAT;
import utsw.bicf.nucliavault.model.hybrid.TimeTakenPerOrder;
......@@ -185,4 +190,116 @@ public class HomeController {
emptyTAT.setMonthLabel(expectedNextFullTatDate.format(TypeUtils.shortMonthYearFormatter).toUpperCase());
return emptyTAT;
}
@RequestMapping("/getDnaDinFailureRates")
@ResponseBody
public String getDnaDinFailureRates(Model model, HttpSession session, String refName, @RequestParam(defaultValue="false") Boolean doExport) {
try {
Threshold threshold = modelDAO.getAThreshold(Threshold.DIN);
FailureRateTableSummary summary = new FailureRateTableSummary(modelDAO, "extract_din", "dna_extract_qc", threshold);
summary.setRefName(refName);
if (doExport) {
summary.createCSVContent(new ArrayList<Header>());
}
return summary.createVuetifyObjectJSON();
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
@RequestMapping("/getDnaYieldFailureRates")
@ResponseBody
public String getDnaYieldFailureRates(Model model, HttpSession session, String refName, @RequestParam(defaultValue="false") Boolean doExport) {
try {
Threshold threshold = modelDAO.getAThreshold(Threshold.DNA_EXTRACT_YIELD);
FailureRateTableSummary summary = new FailureRateTableSummary(modelDAO, "dna_yield_ng", "dna_extract_qc", threshold);
summary.setRefName(refName);
if (doExport) {
summary.createCSVContent(new ArrayList<Header>());
}
return summary.createVuetifyObjectJSON();
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
@RequestMapping("/getRna200FailureRates")
@ResponseBody
public String getRna200FailureRates(Model model, HttpSession session, String refName, @RequestParam(defaultValue="false") Boolean doExport) {
try {
Threshold threshold = modelDAO.getAThreshold(Threshold.RNA_PCT_OVER_200);
FailureRateTableSummary summary = new FailureRateTableSummary(modelDAO, "perc_over_200_nt", "rna_extract_qc", threshold);
summary.setRefName(refName);
if (doExport) {
summary.createCSVContent(new ArrayList<Header>());
}
return summary.createVuetifyObjectJSON();
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
@RequestMapping("/getRnaYieldFailureRates")
@ResponseBody
public String getRnaYieldFailureRates(Model model, HttpSession session, String refName, @RequestParam(defaultValue="false") Boolean doExport) {
try {
Threshold threshold = modelDAO.getAThreshold(Threshold.RNA_EXTRACT_YIELD);
FailureRateTableSummary summary = new FailureRateTableSummary(modelDAO, "rna_yield_ng", "rna_extract_qc", threshold);
summary.setRefName(refName);
if (doExport) {
summary.createCSVContent(new ArrayList<Header>());
}
return summary.createVuetifyObjectJSON();
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
@RequestMapping("/getYearOnlyFailureRates")
@ResponseBody
public String getYearOnlyFailureRates(Model model, HttpSession session, String refName, @RequestParam(defaultValue="false") Boolean doExport) {
try {
Threshold threshold = modelDAO.getAThreshold(Threshold.DIN);
FailureRateTableSummary thresholdDnaDinSummary = new FailureRateTableSummary(modelDAO, "extract_din", "dna_extract_qc", threshold);
threshold = modelDAO.getAThreshold(Threshold.DNA_EXTRACT_YIELD);
FailureRateTableSummary thresholdDnaYieldSummary = new FailureRateTableSummary(modelDAO, "dna_yield_ng", "dna_extract_qc", threshold);
threshold = modelDAO.getAThreshold(Threshold.RNA_PCT_OVER_200);
FailureRateTableSummary thresholdRna200Summary = new FailureRateTableSummary(modelDAO, "perc_over_200_nt", "rna_extract_qc", threshold);
threshold = modelDAO.getAThreshold(Threshold.RNA_EXTRACT_YIELD);
FailureRateTableSummary thresholdRnaYieldSummary = new FailureRateTableSummary(modelDAO, "rna_yield_ng", "rna_extract_qc", threshold);
FailureRateYearOnlyTableSummary summary = new FailureRateYearOnlyTableSummary(thresholdDnaDinSummary, thresholdDnaYieldSummary, thresholdRna200Summary, thresholdRnaYieldSummary);
summary.setRefName(refName);
if (doExport) {
summary.createCSVContent(new ArrayList<Header>());
}
return summary.createVuetifyObjectJSON();
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
package utsw.bicf.nucliavault.controller.serialization.vuetify;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import utsw.bicf.nucliavault.dao.ModelDAO;
import utsw.bicf.nucliavault.model.Threshold;
import utsw.bicf.nucliavault.model.hybrid.FailureRate;
import utsw.bicf.nucliavault.model.hybrid.FailureRateTable;
//JSON Object with
//headerOrder: array of the headers in the order we want them displayed
//items: array of json objects containing the data with the keys matching the header's value property
//headers: array of json objects (value, text)
public class FailureRateTableSummary extends Summary<FailureRateTable>{
public static NumberFormat PCT_FORMAT = NumberFormat.getPercentInstance();
String refName;
public FailureRateTableSummary(ModelDAO modelDAO, String field, String table, Threshold threshold) {
super(getSummaryData(modelDAO, field, table, threshold), "year");
}
private static List<FailureRateTable> getSummaryData(ModelDAO modelDAO, String field, String tableName, Threshold threshold) {
List<FailureRate> data =
modelDAO.getFailureRateSummaryData(modelDAO, field, tableName, threshold.getValue());
Map<Integer, List<FailureRate>> byYear = new HashMap<Integer, List<FailureRate>>();
if (data != null) {
byYear = data.stream().collect(Collectors.groupingBy(fr -> fr.getYear()));
}
List<FailureRateTable> table = new ArrayList<FailureRateTable>();
for (Integer year : byYear.keySet()) {
Map<Integer, FailureRate> byMonth = byYear.get(year).stream().collect(Collectors.toMap(FailureRate::getMonth, Function.identity()));
FailureRateTable row = new FailureRateTable();
row.setYear(year);
row.setJan(getRateValue(byMonth.get(1)));
row.setFeb(getRateValue(byMonth.get(2)));
row.setMar(getRateValue(byMonth.get(3)));
row.setApr(getRateValue(byMonth.get(4)));
row.setMay(getRateValue(byMonth.get(5)));
row.setJun(getRateValue(byMonth.get(6)));
row.setJul(getRateValue(byMonth.get(7)));
row.setAug(getRateValue(byMonth.get(8)));
row.setSep(getRateValue(byMonth.get(9)));
row.setOct(getRateValue(byMonth.get(10)));
row.setNov(getRateValue(byMonth.get(11)));
row.setDec(getRateValue(byMonth.get(12)));
row.setTotal(getTotalRateValue(byYear.get(year)));
table.add(row);
}
return table;
}
private static String getRateValue(FailureRate fr) {
if (fr == null) {
return null;
}
return PCT_FORMAT.format((double) fr.getPass() / (fr.getPass() + fr.getFail()));
}
private static String getTotalRateValue(List<FailureRate> failureRates) {
if (failureRates == null) {
return null;
}
Long pass = failureRates.stream().collect(Collectors.summingLong(FailureRate::getPass));
Long fail = failureRates.stream().collect(Collectors.summingLong(FailureRate::getFail));
return PCT_FORMAT.format((double) pass / (pass + fail));
}
@Override
public void initializeHeaders() {
Header year = new Header("Year", "year");
// year.setWidth("50px");
headers.add(year);
Header jan = new Header("Jan", "jan");
// jan.setWidth("50px");
headers.add(jan);
Header feb = new Header("Feb", "feb");
// feb.setWidth("50px");
headers.add(feb);
Header mar = new Header("Mar", "mar");
// mar.setWidth("50px");
headers.add(mar);
Header apr = new Header("Apr", "apr");
// apr.setWidth("50px");
headers.add(apr);
Header may = new Header("May", "may");
// may.setWidth("50px");
headers.add(may);
Header jun = new Header("Jun", "jun");
// jun.setWidth("50px");
headers.add(jun);
Header jul = new Header("Jul", "jul");
// jul.setWidth("50px");
headers.add(jul);
Header aug = new Header("Aug", "aug");
// aug.setWidth("50px");
headers.add(aug);
Header sep = new Header("Sep", "sep");
// sep.setWidth("50px");
headers.add(sep);
Header oct = new Header("Oct", "oct");
// oct.setWidth("50px");
headers.add(oct);
Header nov = new Header("Nov", "nov");
// nov.setWidth("50px");
headers.add(nov);
Header dec = new Header("Dec", "dec");
// dec.setWidth("50px");
headers.add(dec);
Header total = new Header("Total", "total");
// total.setWidth("50px");
headers.add(total);
//keep in the same order
headerOrder = headers.stream().map(header -> header.getValue()).collect(Collectors.toList());
}
public String getRefName() {
return refName;
}
public void setRefName(String refName) {
this.refName = refName;
}
}
package utsw.bicf.nucliavault.controller.serialization.vuetify;
import java.text.NumberFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import utsw.bicf.nucliavault.model.hybrid.FailureRateTable;
import utsw.bicf.nucliavault.model.hybrid.FailureRateYearOnlyTable;
//JSON Object with
//headerOrder: array of the headers in the order we want them displayed
//items: array of json objects containing the data with the keys matching the header's value property
//headers: array of json objects (value, text)
public class FailureRateYearOnlyTableSummary extends Summary<FailureRateYearOnlyTable>{
public static NumberFormat PCT_FORMAT = NumberFormat.getPercentInstance();
String refName;
public FailureRateYearOnlyTableSummary(FailureRateTableSummary thresholdDnaDinSummary,
FailureRateTableSummary thresholdDnaYieldSummary, FailureRateTableSummary thresholdRna200Summary,
FailureRateTableSummary thresholdRnaYieldSummary) {
super(getSummaryData(thresholdDnaDinSummary, thresholdDnaYieldSummary, thresholdRna200Summary, thresholdRnaYieldSummary), "year");
}
private static List<FailureRateYearOnlyTable> getSummaryData(FailureRateTableSummary thresholdDnaDinSummary,
FailureRateTableSummary thresholdDnaYieldSummary, FailureRateTableSummary thresholdRna200Summary,
FailureRateTableSummary thresholdRnaYieldSummary) {
Map<Integer, FailureRateYearOnlyTable> byYear = new HashMap<Integer, FailureRateYearOnlyTable>();
for (FailureRateTable frt : thresholdDnaDinSummary.getItems()) {
FailureRateYearOnlyTable row = byYear.get(frt.getYear());
if (row == null) {
row = new FailureRateYearOnlyTable();
row.setYear(frt.getYear());
byYear.put(frt.getYear(), row);
}
row.setDnaDin(frt.getTotal());
}
for (FailureRateTable frt : thresholdDnaYieldSummary.getItems()) {
FailureRateYearOnlyTable row = byYear.get(frt.getYear());
if (row == null) {
row = new FailureRateYearOnlyTable();
row.setYear(frt.getYear());
byYear.put(frt.getYear(), row);
}
row.setDnaYield(frt.getTotal());
}
for (FailureRateTable frt : thresholdRna200Summary.getItems()) {
FailureRateYearOnlyTable row = byYear.get(frt.getYear());
if (row == null) {
row = new FailureRateYearOnlyTable();
row.setYear(frt.getYear());
byYear.put(frt.getYear(), row);
}
row.setRna200(frt.getTotal());
}
for (FailureRateTable frt : thresholdRnaYieldSummary.getItems()) {
FailureRateYearOnlyTable row = byYear.get(frt.getYear());
if (row == null) {
row = new FailureRateYearOnlyTable();
row.setYear(frt.getYear());
byYear.put(frt.getYear(), row);
}
row.setRnaYield(frt.getTotal());
}
return byYear.values().stream().collect(Collectors.toList());
}
@Override
public void initializeHeaders() {
Header year = new Header("Year", "year");
year.setWidth("50px");
headers.add(year);
Header jan = new Header("DNA DIN", "dnaDin");
jan.setWidth("50px");
headers.add(jan);
Header feb = new Header("DNA Yield", "dnaYield");
feb.setWidth("50px");
headers.add(feb);
Header mar = new Header("RNA 200", "rna200");
mar.setWidth("50px");
headers.add(mar);
Header apr = new Header("RNA Yield", "rnaYield");
apr.setWidth("50px");
headers.add(apr);