Example usage for org.jfree.chart.renderer.category BarRenderer setMinimumBarLength

List of usage examples for org.jfree.chart.renderer.category BarRenderer setMinimumBarLength

Introduction

In this page you can find the example usage for org.jfree.chart.renderer.category BarRenderer setMinimumBarLength.

Prototype

public void setMinimumBarLength(double min) 

Source Link

Document

Sets the minimum bar length and sends a RendererChangeEvent to all registered listeners.

Usage

From source file:edu.wustl.cab2b.client.ui.visualization.charts.BarChart.java

protected JFreeChart createChart(Dataset dataset) {
    CategoryDataset categoryDataSet = (CategoryDataset) dataset;

    JFreeChart jFreeChart = ChartFactory.createBarChart("Bar Chart", null, "Value", categoryDataSet,
            PlotOrientation.VERTICAL, true, true, false);
    jFreeChart.setBackgroundPaint(Color.white);

    CategoryPlot categoryPlot = (CategoryPlot) jFreeChart.getPlot();
    categoryPlot.setBackgroundPaint(Color.white);
    categoryPlot.setDomainGridlinePaint(Color.white);
    categoryPlot.setRangeGridlinePaint(Color.white);

    NumberAxis numberAxis = (NumberAxis) categoryPlot.getRangeAxis();
    numberAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
    BarRenderer barRenderer = (BarRenderer) categoryPlot.getRenderer();
    barRenderer.setDrawBarOutline(false);
    barRenderer.setMinimumBarLength(0.7D);
    barRenderer.setMaximumBarWidth(0.7D);
    barRenderer.setItemMargin(0.1D);//  w  w  w.  ja  v a  2s  .  com

    CategoryAxis categoryaxis = categoryPlot.getDomainAxis();
    categoryaxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);

    return jFreeChart;
}

From source file:org.sakaiproject.gradebookng.tool.panels.AssignmentStatisticsPanel.java

@Override
public void onInitialize() {
    super.onInitialize();

    final Long assignmentId = ((Model<Long>) getDefaultModel()).getObject();

    final Assignment assignment = this.businessService.getAssignment(assignmentId.longValue());

    AssignmentStatisticsPanel.this.window.setTitle(
            (new StringResourceModel("label.statistics.title", null, new Object[] { assignment.getName() })
                    .getString()));//w w  w.j  a v a  2  s.co m

    final List<GbStudentGradeInfo> gradeInfo = this.businessService.buildGradeMatrix(Arrays.asList(assignment));

    final List<Double> allGrades = new ArrayList<>();

    for (int i = 0; i < gradeInfo.size(); i++) {
        final GbStudentGradeInfo studentGradeInfo = gradeInfo.get(i);

        final Map<Long, GbGradeInfo> studentGrades = studentGradeInfo.getGrades();
        final GbGradeInfo grade = studentGrades.get(assignmentId);

        if (grade == null || grade.getGrade() == null) {
            // this is not the grade you are looking for
        } else {
            allGrades.add(Double.valueOf(grade.getGrade()));
        }
    }

    Collections.sort(allGrades);

    final DefaultCategoryDataset data = new DefaultCategoryDataset();

    final Map<String, Integer> counts = new TreeMap<>();
    Integer extraCredits = 0;

    // Start off with a 0-50% range
    counts.put(String.format("%d-%d", 0, 50), 0);

    final int range = 10;
    for (int start = 50; start < 100; start = start + range) {
        final String key = String.format("%d-%d", start, start + range);
        counts.put(key, 0);
    }

    for (final Double grade : allGrades) {
        if (isExtraCredit(grade, assignment)) {
            extraCredits = extraCredits + 1;
            continue;
        }

        final double percentage;
        if (GradingType.PERCENTAGE.equals(this.gradingType)) {
            percentage = grade;
        } else {
            percentage = grade / assignment.getPoints() * 100;
        }

        final int total = Double.valueOf(Math.ceil(percentage) / range).intValue();

        int start = total * range;

        if (start == 100) {
            start = start - range;
        }

        String key = String.format("%d-%d", start, start + range);

        if (start < 50) {
            key = String.format("%d-%d", 0, 50);
        }

        counts.put(key, counts.get(key) + 1);
    }

    for (final String label : counts.keySet()) {
        data.addValue(counts.get(label), "count", label);
    }
    if (extraCredits > 0) {
        data.addValue(extraCredits, "count", getString("label.statistics.chart.extracredit"));
    }

    final JFreeChart chart = ChartFactory.createBarChart(null, // the chart title
            getString("label.statistics.chart.xaxis"), // the label for the category axis
            getString("label.statistics.chart.yaxis"), // the label for the value axis
            data, // the dataset for the chart
            PlotOrientation.VERTICAL, // the plot orientation
            false, // show legend
            true, // show tooltips
            false); // show urls

    chart.setBorderVisible(false);

    chart.setAntiAlias(false);

    final CategoryPlot categoryPlot = chart.getCategoryPlot();
    final BarRenderer br = (BarRenderer) categoryPlot.getRenderer();

    br.setItemMargin(0);
    br.setMinimumBarLength(0.05);
    br.setMaximumBarWidth(0.1);
    br.setSeriesPaint(0, new Color(51, 122, 183));
    br.setBarPainter(new StandardBarPainter());
    br.setShadowPaint(new Color(220, 220, 220));
    BarRenderer.setDefaultShadowsVisible(true);

    br.setBaseToolTipGenerator(new StandardCategoryToolTipGenerator(getString("label.statistics.chart.tooltip"),
            NumberFormat.getInstance()));

    categoryPlot.setRenderer(br);

    // show only integers in the count axis
    categoryPlot.getRangeAxis().setStandardTickUnits(new NumberTickUnitSource(true));
    categoryPlot.setBackgroundPaint(Color.white);

    add(new JFreeChartImageWithToolTip("chart", Model.of(chart), "tooltip", 540, 300));

    add(new Label("graded", String.valueOf(allGrades.size())));

    if (allGrades.size() > 0) {
        add(new Label("average", constructAverageLabel(allGrades, assignment)));
        add(new Label("median", constructMedianLabel(allGrades, assignment)));
        add(new Label("lowest", constructLowestLabel(allGrades, assignment)));
        add(new Label("highest", constructHighestLabel(allGrades, assignment)));
        add(new Label("deviation", constructStandardDeviationLabel(allGrades)));
    } else {
        add(new Label("average", "-"));
        add(new Label("median", "-"));
        add(new Label("lowest", "-"));
        add(new Label("highest", "-"));
        add(new Label("deviation", "-"));
    }

    add(new GbAjaxLink("done") {
        private static final long serialVersionUID = 1L;

        @Override
        public void onClick(final AjaxRequestTarget target) {
            AssignmentStatisticsPanel.this.window.close(target);
        }
    });
}

From source file:org.sakaiproject.gradebookng.tool.panels.SettingsGradingSchemaPanel.java

/**
 * Build the data for the chart/* w w  w.j  a  v  a 2 s.  c  om*/
 * 
 * @return
 */
private JFreeChart getChartData() {

    // just need the list
    final List<CourseGrade> courseGrades = this.courseGradeMap.values().stream().collect(Collectors.toList());

    // get current grading schema (from model so that it reflects current state)
    final List<GbGradingSchemaEntry> gradingSchemaEntries = this.model.getObject().getGradingSchemaEntries();

    final DefaultCategoryDataset data = new DefaultCategoryDataset();
    final Map<String, Integer> counts = new LinkedHashMap<>(); // must retain order so graph can be printed correctly

    // add all schema entries (these will be sorted according to {@link LetterGradeComparator})
    gradingSchemaEntries.forEach(e -> {
        counts.put(e.getGrade(), 0);
    });

    // now add the count of each course grade for those schema entries
    this.total = 0;
    for (final CourseGrade g : courseGrades) {

        // course grade may not be released so we have to skip it
        if (StringUtils.isBlank(g.getMappedGrade())) {
            continue;
        }

        counts.put(g.getMappedGrade(), counts.get(g.getMappedGrade()) + 1);
        this.total++;
    }

    // build the data
    final ListIterator<String> iter = new ArrayList<>(counts.keySet()).listIterator(0);
    while (iter.hasNext()) {
        final String c = iter.next();
        data.addValue(counts.get(c), "count", c);
    }

    final JFreeChart chart = ChartFactory.createBarChart(null, // the chart title
            getString("settingspage.gradingschema.chart.xaxis"), // the label for the category (x) axis
            getString("label.statistics.chart.yaxis"), // the label for the value (y) axis
            data, // the dataset for the chart
            PlotOrientation.HORIZONTAL, // the plot orientation
            false, // show legend
            true, // show tooltips
            false); // show urls

    chart.getCategoryPlot().setRangeAxisLocation(AxisLocation.BOTTOM_OR_RIGHT);
    chart.setBorderVisible(false);
    chart.setAntiAlias(false);

    final CategoryPlot plot = chart.getCategoryPlot();
    final BarRenderer br = (BarRenderer) plot.getRenderer();

    br.setItemMargin(0);
    br.setMinimumBarLength(0.05);
    br.setMaximumBarWidth(0.1);
    br.setSeriesPaint(0, new Color(51, 122, 183));
    br.setBarPainter(new StandardBarPainter());
    br.setShadowPaint(new Color(220, 220, 220));
    BarRenderer.setDefaultShadowsVisible(true);

    br.setBaseToolTipGenerator(new StandardCategoryToolTipGenerator(getString("label.statistics.chart.tooltip"),
            NumberFormat.getInstance()));

    plot.setRenderer(br);

    // show only integers in the count axis
    plot.getRangeAxis().setStandardTickUnits(new NumberTickUnitSource(true));

    // make x-axis wide enough so we don't get ... suffix
    plot.getDomainAxis().setMaximumCategoryLabelWidthRatio(2.0f);

    plot.setBackgroundPaint(Color.white);

    chart.setTitle(getString("settingspage.gradingschema.chart.heading"));

    return chart;
}

From source file:com.manydesigns.portofino.chart.ChartStackedBarGenerator.java

public JFreeChart generate(ChartDefinition chartDefinition, Persistence persistence, Locale locale) {
    DefaultCategoryDataset dataset = new DefaultCategoryDataset();
    java.util.List<Object[]> result;
    String query = chartDefinition.getQuery();
    logger.info(query);//from  ww w  .  ja  v  a 2  s. co  m
    Session session = persistence.getSession(chartDefinition.getDatabase());
    result = QueryUtils.runSql(session, query);
    for (Object[] current : result) {
        ComparableWrapper x = new ComparableWrapper((Comparable) current[0]);
        ComparableWrapper y = new ComparableWrapper((Comparable) current[1]);
        if (current.length > 3) {
            x.setLabel(current[3].toString());
        }
        if (current.length > 4) {
            y.setLabel(current[4].toString());
        }
        dataset.setValue((Number) current[2], x, y);
    }

    PlotOrientation plotOrientation = PlotOrientation.HORIZONTAL;
    if (chartDefinition.getActualOrientation() == ChartDefinition.Orientation.VERTICAL) {
        plotOrientation = PlotOrientation.VERTICAL;
    }

    JFreeChart chart = createChart(chartDefinition, dataset, plotOrientation);

    chart.setAntiAlias(antiAlias);

    // impostiamo il bordo invisibile
    // eventualmente e' il css a fornirne uno
    chart.setBorderVisible(borderVisible);

    // impostiamo il titolo
    TextTitle title = chart.getTitle();
    title.setFont(titleFont);
    title.setMargin(10.0, 0.0, 0.0, 0.0);

    // ottieni il Plot
    CategoryPlot plot = (CategoryPlot) chart.getPlot();

    CategoryItemRenderer renderer = plot.getRenderer();
    String urlExpression = chartDefinition.getUrlExpression();
    if (!StringUtils.isBlank(urlExpression)) {
        CategoryURLGenerator urlGenerator = new ChartBarUrlGenerator(chartDefinition.getUrlExpression());
        renderer.setBaseItemURLGenerator(urlGenerator);
    } else {
        renderer.setBaseItemURLGenerator(null);
    }
    renderer.setBaseOutlinePaint(Color.BLACK);

    // ///////////////
    if (renderer instanceof BarRenderer) {
        BarRenderer barRenderer = (BarRenderer) renderer;

        barRenderer.setDrawBarOutline(true);
        barRenderer.setShadowVisible(false);
        barRenderer.setBarPainter(new StandardBarPainter());

        // hongliangpan add
        // ?
        barRenderer.setSeriesItemLabelGenerator(0, new StandardCategoryItemLabelGenerator());
        // bar???
        barRenderer.setMinimumBarLength(0.02);
        // 
        barRenderer.setMaximumBarWidth(0.06);
    }
    if (renderer instanceof StackedBarRenderer3D || renderer instanceof StackedBarRenderer) {
        BarRenderer barRenderer = (BarRenderer) renderer;
        barRenderer.setDrawBarOutline(true);
        barRenderer.setShadowVisible(false);
        barRenderer.setBarPainter(new StandardBarPainter());

        // hongliangpan add
        // ? setSeriesItemLabelGenerator
        barRenderer.setItemLabelGenerator(new StandardCategoryItemLabelGenerator());
        // bar???
        barRenderer.setMinimumBarLength(0.02);
        // 
        barRenderer.setMaximumBarWidth(0.06);
        // ?????
        ItemLabelPosition itemLabelPositionFallback = new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12,
                TextAnchor.BASELINE_LEFT, TextAnchor.HALF_ASCENT_LEFT, -1.57D);
        // ??labelposition
        barRenderer.setPositiveItemLabelPositionFallback(itemLabelPositionFallback);
        barRenderer.setNegativeItemLabelPositionFallback(itemLabelPositionFallback);

        barRenderer.setItemLabelsVisible(true);
        barRenderer.setItemMargin(10);
    }

    // ///////////////

    // il plot ha sfondo e bordo trasparente
    // (quindi si vede il colore del chart)
    plot.setBackgroundPaint(transparentColor);
    plot.setOutlinePaint(transparentColor);

    // Modifico il toolTip
    // plot.setToolTipGenerator(new StandardPieToolTipGenerator("{0} = {1} ({2})"));

    // imposta il messaggio se non ci sono dati
    plot.setNoDataMessage(ElementsThreadLocals.getText("no.data.available"));
    plot.setRangeGridlinesVisible(true);
    plot.setRangeGridlinePaint(Color.GRAY);
    plot.setAxisOffset(new RectangleInsets(0, 0, 0, 0));

    // Category axis
    CategoryAxis categoryAxis = plot.getDomainAxis();
    categoryAxis.setAxisLinePaint(Color.BLACK);
    categoryAxis.setLabelFont(axisFont);
    categoryAxis.setAxisLineVisible(true);

    // impostiamo la rotazione dell'etichetta
    if (plot.getOrientation() == PlotOrientation.VERTICAL) {
        CategoryLabelPosition pos = new CategoryLabelPosition(RectangleAnchor.TOP_LEFT,
                TextBlockAnchor.TOP_RIGHT, TextAnchor.TOP_RIGHT, -Math.PI / 4.0,
                CategoryLabelWidthType.CATEGORY, 100);
        CategoryLabelPositions positions = new CategoryLabelPositions(pos, pos, pos, pos);
        categoryAxis.setCategoryLabelPositions(positions);
        categoryAxis.setMaximumCategoryLabelWidthRatio(6.0f);
        height = 333;
    } else {
        categoryAxis.setMaximumCategoryLabelWidthRatio(0.4f);

        // recuperiamo 8 pixel a sinistra
        plot.setInsets(new RectangleInsets(4.0, 0.0, 4.0, 8.0));

        height = 74;

        // contiamo gli elementi nel dataset
        height += 23 * dataset.getColumnCount();

        height += 57;
    }

    Axis rangeAxis = plot.getRangeAxis();
    rangeAxis.setAxisLinePaint(Color.BLACK);
    rangeAxis.setLabelFont(axisFont);

    DrawingSupplier supplier = new DesaturatedDrawingSupplier(plot.getDrawingSupplier());
    plot.setDrawingSupplier(supplier);

    // impostiamo il titolo della legenda
    String legendString = chartDefinition.getLegend();
    Title subtitle = new TextTitle(legendString, legendFont, Color.BLACK, RectangleEdge.BOTTOM,
            HorizontalAlignment.CENTER, VerticalAlignment.CENTER, new RectangleInsets(0, 0, 0, 0));
    subtitle.setMargin(0, 0, 5, 0);
    chart.addSubtitle(subtitle);

    // impostiamo la legenda
    LegendTitle legend = chart.getLegend();
    legend.setBorder(0, 0, 0, 0);
    legend.setItemFont(legendItemFont);
    int legendMargin = 10;
    legend.setMargin(0.0, legendMargin, legendMargin, legendMargin);
    legend.setBackgroundPaint(transparentColor);

    // impostiamo un gradiente orizzontale
    Paint chartBgPaint = new GradientPaint(0, 0, new Color(255, 253, 240), 0, height, Color.WHITE);
    chart.setBackgroundPaint(chartBgPaint);
    return chart;
}

From source file:com.manydesigns.portofino.chart.ChartBarGenerator.java

public JFreeChart generate(ChartDefinition chartDefinition, Persistence persistence, Locale locale) {
    DefaultCategoryDataset dataset = new DefaultCategoryDataset();
    java.util.List<Object[]> result;
    String query = chartDefinition.getQuery();
    logger.info(query);//from   w w w. j a  v  a  2  s. co  m
    Session session = persistence.getSession(chartDefinition.getDatabase());
    result = QueryUtils.runSql(session, query);
    for (Object[] current : result) {
        ComparableWrapper x = new ComparableWrapper((Comparable) current[0]);
        ComparableWrapper y = new ComparableWrapper((Comparable) current[1]);
        if (current.length > 3) {
            x.setLabel(current[3].toString());
        }
        if (current.length > 4) {
            y.setLabel(current[4].toString());
        }
        dataset.setValue((Number) current[2], x, y);
    }

    PlotOrientation plotOrientation = PlotOrientation.HORIZONTAL;
    if (chartDefinition.getActualOrientation() == ChartDefinition.Orientation.VERTICAL) {
        plotOrientation = PlotOrientation.VERTICAL;
    }

    JFreeChart chart = createChart(chartDefinition, dataset, plotOrientation);

    chart.setAntiAlias(antiAlias);

    // impostiamo il bordo invisibile
    // eventualmente e' il css a fornirne uno
    chart.setBorderVisible(borderVisible);

    // impostiamo il titolo
    TextTitle title = chart.getTitle();
    title.setFont(titleFont);
    title.setMargin(10.0, 0.0, 0.0, 0.0);

    // ottieni il Plot
    CategoryPlot plot = (CategoryPlot) chart.getPlot();

    CategoryItemRenderer renderer = plot.getRenderer();
    String urlExpression = chartDefinition.getUrlExpression();
    if (!StringUtils.isBlank(urlExpression)) {
        CategoryURLGenerator urlGenerator = new ChartBarUrlGenerator(chartDefinition.getUrlExpression());
        renderer.setBaseItemURLGenerator(urlGenerator);
    } else {
        renderer.setBaseItemURLGenerator(null);
    }
    renderer.setBaseOutlinePaint(Color.BLACK);

    // ///////////////
    if (renderer instanceof BarRenderer || renderer instanceof BarRenderer3D) {
        BarRenderer barRenderer = (BarRenderer) renderer;

        barRenderer.setDrawBarOutline(true);
        barRenderer.setShadowVisible(false);
        barRenderer.setBarPainter(new StandardBarPainter());

        // hongliangpan add
        barRenderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
        barRenderer.setBaseItemLabelsVisible(true);
        // ? setSeriesItemLabelGenerator
        barRenderer.setItemLabelGenerator(new StandardCategoryItemLabelGenerator());
        // bar???
        barRenderer.setMinimumBarLength(0.02);
        // 
        barRenderer.setMaximumBarWidth(0.05);
        // ?????
        // ??90,??/3.14
        ItemLabelPosition itemLabelPositionFallback = new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12,
                TextAnchor.BASELINE_LEFT, TextAnchor.HALF_ASCENT_LEFT, -1.57D);
        // ??labelposition
        // barRenderer.setPositiveItemLabelPositionFallback(itemLabelPositionFallback);
        // barRenderer.setNegativeItemLabelPositionFallback(itemLabelPositionFallback);

        barRenderer.setItemLabelsVisible(true);

        // ?
        barRenderer.setBaseOutlinePaint(Color.BLACK);
        // ???
        barRenderer.setDrawBarOutline(true);

        // ???
        barRenderer.setItemMargin(0.0);

        // ?
        barRenderer.setIncludeBaseInRange(true);
        barRenderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
        barRenderer.setBaseItemLabelsVisible(true);
        // ?
        plot.setForegroundAlpha(1.0f);
    }

    // ///////////////

    // il plot ha sfondo e bordo trasparente
    // (quindi si vede il colore del chart)
    plot.setBackgroundPaint(transparentColor);
    plot.setOutlinePaint(transparentColor);

    // Modifico il toolTip
    // plot.setToolTipGenerator(new StandardPieToolTipGenerator("{0} = {1} ({2})"));

    // imposta il messaggio se non ci sono dati
    plot.setNoDataMessage(ElementsThreadLocals.getText("no.data.available"));
    plot.setRangeGridlinesVisible(true);
    plot.setRangeGridlinePaint(Color.GRAY);
    plot.setAxisOffset(new RectangleInsets(0, 0, 0, 0));

    // Category axis
    CategoryAxis categoryAxis = plot.getDomainAxis();
    categoryAxis.setAxisLinePaint(Color.BLACK);
    categoryAxis.setLabelFont(axisFont);
    categoryAxis.setAxisLineVisible(true);

    // impostiamo la rotazione dell'etichetta
    if (plot.getOrientation() == PlotOrientation.VERTICAL) {
        CategoryLabelPosition pos = new CategoryLabelPosition(RectangleAnchor.TOP_LEFT,
                TextBlockAnchor.TOP_RIGHT, TextAnchor.TOP_RIGHT, -Math.PI / 4.0,
                CategoryLabelWidthType.CATEGORY, 100);
        CategoryLabelPositions positions = new CategoryLabelPositions(pos, pos, pos, pos);
        categoryAxis.setCategoryLabelPositions(positions);
        categoryAxis.setMaximumCategoryLabelWidthRatio(6.0f);
        height = 333;
    } else {
        categoryAxis.setMaximumCategoryLabelWidthRatio(0.4f);

        // recuperiamo 8 pixel a sinistra
        plot.setInsets(new RectangleInsets(4.0, 0.0, 4.0, 8.0));

        height = 74;

        // contiamo gli elementi nel dataset
        height += 23 * dataset.getColumnCount();

        height += 57;
    }

    Axis rangeAxis = plot.getRangeAxis();
    rangeAxis.setAxisLinePaint(Color.BLACK);
    rangeAxis.setLabelFont(axisFont);

    DrawingSupplier supplier = new DesaturatedDrawingSupplier(plot.getDrawingSupplier());
    plot.setDrawingSupplier(supplier);

    // impostiamo il titolo della legenda
    String legendString = chartDefinition.getLegend();
    Title subtitle = new TextTitle(legendString, legendFont, Color.BLACK, RectangleEdge.BOTTOM,
            HorizontalAlignment.CENTER, VerticalAlignment.CENTER, new RectangleInsets(0, 0, 0, 0));
    subtitle.setMargin(0, 0, 5, 0);
    chart.addSubtitle(subtitle);

    // impostiamo la legenda
    LegendTitle legend = chart.getLegend();
    legend.setBorder(0, 0, 0, 0);
    legend.setItemFont(legendItemFont);
    int legendMargin = 10;
    legend.setMargin(0.0, legendMargin, legendMargin, legendMargin);
    legend.setBackgroundPaint(transparentColor);

    // impostiamo un gradiente orizzontale
    Paint chartBgPaint = new GradientPaint(0, 0, new Color(255, 253, 240), 0, height, Color.WHITE);
    chart.setBackgroundPaint(chartBgPaint);
    return chart;
}

From source file:org.tap4j.plugin.util.GraphHelper.java

/**
 * Creates the graph displayed on Method results page to compare execution
 * duration and status of a test method across builds.
 * //from  w ww. j a  va2s. com
 * At max, 9 older builds are displayed.
 * 
 * @param req
 *            request
 * @param dataset
 *            data set to be displayed on the graph
 * @param statusMap
 *            a map with build as key and the test methods execution status
 *            (result) as the value
 * @param methodUrl
 *            URL to get to the method from a build test result page
 * @return the chart
 */
public static JFreeChart createMethodChart(StaplerRequest req, final CategoryDataset dataset,
        final Map<NumberOnlyBuildLabel, String> statusMap, final String methodUrl) {

    final JFreeChart chart = ChartFactory.createBarChart(null, // chart
            // title
            null, // unused
            " Duration (secs)", // range axis label
            dataset, // data
            PlotOrientation.VERTICAL, // orientation
            true, // include legend
            true, // tooltips
            true // urls
    );

    // NOW DO SOME OPTIONAL CUSTOMISATION OF THE CHART...
    chart.setBackgroundPaint(Color.white);
    chart.removeLegend();

    final CategoryPlot plot = chart.getCategoryPlot();
    plot.setBackgroundPaint(Color.WHITE);
    plot.setOutlinePaint(null);
    plot.setForegroundAlpha(0.8f);
    plot.setDomainGridlinesVisible(true);
    plot.setDomainGridlinePaint(Color.white);
    plot.setRangeGridlinesVisible(true);
    plot.setRangeGridlinePaint(Color.black);

    CategoryAxis domainAxis = new ShiftedCategoryAxis(null);
    plot.setDomainAxis(domainAxis);
    domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_90);
    domainAxis.setLowerMargin(0.0);
    domainAxis.setUpperMargin(0.0);
    domainAxis.setCategoryMargin(0.0);

    final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
    rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());

    BarRenderer br = new BarRenderer() {

        private static final long serialVersionUID = 961671076462240008L;
        Map<String, Paint> statusPaintMap = new HashMap<String, Paint>();

        {
            statusPaintMap.put("PASS", ColorPalette.BLUE);
            statusPaintMap.put("SKIP", ColorPalette.YELLOW);
            statusPaintMap.put("FAIL", ColorPalette.RED);
        }

        /**
         * Returns the paint for an item. Overrides the default behavior
         * inherited from AbstractSeriesRenderer.
         * 
         * @param row
         *            the series.
         * @param column
         *            the category.
         * 
         * @return The item color.
         */
        public Paint getItemPaint(final int row, final int column) {
            NumberOnlyBuildLabel label = (NumberOnlyBuildLabel) dataset.getColumnKey(column);
            Paint paint = statusPaintMap.get(statusMap.get(label));
            // when the status of test method is unknown, use gray color
            return paint == null ? Color.gray : paint;
        }
    };

    br.setBaseToolTipGenerator(new CategoryToolTipGenerator() {
        public String generateToolTip(CategoryDataset dataset, int row, int column) {
            NumberOnlyBuildLabel label = (NumberOnlyBuildLabel) dataset.getColumnKey(column);
            if ("UNKNOWN".equals(statusMap.get(label))) {
                return "unknown";
            }
            // values are in seconds
            return dataset.getValue(row, column) + " secs";
        }
    });

    br.setBaseItemURLGenerator(new CategoryURLGenerator() {
        public String generateURL(CategoryDataset dataset, int series, int category) {
            NumberOnlyBuildLabel label = (NumberOnlyBuildLabel) dataset.getColumnKey(category);
            if ("UNKNOWN".equals(statusMap.get(label))) {
                // no link when method result doesn't exist
                return null;
            }
            // return label.build.getUpUrl() + label.build.getNumber() + "/" + PluginImpl.URL + "/" + methodUrl;
            return label.build.getUpUrl() + label.build.getNumber() + "/tap/" + methodUrl;
        }
    });

    br.setItemMargin(0.0);
    br.setMinimumBarLength(5);
    // set the base to be 1/100th of the maximum value displayed in the
    // graph
    br.setBase(br.findRangeBounds(dataset).getUpperBound() / 100);
    plot.setRenderer(br);

    // crop extra space around the graph
    plot.setInsets(new RectangleInsets(0, 0, 0, 5.0));
    return chart;
}