Skip to content

Commit

Permalink
Merge pull request #50 from mheinzerling/JENKINS-16580
Browse files Browse the repository at this point in the history
JENKINS-16580: Prepare a way to add different charts for the coverage reports.
  • Loading branch information
centic9 committed May 30, 2016
2 parents 29bcd67 + d4d8c97 commit 04bdfe9
Show file tree
Hide file tree
Showing 15 changed files with 795 additions and 76 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -13,5 +13,8 @@ work
.project
build

# Generated images from CoverageObjectGraphTest
/*.png

# other
*~
13 changes: 13 additions & 0 deletions resources/test/Font Monkey License.txt
@@ -0,0 +1,13 @@
This font is copyright 2008 by P.D. Magnus. Like all the Fontmonkey fonts, it is free for for all commercial or non-commercial use. To be clear: They do not cost anything.

If you do use them for something, though, I would love to here about it. I would appreciate a sample of the thing for which you used the font, a photo of it, or even just an e-mail telling me about it.

You can contact me via the website or by e-mail at pmagnus@fecundity.com

You are also encouraged to acknowledge fontmonkey or link to me, although neither is strictly speaking required.

The font files may be freely distributed provided this license, attribution to me, and the fontmonkey URL are included.

VERSION HISTORY

26apr2008 first release
Binary file added resources/test/baseStroke.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/test/belligerent.ttf
Binary file not shown.
Binary file added resources/test/crop100.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/test/crop5.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/test/multiple.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/test/simple.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/test/skipzero.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
344 changes: 344 additions & 0 deletions src/main/java/hudson/plugins/jacoco/model/CoverageGraphLayout.java
@@ -0,0 +1,344 @@
package hudson.plugins.jacoco.model;

import hudson.plugins.jacoco.Messages;
import java.awt.BasicStroke;
import java.awt.Color;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.RectangleInsets;

/**
* @author Martin Heinzerling
*/
public class CoverageGraphLayout
{
enum CoverageType
{
INSTRUCTION(Messages.CoverageObject_Legend_Instructions())
{
@Override
public Coverage getCoverage(CoverageObject<?> a)
{
return a.instruction;
}

},
BRANCH(Messages.CoverageObject_Legend_Branch())
{
@Override
public Coverage getCoverage(CoverageObject<?> a)
{
return a.branch;
}

},
COMPLEXITY(Messages.CoverageObject_Legend_Complexity())
{
@Override
public Coverage getCoverage(CoverageObject<?> a)
{
return a.complexity;
}

},
METHOD(Messages.CoverageObject_Legend_Method())
{
@Override
public Coverage getCoverage(CoverageObject<?> a)
{
return a.method;
}

},
CLAZZ(Messages.CoverageObject_Legend_Class())
{
@Override
public Coverage getCoverage(CoverageObject<?> a)
{
return a.clazz;
}

},
LINE(Messages.CoverageObject_Legend_Line())
{
@Override
public Coverage getCoverage(CoverageObject<?> a)
{
return a.line;
}

};

private String message;

CoverageType(String message)
{
this.message = message;
}

public String getMessage()
{

return message;
}

public abstract Coverage getCoverage(CoverageObject<?> a);

public Number getValue(CoverageObject<?> a, CoverageValue value)
{
Coverage c = getCoverage(a);
if (c == null) return 0;
return value.getValue(c);

}

}

enum CoverageValue
{
MISSED
{
@Override
public String getMessage(CoverageType type)
{
return
Messages.CoverageObject_Legend_Missed(type.getMessage());

}

@Override
public Number getValue(Coverage c)
{
return c.getMissed();
}
},
COVERED
{
@Override
public String getMessage(CoverageType type)
{
return Messages.CoverageObject_Legend_Covered(type.getMessage());
}

@Override
public Number getValue(Coverage c)
{
return c.getCovered();
}
},
PERCENTAGE
{
@Override
public String getMessage(CoverageType type)
{
return type.getMessage();
}

@Override
public Number getValue(Coverage c)
{
return c.getPercentageFloat();
}
};


public abstract String getMessage(CoverageType type);

public abstract Number getValue(Coverage c);
}

static class Axis
{
private String label = null;
private int crop = -1;
private boolean skipZero = false;

public boolean isCrop()
{
return crop != -1;
}

public boolean isSkipZero()
{
return skipZero;
}

public String getLabel()
{
return label;
}

public int getCrop()
{
return crop;
}
}

static class Plot
{
private CoverageValue value;
private CoverageType type;
private Axis axis;
private Color color;

public Plot(Axis axis)
{
this.axis = axis;
}

public Number getValue(CoverageObject<?> a)
{
return type.getValue(a, value);
}

public String getMessage()
{
return value.getMessage(type);
}

public Axis getAxis()
{
return axis;
}

@Override
public String toString()
{
return axis + " " + type + " " + value + " " + color;
}
}

private float baseStroke = 4f;
private Stack<Axis> axes = new Stack<Axis>();
private Stack<Plot> plots = new Stack<Plot>();

public CoverageGraphLayout baseStroke(float baseStroke)
{
this.baseStroke = baseStroke;
return this;
}

public CoverageGraphLayout axis()
{
axes.push(new Axis());
return this;
}

private void assureAxis()
{
if (axes.isEmpty()) axis();
}

public CoverageGraphLayout crop()
{
return crop(5);
}

public CoverageGraphLayout crop(int marginInPercent)
{
assureAxis();
axes.peek().crop = marginInPercent;
return this;
}

public CoverageGraphLayout label(String label)
{
assureAxis();
axes.peek().label = label;
return this;
}

public CoverageGraphLayout skipZero()
{
assureAxis();
axes.peek().skipZero = true;
return this;
}

public CoverageGraphLayout plot()
{
assureAxis();
plots.add(new Plot(axes.peek()));
return this;
}

private void assurePlot()
{
if (plots.isEmpty()) plot();
}

public CoverageGraphLayout type(CoverageType type)
{
assurePlot();
plots.peek().type = type;
return this;
}

public CoverageGraphLayout value(CoverageValue value)
{
assurePlot();
plots.peek().value = value;
return this;
}

public CoverageGraphLayout color(Color color)
{
assurePlot();
plots.peek().color = color;
return this;
}

public List<Axis> getAxes()
{
return Collections.unmodifiableList(axes);
}

public List<Plot> getPlots()
{
return Collections.unmodifiableList(plots);
}

public void apply(JFreeChart chart)
{
final CategoryPlot plot = chart.getCategoryPlot();
Map<Axis, Integer> axisIds = new HashMap<Axis, Integer>();
int axisId = 0;
for (Axis axis : axes)
{
LineAndShapeRenderer renderer = new LineAndShapeRenderer(true, false);
renderer.setBaseStroke(new BasicStroke(baseStroke));
//add axis layout here
plot.setRenderer(axisId, renderer);
axisIds.put(axis, axisId);
axisId++;
}

for (Plot p : plots)
{
axisId = axisIds.get(p.axis);
int lineIdPerAxis = plot.getDataset(axisId).getRowIndex(p.getMessage());
LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot.getRenderer(axisId);
renderer.setSeriesPaint(lineIdPerAxis, p.color);
renderer.setSeriesItemLabelPaint(lineIdPerAxis, p.color);
renderer.setSeriesFillPaint(lineIdPerAxis, p.color);
//add line layout here
}

chart.getLegend().setPosition(RectangleEdge.RIGHT);
chart.setBackgroundPaint(Color.white);
// plot.setAxisOffset(new Spacer(Spacer.ABSOLUTE, 5.0, 5.0, 5.0, 5.0));
plot.setBackgroundPaint(Color.WHITE);
plot.setOutlinePaint(null);
plot.setRangeGridlinesVisible(true);
plot.setRangeGridlinePaint(Color.black);
plot.setInsets(new RectangleInsets(5.0, 0, 0, 5.0));
// add common layout here
}
}

0 comments on commit 04bdfe9

Please sign in to comment.