/** Calculates the Food Made+Used data sets. */ private void calculateFoodMadeUsedDataSets() { // Food Made+Used is showing 2 player stats at once: Food Made and Food Used // First calculate FOOD_USED data set... calculateDataSets(Stat.FOOD_USED); // ...and clone it because we'll need it in a moment final List<Chart<LineChartDataSet>> clonedChartList = new ArrayList<>(chartList.size()); for (final Chart<LineChartDataSet> chart : chartList) { final Chart<LineChartDataSet> clonedChart = createChart(); for (final DataModel<LineChartDataSet> model : chart.getDataModelList()) { final DataModel<LineChartDataSet> clonedModel = new DataModel<>(model.getTitle(), model.getColor()); for (final LineChartDataSet dataSet : model.getDataSetList()) { // Use brighter color as this will be the 2nd dataset final Color color = ((User) model.getUserobObject()).getPlayerColor().brighterColor; clonedModel.addDataSet( new LineChartDataSet( color, dataSet.getStroke(), dataSet.getLoops(), dataSet.getValues())); } clonedChart.addModel(clonedModel); } clonedChartList.add(clonedChart); } // Cloning done, let's roll on to calculating the FOOD_MADE data set... calculateDataSets(Stat.FOOD_MADE); // And the final step: "merge" the 2 data sets into one, simply add the datasets... for (int chartIdx = 0; chartIdx < chartList.size(); chartIdx++) { final Chart<LineChartDataSet> chart = chartList.get(chartIdx); final Chart<LineChartDataSet> clonedChart = clonedChartList.get(chartIdx); for (int modelIdx = 0; modelIdx < chart.getDataModelList().size(); modelIdx++) { final DataModel<LineChartDataSet> model = chart.getDataModelList().get(modelIdx); final DataModel<LineChartDataSet> clonedModel = clonedChart.getDataModelList().get(modelIdx); model.getDataSetList().addAll(clonedModel.getDataSetList()); } } }
/** Calculates the Spending Quotient data sets. */ private void calculateSQDataSets() { // Spending Quotient is a function of 2 other Stats: SQ = f( RES_CURRENT, RES_COLL_RATE ) // First calculate RES_CURRENT data set... calculateDataSets(Stat.RES_CURRENT); // ...and clone it because we'll need it in a moment final List<Chart<LineChartDataSet>> clonedChartList = new ArrayList<>(chartList.size()); for (final Chart<LineChartDataSet> chart : chartList) { final Chart<LineChartDataSet> clonedChart = createChart(); for (final DataModel<LineChartDataSet> model : chart.getDataModelList()) { final DataModel<LineChartDataSet> clonedModel = new DataModel<>(null, null); for (final LineChartDataSet dataSet : model.getDataSetList()) clonedModel.addDataSet( new LineChartDataSet(null, null, dataSet.getLoops(), dataSet.getValues())); clonedChart.addModel(clonedModel); } clonedChartList.add(clonedChart); } // Cloning done, let's roll on to calculating the RES_COLL_RATE data set... calculateDataSets(Stat.RES_COLL_RATE); // We'll need the last command game event loops indexed by data model (last cmd loop is the same // for all data sets in a // model) final Map<DataModel<LineChartDataSet>, Int> modelLastCmdLoopsMap = new HashMap<>(); for (final Event event : repProc.replay.gameEvents.events) { if (event.id != IGameEvents.ID_CMD) continue; // Player stats go by tracker events which go by player id. First check if there is player for // the user! final int playerId = repProc.usersByUserId[event.userId].playerId; if (playerId <= 0) continue; final DataModel<LineChartDataSet> model = modelByPlayerIds[playerId]; if (model == null) continue; // Update last command loop per model Int lastCmdLoop = modelLastCmdLoopsMap.get(model); if (lastCmdLoop == null) modelLastCmdLoopsMap.put(model, lastCmdLoop = new Int()); lastCmdLoop.value = event.loop; } // And the final step: "merge" the 2 data sets, the result being the SQ for (int chartIdx = 0; chartIdx < chartList.size(); chartIdx++) { final Chart<LineChartDataSet> chart = chartList.get(chartIdx); final Chart<LineChartDataSet> clonedChart = clonedChartList.get(chartIdx); for (int modelIdx = 0; modelIdx < chart.getDataModelList().size(); modelIdx++) { final DataModel<LineChartDataSet> model = chart.getDataModelList().get(modelIdx); final DataModel<LineChartDataSet> clonedModel = clonedChart.getDataModelList().get(modelIdx); final int lastCmdLoop = modelLastCmdLoopsMap.get(model) == null ? 0 : modelLastCmdLoopsMap.get(model).value; for (int dataSetIdx = 0; dataSetIdx < model.getDataSetList().size(); dataSetIdx++) { final LineChartDataSet dataSet = model.getDataSetList().get(dataSetIdx); final LineChartDataSet clonedDataSet = clonedModel.getDataSetList().get(dataSetIdx); // Only include values in total before the last command loop! And of course only count // samples up to that. final int[] loops = dataSet.getLoops(); final int[] values = dataSet.getValues(); final int[] clonedValues = clonedDataSet.getValues(); long totalValues = 0, totalClonedValues = 0; int totalCount = 0; for (int valueIdx = 0; valueIdx < values.length; valueIdx++) { if (loops[valueIdx] <= lastCmdLoop) { totalClonedValues += clonedValues[valueIdx]; totalValues += values[valueIdx]; totalCount++; } values[valueIdx] = RepProcessor.calculateSQImpl(clonedValues[valueIdx], values[valueIdx]); } // Calculate average SQ for the data set, put in data set title! final int avgSQ = totalCount == 0 ? 0 : RepProcessor.calculateSQImpl( (int) (totalClonedValues / totalCount), (int) (totalValues / totalCount)); dataSet.setTitle("SQ: " + avgSQ); dataSet.calculateValueMax(); } } } }