Skip to content
This repository has been archived by the owner on Nov 19, 2024. It is now read-only.

Jenkins 16580: Display more than only line coverage in graph #50

Merged
merged 10 commits into from
May 30, 2016
Merged
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Loading
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
Loading
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
Loading
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
Loading
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
Loading
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
Loading
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
Original file line number Diff line number Diff line change
@@ -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
}
}
Loading