public static Result restFlowMetricsGraphData(String flowDefId) {
    JsonArray datasets = new JsonArray();
    if (flowDefId == null || flowDefId.isEmpty()) {
      return ok(new Gson().toJson(datasets));
    }

    List<AppResult> results = getRestFlowAppResults(flowDefId);

    if (results.size() == 0) {
      logger.info("No results for Job url");
    }
    Map<IdUrlPair, List<AppResult>> flowExecIdToJobsMap =
        ControllerUtil.limitHistoryResults(ControllerUtil.groupJobs(results, ControllerUtil.GroupBy.FLOW_EXECUTION_ID), results.size(), MAX_HISTORY_LIMIT);

    // Compute the graph data starting from the earliest available execution to latest
    List<IdUrlPair> keyList = new ArrayList<IdUrlPair>(flowExecIdToJobsMap.keySet());
    for (int i = keyList.size() - 1; i >= 0; i--) {
      IdUrlPair flowExecPair = keyList.get(i);
      int flowPerfScore = 0;
      JsonArray jobScores = new JsonArray();
      List<AppResult> mrJobsList = Lists.reverse(flowExecIdToJobsMap.get(flowExecPair));
      Map<IdUrlPair, List<AppResult>> jobDefIdToJobsMap = ControllerUtil.groupJobs(mrJobsList, ControllerUtil.GroupBy.JOB_DEFINITION_ID);

      long totalFlowMemoryUsed = 0;
      long totalFlowMemoryWasted = 0;
      long totalFlowDelay = 0;
      long totalFlowRuntime = 0;
      // Compute the execution records. Note that each entry in the jobDefIdToJobsMap will have at least one AppResult
      for (IdUrlPair jobDefPair : jobDefIdToJobsMap.keySet()) {
        // Compute job perf score
        long totalJobMemoryUsed = 0;
        long totalJobMemoryWasted = 0;
        long totalJobDelay = 0;
        long totalJobRuntime = 0;

        totalJobRuntime = Utils.getTotalRuntime(jobDefIdToJobsMap.get(jobDefPair));
        totalJobDelay = Utils.getTotalWaittime(jobDefIdToJobsMap.get(jobDefPair));

        for (AppResult job : jobDefIdToJobsMap.get(jobDefPair)) {
          totalJobMemoryUsed += job.resourceUsed;
          totalJobMemoryWasted += job.resourceWasted;
        }

        // A job in jobscores list
        JsonObject jobScore = new JsonObject();
        jobScore.addProperty("runtime", totalJobRuntime);
        jobScore.addProperty("waittime", totalJobDelay);
        jobScore.addProperty("resourceused", totalJobMemoryUsed);
        jobScore.addProperty("resourcewasted", totalJobMemoryWasted);
        jobScore.addProperty("jobdefurl", jobDefPair.getUrl());
        jobScore.addProperty("jobexecurl", jobDefIdToJobsMap.get(jobDefPair).get(0).jobExecUrl);

        jobScores.add(jobScore);
        totalFlowMemoryUsed += totalJobMemoryUsed;
        totalFlowMemoryWasted += totalJobMemoryWasted;
      }

      totalFlowDelay = Utils.getTotalWaittime(flowExecIdToJobsMap.get(flowExecPair));
      totalFlowRuntime = Utils.getTotalRuntime(flowExecIdToJobsMap.get(flowExecPair));

      // Execution record
      JsonObject dataset = new JsonObject();
      dataset.addProperty("flowtime", Utils.getFlowTime(mrJobsList.get(mrJobsList.size() - 1)));
      dataset.addProperty("runtime", totalFlowRuntime);
      dataset.addProperty("waittime", totalFlowDelay);
      dataset.addProperty("resourceused", totalFlowMemoryUsed);
      dataset.addProperty("resourcewasted", totalFlowMemoryWasted);
      dataset.add("jobmetrics", jobScores);

      datasets.add(dataset);
    }

    JsonArray sortedDatasets = Utils.sortJsonArray(datasets);

    return ok(new Gson().toJson(sortedDatasets));
  }
Rest data to plot flot history graph using time and resource metrics. While plotting the flow history
graph an ajax call is made to this to fetch the graph data.
[
{
 "flowtime": 1461744881991,
 "runtime": 3190223,
 "waittime": 368011,
 "resourceused": 180488192,
 "resourcewasted": 0,
 "jobmetrics": [
         {
        "runtime": 3190223,
        "waittime": 368011,
        "resourceused": 180488192,
        "resourcewasted": 0,
        "jobdefurl": "sampleURL"
        "jobexecurl": "sampleURL"
         }
       ]
},
{
 "flowtime": 1461818409959,
 "runtime": 897490,
 "waittime": 100703,
 "resourceused": 12863488,
 "resourcewasted": 0,
 "jobmetrics": [
         {
        "runtime": 897490,
        "waittime": 100703,
        "resourceused": 12863488,
        "resourcewasted": 0,
        "jobdefurl": "sampleURL"
        "jobexecurl": "sampleURL"
}
]
}
]
app/controllers/Application.java