use of com.supercilex.robotscouter.data.model.Metric in project Robot-Scouter by SUPERCILEX.
the class SpreadsheetExporter method buildAverageColumn.
@AddTrace(name = "buildAverageColumn")
private void buildAverageColumn(Sheet sheet, TeamHelper teamHelper) {
int farthestColumn = 0;
for (Row row : sheet) {
int last = row.getLastCellNum();
if (last > farthestColumn)
farthestColumn = last;
}
Map<Chart, Pair<LineChartData, List<ChartAxis>>> chartData = new HashMap<>();
Map<Metric<Void>, Chart> chartPool = new HashMap<>();
Iterator<Row> rowIterator = sheet.rowIterator();
for (int i = 0; rowIterator.hasNext(); i++) {
Row row = rowIterator.next();
Cell cell = row.createCell(farthestColumn);
if (i == 0) {
cell.setCellValue(getString(R.string.average));
cell.setCellStyle(mCache.getColumnHeaderStyle());
continue;
}
Cell first = row.getCell(1, MissingCellPolicy.CREATE_NULL_AS_BLANK);
cell.setCellStyle(first.getCellStyle());
int type = getMetricForScouts(mScouts.get(teamHelper), mCache.getMetricKey(row)).getType();
String rangeAddress = getCellRangeAddress(first, row.getCell(cell.getColumnIndex() - 1, MissingCellPolicy.CREATE_NULL_AS_BLANK));
switch(type) {
case BOOLEAN:
cell.setCellFormula("COUNTIF(" + rangeAddress + ", TRUE) / COUNTA(" + rangeAddress + ")");
mCache.setCellFormat(cell, "0.00%");
break;
case NUMBER:
cell.setCellFormula("SUM(" + rangeAddress + ")" + " / " + "COUNT(" + rangeAddress + ")");
buildTeamChart(row, teamHelper, chartData, chartPool);
break;
case STOPWATCH:
String excludeZeros = "\"<>0\"";
cell.setCellFormula("IF(COUNTIF(" + rangeAddress + ", " + excludeZeros + ") = 0, 0, AVERAGEIF(" + rangeAddress + ", " + excludeZeros + "))");
buildTeamChart(row, teamHelper, chartData, chartPool);
break;
case LIST:
sheet.setArrayFormula("INDEX(" + rangeAddress + ", " + "MATCH(" + "MAX(" + "COUNTIF(" + rangeAddress + ", " + rangeAddress + ")" + "), " + "COUNTIF(" + rangeAddress + ", " + rangeAddress + ")" + ", 0))", new CellRangeAddress(cell.getRowIndex(), cell.getRowIndex(), cell.getColumnIndex(), cell.getColumnIndex()));
break;
case HEADER:
case TEXT:
// Nothing to average
break;
default:
throw new IllegalStateException();
}
}
for (Chart chart : chartData.keySet()) {
Pair<LineChartData, List<ChartAxis>> data = chartData.get(chart);
chart.plot(data.first, data.second.toArray(new ChartAxis[data.second.size()]));
if (chart instanceof XSSFChart) {
XSSFChart xChart = (XSSFChart) chart;
CTChart ctChart = xChart.getCTChart();
CTPlotArea plotArea = ctChart.getPlotArea();
setChartAxisTitle(plotArea.getValAxArray(0).addNewTitle(), "Values");
setChartAxisTitle(plotArea.getCatAxArray(0).addNewTitle(), "Scouts");
String name = getMetricForChart(xChart, chartPool).getName();
if (!TextUtils.isEmpty(name))
xChart.setTitle(name);
}
}
}
use of com.supercilex.robotscouter.data.model.Metric in project Robot-Scouter by SUPERCILEX.
the class SpreadsheetExporter method buildTeamAveragesSheet.
@AddTrace(name = "buildTeamAveragesSheet")
private void buildTeamAveragesSheet(Sheet averageSheet) {
Workbook workbook = averageSheet.getWorkbook();
Row headerRow = averageSheet.createRow(0);
headerRow.createCell(0);
List<Sheet> scoutSheets = getAdjustedList(workbook);
for (int i = 0; i < scoutSheets.size(); i++) {
Sheet scoutSheet = scoutSheets.get(i);
Row row = averageSheet.createRow(i + 1);
Cell rowHeaderCell = row.createCell(0);
rowHeaderCell.setCellValue(scoutSheet.getSheetName());
rowHeaderCell.setCellStyle(mCache.getRowHeaderStyle());
List<Row> metricsRows = getAdjustedList(scoutSheet);
rowIterator: for (Row averageRow : metricsRows) {
Cell averageCell = averageRow.getCell(averageRow.getLastCellNum() - 1);
Metric<?> keyMetric = mCache.getKeyMetric(averageRow.getCell(0));
if (TextUtils.isEmpty(getStringForCell(averageCell)) || keyMetric.getType() == TEXT) {
continue;
}
for (Cell keyCell : getAdjustedList(headerRow)) {
if (TextUtils.equals(keyMetric.getRef().getKey(), mCache.getMetricKey(keyCell))) {
setAverageFormula(scoutSheet, row.createCell(keyCell.getColumnIndex()), averageCell);
continue rowIterator;
}
}
Cell keyCell = headerRow.createCell(headerRow.getLastCellNum());
keyCell.setCellValue(averageRow.getCell(0).getStringCellValue());
keyCell.setCellStyle(mCache.getColumnHeaderStyle());
mCache.putKeyMetric(keyCell, keyMetric);
setAverageFormula(scoutSheet, row.createCell(keyCell.getColumnIndex()), averageCell);
}
}
buildAverageCharts(averageSheet);
}
use of com.supercilex.robotscouter.data.model.Metric in project Robot-Scouter by SUPERCILEX.
the class SpreadsheetExporter method buildTeamSheet.
@AddTrace(name = "buildTeamSheet")
private void buildTeamSheet(TeamHelper teamHelper, Sheet teamSheet) {
List<Scout> scouts = mScouts.get(teamHelper);
if (scouts.isEmpty()) {
Workbook workbook = teamSheet.getWorkbook();
workbook.removeSheetAt(workbook.getSheetIndex(teamSheet));
return;
}
Row header = teamSheet.createRow(0);
// Create empty top left corner cell
header.createCell(0);
List<Metric<?>> orderedMetrics = scouts.get(scouts.size() - 1).getMetrics();
for (int i = 0; i < orderedMetrics.size(); i++) {
Metric metric = orderedMetrics.get(i);
Row row = teamSheet.createRow(i + 1);
setupRow(row, teamHelper, metric);
}
for (int i = 0, column = 1; i < scouts.size(); i++, column++) {
Scout scout = scouts.get(i);
List<Metric<?>> metrics = scout.getMetrics();
Cell cell = header.getCell(column, MissingCellPolicy.CREATE_NULL_AS_BLANK);
String name = scout.getName();
cell.setCellValue(TextUtils.isEmpty(name) ? "Scout " + column : name);
cell.setCellStyle(mCache.getColumnHeaderStyle());
columnIterator: for (int j = 0, rowNum = 1; j < metrics.size(); j++, rowNum++) {
Metric metric = metrics.get(j);
Row row = teamSheet.getRow(rowNum);
if (row == null) {
setupRowAndSetValue(teamSheet.createRow(rowNum), teamHelper, metric, column);
} else {
List<Row> rows = getAdjustedList(teamSheet);
for (Row row1 : rows) {
Cell cell1 = row1.getCell(0);
if (TextUtils.equals(mCache.getMetricKey(row1), metric.getRef().getKey())) {
setRowValue(column, metric, row1);
if (TextUtils.isEmpty(cell1.getStringCellValue())) {
cell1.setCellValue(metric.getName());
}
continue columnIterator;
}
}
setupRowAndSetValue(teamSheet.createRow(teamSheet.getLastRowNum() + 1), teamHelper, metric, column);
}
}
}
if (scouts.size() > SINGLE_ITEM) {
buildAverageColumn(teamSheet, teamHelper);
}
}
use of com.supercilex.robotscouter.data.model.Metric in project Robot-Scouter by SUPERCILEX.
the class SpreadsheetExporter method setRowValue.
private void setRowValue(int column, Metric metric, Row row) {
row.getCell(0, MissingCellPolicy.CREATE_NULL_AS_BLANK).setCellValue(metric.getName());
Cell valueCell = row.getCell(column, MissingCellPolicy.CREATE_NULL_AS_BLANK);
switch(metric.getType()) {
case BOOLEAN:
valueCell.setCellValue((boolean) metric.getValue());
break;
case NUMBER:
Metric.Number numberMetric = (Metric.Number) metric;
valueCell.setCellValue(numberMetric.getValue());
String unit = numberMetric.getUnit();
if (!TextUtils.isEmpty(unit)) {
mCache.setCellFormat(valueCell, "#0\"" + unit + "\"");
}
break;
case LIST:
Metric.List listMetric = (Metric.List) metric;
String selectedItem = listMetric.getValue().get(listMetric.getSelectedValueKey());
valueCell.setCellValue(selectedItem);
break;
case TEXT:
RichTextString note = mCache.getCreationHelper().createRichTextString(String.valueOf(metric.getValue()));
valueCell.setCellValue(note);
break;
case STOPWATCH:
List<? extends Long> cycles = ((Metric.Stopwatch) metric).getValue();
long sum = 0;
for (Long duration : cycles) sum += duration;
long average = cycles.isEmpty() ? 0 : sum / cycles.size();
valueCell.setCellValue(TimeUnit.MILLISECONDS.toSeconds(average));
mCache.setCellFormat(valueCell, "#0\"s\"");
break;
case HEADER:
// Headers are skipped because they don't contain any data
break;
default:
throw new IllegalStateException();
}
}
use of com.supercilex.robotscouter.data.model.Metric in project Robot-Scouter by SUPERCILEX.
the class SpreadsheetExporter method buildTeamChart.
@AddTrace(name = "buildTeamChart")
private void buildTeamChart(Row row, TeamHelper teamHelper, Map<Chart, Pair<LineChartData, List<ChartAxis>>> chartData, Map<Metric<Void>, Chart> chartPool) {
if (isUnsupportedDevice())
return;
Sheet sheet = row.getSheet();
int rowNum = row.getRowNum();
int lastDataCellNum = row.getSheet().getRow(0).getLastCellNum() - 2;
Chart chart = null;
Pair<Integer, Metric<Void>> nearestHeader = null;
List<Row> rows = getAdjustedList(row.getSheet());
for (int i = row.getRowNum() - 1; i >= 0; i--) {
Metric metric = getMetricForScouts(mScouts.get(teamHelper), mCache.getMetricKey(rows.get(i)));
if (metric.getType() == HEADER) {
nearestHeader = Pair.create(i, metric);
Chart cachedChart = chartPool.get(metric);
if (cachedChart != null)
chart = cachedChart;
break;
}
}
chartFinder: if (nearestHeader == null) {
for (Chart possibleChart : chartData.keySet()) {
if (possibleChart instanceof XSSFChart) {
XSSFChart xChart = (XSSFChart) possibleChart;
if (xChart.getGraphicFrame().getAnchor().getRow1() == SINGLE_ITEM) {
nearestHeader = Pair.create(0, getMetricForChart(xChart, chartPool));
chart = xChart;
break chartFinder;
}
}
}
nearestHeader = Pair.create(0, new Metric.Header("", null));
}
LineChartData data;
if (chart == null) {
Drawing drawing = sheet.createDrawingPatriarch();
Integer headerIndex = nearestHeader.first + 1;
int startChartIndex = lastDataCellNum + 3;
chart = drawing.createChart(createChartAnchor(drawing, getChartRowIndex(headerIndex, new ArrayList<>(chartData.keySet())), startChartIndex, startChartIndex + 10));
LineChartData lineChartData = chart.getChartDataFactory().createLineChartData();
data = lineChartData;
ChartAxis bottomAxis = chart.getChartAxisFactory().createCategoryAxis(AxisPosition.BOTTOM);
ValueAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT);
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
ChartLegend legend = chart.getOrCreateLegend();
legend.setPosition(LegendPosition.RIGHT);
chartData.put(chart, Pair.create(lineChartData, Arrays.asList(bottomAxis, leftAxis)));
chartPool.put(nearestHeader.second, chart);
} else {
data = chartData.get(chart).first;
}
ChartDataSource<String> categorySource = DataSources.fromStringCellRange(sheet, new CellRangeAddress(0, 0, 1, lastDataCellNum));
data.addSeries(categorySource, DataSources.fromNumericCellRange(sheet, new CellRangeAddress(rowNum, rowNum, 1, lastDataCellNum))).setTitle(row.getCell(0).getStringCellValue());
}
Aggregations