예제 #1
0
  /**
   * Calculates the data sets for the specified {@link Stat}.
   *
   * @param stat stat to calculate the data sets for
   */
  private void calculateDataSets(final Stat stat) {
    // Data points for each data set, inside being mapped from loop to value.
    final Map<LineChartDataSet, Map<Integer, Int>> dataSetPointsMap = new HashMap<>();

    final boolean mergeMinGas = stat.hasMinGas && !separateMinsGasCheckBox.isSelected();

    final String[] eventFields; // Event fields to query eventually
    if (stat.hasMinGas) {
      final boolean includeMins = minsCheckBox.isSelected();
      final boolean includeGas = gasCheckBox.isSelected();
      if (includeMins && includeGas) eventFields = stat.eventFields;
      else if (includeMins) eventFields = new String[] {stat.eventFields[0]};
      else if (includeGas) eventFields = new String[] {stat.eventFields[1]};
      else eventFields = new String[0];
    } else eventFields = stat.eventFields;

    // Calculate data points maps
    for (final Event event : repProc.replay.trackerEvents.events) {
      if (event.id != ITrackerEvents.ID_PLAYER_STATS) continue;

      final DataModel<LineChartDataSet> model = modelByPlayerIds[event.getPlayerId()];
      if (model == null) continue;

      // One extra player stat event is recorded when a user leaves (at the same loop) even if at
      // the same loop there was a
      // scheduled player stat event. So we have to exclude the last player stat event (to avoid the
      // chart getting
      // "screwed"). (This for example contains mineralsCurrent = 0.)
      // Note: if there's a scheduled stat event when the player left, this will be excluded
      // wrongly,
      // but I don't care, it won't make any noticable difference...
      if (event.loop == repProc.usersByPlayerId[event.getPlayerId()].leaveLoop) continue;

      // Data sets per event fields
      for (int i = 0; i < eventFields.length; i++) {
        final String field = eventFields[i];
        final LineChartDataSet dataSet = model.getDataSetList().get(mergeMinGas ? 0 : i);

        Map<Integer, Int> pointsMap = dataSetPointsMap.get(dataSet);
        if (pointsMap == null) dataSetPointsMap.put(dataSet, pointsMap = new HashMap<>());
        final Integer loop = Integer.valueOf(event.loop);
        Int point = pointsMap.get(loop);
        if (point == null) {
          pointsMap.put(loop, point = new Int());
        }
        int value = ((PlayerStatsEvent) event).stats.<Integer>get(field);
        if (field == PlayerStatsEvent.F_FOOD_MADE || field == PlayerStatsEvent.F_FOOD_USED)
          value >>= 12;
        point.value += value;
      }
    }

    // Convert data points maps to arrays
    for (final Chart<LineChartDataSet> chart : chartList) {
      for (final DataModel<LineChartDataSet> model : chart.getDataModelList()) {
        for (final LineChartDataSet dataSet : model.getDataSetList()) {
          final Map<Integer, Int> pointsMap = dataSetPointsMap.get(dataSet);
          if (pointsMap == null) continue;

          // Data points are needed sorted by loop
          final List<Entry<Integer, Int>> dataPointList = new ArrayList<>(pointsMap.entrySet());
          Collections.sort(
              dataPointList,
              new Comparator<Entry<Integer, Int>>() {
                @Override
                public int compare(Entry<Integer, Int> o1, Entry<Integer, Int> o2) {
                  return o1.getKey().compareTo(o2.getKey());
                }
              });

          int i = 0;
          final int[] loops = new int[pointsMap.size()];
          final int[] values = new int[pointsMap.size()];
          for (final Entry<Integer, Int> dataPoint : dataPointList) {
            loops[i] = dataPoint.getKey();
            values[i] = dataPoint.getValue().value;
            i++;
          }

          dataSet.setLoops(loops);
          dataSet.setValues(values);
          dataSet.calculateValueMax();
        }
      }
    }
  }