Search in sources :

Example 6 with DataPair

use of net.sourceforge.processdash.util.DataPair in project processdash by dtuma.

the class WorkflowPlanSummary method printDefectsByPhaseCharts.

private void printDefectsByPhaseCharts(Map<String, DataPair>[] defectsByPhase) throws IOException {
    if (isExportingToExcel())
        return;
    // shuffle the items in the "injected" list so "Before Development" is
    // at the end. This makes the phase colors consistent across pie charts.
    Map<String, DataPair> injected = new LinkedHashMap(defectsByPhase[0]);
    DataPair before = injected.remove(Defect.BEFORE_DEVELOPMENT);
    DataPair total = injected.remove(TOTAL_KEY);
    injected.put(Defect.BEFORE_DEVELOPMENT, before);
    injected.put(TOTAL_KEY, total);
    Map removed = defectsByPhase[1];
    out.print("<p>\n");
    writePhaseChart(false, "Defects_Injected", "Defects", 1, injected);
    writePhaseChart(false, "Defects_Removed", "Defects", 1, removed);
    out.print("</p>\n");
}
Also used : LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) DataPair(net.sourceforge.processdash.util.DataPair)

Example 7 with DataPair

use of net.sourceforge.processdash.util.DataPair in project processdash by dtuma.

the class WorkflowPlanSummary method writeOverallMetrics.

private void writeOverallMetrics(Map<String, DataPair> sizes, Map<String, DataPair> timeInPhase, Map<String, String> phaseTypes) {
    DataPair totalTime = timeInPhase.get(TOTAL_KEY);
    out.print("<h2 style='margin-top:0px'>");
    out.print(res("Overall_Metrics"));
    out.print("</h2>\n<table>\n");
    printTableHeader(null, false);
    // print numbers for productivity
    for (Entry<String, DataPair> e : sizes.entrySet()) {
        String metric = e.getKey();
        String label = resources.format("Productivity_Units_FMT", metric);
        DataPair productivity = new DataPair(e.getValue()).multiply(60).divide(totalTime);
        printTableRow(label, productivity, Format.Number);
    }
    // print total time
    printTableRow(res("Total_Time"), totalTime, Format.Time);
    // print time estimating error
    DataPair timeEst = new DataPair();
    timeEst.actual = (totalTime.actual - totalTime.plan) / totalTime.plan;
    printTableRow(res("Time_Estimating_Error"), timeEst, Format.Percent, true, 0);
    // print CPI
    DataPair cpi = new DataPair();
    cpi.actual = totalTime.plan / totalTime.actual;
    printTableRow(res("CPI"), cpi, Format.Number, true, 0);
    // calculate cost of quality
    DataPair appraisalCOQ = new DataPair();
    DataPair failureCOQ = new DataPair();
    for (Entry<String, DataPair> e : timeInPhase.entrySet()) {
        String phaseName = e.getKey();
        String phaseType = phaseTypes.get(phaseName);
        if ("Appraisal".equals(phaseType))
            appraisalCOQ.add(e.getValue());
        else if ("Failure".equals(phaseType))
            failureCOQ.add(e.getValue());
    }
    appraisalCOQ.divide(totalTime);
    failureCOQ.divide(totalTime);
    DataPair totalCOQ = new DataPair(appraisalCOQ).add(failureCOQ);
    DataPair afr = new DataPair(appraisalCOQ).divide(failureCOQ);
    printTableRow(res("%_Appraisal_COQ"), appraisalCOQ, Format.Percent);
    printTableRow(res("%_Failure_COQ"), failureCOQ, Format.Percent);
    printTableRow(res("%_Total_COQ"), totalCOQ, Format.Percent);
    printTableRow(res("Appraisal_to_Failure_Ratio"), afr, Format.Number);
    out.print("</table>\n");
}
Also used : DataPair(net.sourceforge.processdash.util.DataPair)

Example 8 with DataPair

use of net.sourceforge.processdash.util.DataPair in project processdash by dtuma.

the class WorkflowPlanSummary method writeContents.

@Override
protected void writeContents() throws IOException {
    ChartData chartData = AnalysisPage.getChartData((HttpServletRequest) env.get(HttpServletRequest.class), true);
    WorkflowHistDataHelper hist = chartData.histData;
    if (hist.getWorkflowName() == null)
        throw new TinyCGIException(404, "The requested workflow was not found.");
    String title = resources.getString("Workflow.Analysis.Title") + " - " + hist.getWorkflowName();
    out.print("<html><head><title>");
    out.print(esc(title));
    out.print("</title>\n");
    out.print(cssLinkHTML());
    if (hist.isFiltering())
        out.write("<link rel='stylesheet' type='text/css' href='filter-style.css'>\n");
    out.print(HTMLUtils.scriptLinkHtml("/lib/overlib.js"));
    out.print("<style>\n");
    out.print(" .rowLabel { padding-right: 10px }\n");
    out.print(" th.plan, th.act { width: 70px; }\n");
    out.print(" td.plan, td.act { padding-right: 4px; border: 1px solid gray; text-align: right }\n");
    out.print(" #filter.collapsed .filterItem { display: none }\n");
    out.print(" #filter.expanded .filterLink { display: none }\n");
    out.print(" #defects th.plan, #defects td.plan { display: none }\n");
    out.print("</style>\n");
    out.print("<script>\n");
    out.print("    function showFilter() {\n");
    out.print("      document.getElementById('filter').className = 'expanded';\n");
    out.print("    }\n");
    out.print("</script>\n");
    out.print("</head>\n");
    out.print("<body><h1>");
    out.print(esc(title));
    out.print("</h1>\n");
    out.write("<table><tr>\n<td style='vertical-align:baseline'><h2>");
    out.print(esc(res("Summary.Title")));
    out.write("&nbsp;</td>\n");
    if (!isExporting())
        writePageSubtitle(hist);
    out.write("</tr></table>\n");
    Map<String, DataPair> sizes = hist.getAddedAndModifiedSizes();
    Map<String, DataPair> timeInPhase = hist.getTotalTimeInPhase();
    Map<String, DataPair>[] defectsByPhase = hist.getDefectsByPhase();
    for (Iterator<String> i = sizes.keySet().iterator(); i.hasNext(); ) {
        if (AnalysisPage.isTimeUnits(i.next()))
            i.remove();
    }
    writeOverallMetrics(sizes, timeInPhase, hist.getPhaseTypes());
    printTable("Size", "Added_&_Modified", sizes, Format.Number, false);
    printTable("Time_in_Phase", null, timeInPhase, Format.Time, true);
    printTimeInPhaseCharts(timeInPhase);
    if (defectsByPhase[1].get(TOTAL_KEY).actual > 0) {
        out.print("<div id=\"defects\">\n");
        setBeforeAndAfterRowLabels(timeInPhase);
        printTable("Defects_Injected", null, defectsByPhase[0], Format.Number, true);
        printTable("Defects_Removed", null, defectsByPhase[1], Format.Number, true);
        printDefectsByPhaseCharts(defectsByPhase);
        writeAdvancedDefectMetrics(hist, defectsByPhase, timeInPhase);
        out.print("</div>\n");
    }
    if (!isExportingToExcel()) {
        out.print("<hr>\n");
        out.print("<a href=\"excel.iqy?fullPage\">");
        out.print(resources.getHTML("Export_to_Excel"));
        out.print("</a>");
    }
    out.print("</body></html>\n");
    if (parameters.containsKey("debug"))
        hist.debugPrintEnactments();
}
Also used : WorkflowHistDataHelper(net.sourceforge.processdash.tool.db.WorkflowHistDataHelper) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) TinyCGIException(net.sourceforge.processdash.net.http.TinyCGIException) DataPair(net.sourceforge.processdash.util.DataPair)

Example 9 with DataPair

use of net.sourceforge.processdash.util.DataPair in project processdash by dtuma.

the class WorkflowPlanSummary method applyLegacyMultiplier.

/**
     * Teams that have been using the dashboard for a while will have legacy
     * (MCF-phase) defects in their defect log. Once they begin collecting
     * defect data against workflow phases, they will receive useful numbers for
     * inj/rem % by phase, as well as yield. But unfortunately, the injection
     * and removal rates will be too low, since we are dividing by time in phase
     * (which includes time from legacy project cycles where the defects were
     * collected the old way).
     * 
     * To avoid this problem, we count the number of legacy defects and apply a
     * scaling factor to let defect counts and time in phase relate in an
     * apples-to-apples way. This is an engineering compromise, based on the
     * observation that useful, meaningful defects rates are better than no
     * rates at all.
     * 
     * In the future, when teams collect all data against workflow phases, this
     * method will be a no-op.
     */
private void applyLegacyMultiplier(Map<String, DataPair>[] defectsByPhase, Map<String, DataPair>... dataToFix) {
    DataPair total = defectsByPhase[1].get(TOTAL_KEY);
    DataPair unrecognized = defectsByPhase[2].get(TOTAL_KEY);
    if (total.actual > 0 && unrecognized.actual > 0) {
        double factor = 1 + (unrecognized.actual / total.actual);
        for (Map<String, DataPair> oneDataSet : dataToFix) {
            for (DataPair pair : oneDataSet.values()) pair.actual *= factor;
        }
    }
}
Also used : DataPair(net.sourceforge.processdash.util.DataPair)

Example 10 with DataPair

use of net.sourceforge.processdash.util.DataPair in project processdash by dtuma.

the class WorkflowPlanSummary method writeAdvancedDefectMetrics.

private void writeAdvancedDefectMetrics(WorkflowHistDataHelper hist, Map<String, DataPair>[] defectsByPhase, Map<String, DataPair> timeInPhase) {
    // get the yields for the process
    Map<String, DataPair>[] yields = hist.getYields();
    Map<String, DataPair> processYields = yields[0];
    Map<String, DataPair> phaseYields = yields[1];
    // change the display name for the "total" row
    DataPair totalProcessYield = processYields.remove(TOTAL_KEY);
    processYields.put(res("Workflow.Analysis.Workflow_Completion"), totalProcessYield);
    // to clean up the report, replace 0/0 yields with #DIV/0!
    replaceNaNs(Double.POSITIVE_INFINITY, processYields, phaseYields);
    printTable("Workflow.Analysis.Phase_Yields", null, phaseYields, Format.Percent, false);
    printTable("Workflow.Analysis.Process_Yields", "Workflow.Analysis.%_Removed_Before", processYields, Format.Percent, false);
    Map<String, DataPair> injRates = divide(defectsByPhase[0], timeInPhase);
    Map<String, DataPair> remRates = divide(defectsByPhase[1], timeInPhase);
    // convert minutes to hours
    multiply(60, injRates, remRates);
    // clean up 0/0 rates
    replaceNaNs(0.0, injRates, remRates);
    applyLegacyMultiplier(defectsByPhase, injRates, remRates);
    printTable("Workflow.Analysis.Defect_Injection_Rates", "Defects_Injected_per_Hour", injRates, Format.Number, false);
    printTable("Workflow.Analysis.Defect_Removal_Rates", "Defects_Removed_per_Hour", remRates, Format.Number, false);
}
Also used : LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) DataPair(net.sourceforge.processdash.util.DataPair)

Aggregations

DataPair (net.sourceforge.processdash.util.DataPair)17 LinkedHashMap (java.util.LinkedHashMap)7 Map (java.util.Map)6 ResultSet (net.sourceforge.processdash.data.util.ResultSet)3 ArrayList (java.util.ArrayList)2 TreeMap (java.util.TreeMap)2 HashMap (java.util.HashMap)1 Entry (java.util.Map.Entry)1 DoubleData (net.sourceforge.processdash.data.DoubleData)1 DataRepository (net.sourceforge.processdash.data.repository.DataRepository)1 TinyCGIException (net.sourceforge.processdash.net.http.TinyCGIException)1 WorkflowHistDataHelper (net.sourceforge.processdash.tool.db.WorkflowHistDataHelper)1 Enactment (net.sourceforge.processdash.tool.db.WorkflowHistDataHelper.Enactment)1