的
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
# Custom Renderers
|
||||
Androidplot renderers can be extended with extra functionality in the form of custom renderers.
|
||||
For the example below we'll look at creating a custom implementation of BarRenderer that will
|
||||
draw bars with rounded edges. While this example demonstrates an `XYPlot`, the steps apply to
|
||||
`PieChart` etc. as well.
|
||||
|
||||
## Create the Formatter
|
||||
The first step to creating a custom renderer is defining it's `Formatter`. Aside from providing
|
||||
the visual configuration used by the `Renderer` to draw series data, it's also used by Androidplot
|
||||
to map a series to a specific renderer type and if necessary, obtain a new instance of that renderer.
|
||||
Here's the most basic implementation:
|
||||
|
||||
```java
|
||||
class RoundedBarFormatter extends BarFormatter {
|
||||
|
||||
{
|
||||
// for now we'll hardcode some formatting values.
|
||||
// a real implementation would probably provide a constructor instead
|
||||
getBorderPaint().setColor(Color.WHITE);
|
||||
getFillPaint().setColor(Color.RED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<RoundedBarRenderer> getRendererClass() {
|
||||
return RoundedBarRenderer.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoundedBarRenderer doGetRendererInstance(XYPlot xyPlot) {
|
||||
return new RoundedBarRenderer(xyPlot);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Create the Renderer
|
||||
All we want to do here is tweak the way `BarRenderer` behaves a little so we'll use it as our base class:
|
||||
|
||||
```java
|
||||
class RoundedBarRenderer extends BarRenderer<RoundedBarFormatter> {
|
||||
|
||||
public RoundedBarRenderer(XYPlot plot) {
|
||||
super(plot);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawBar(Canvas canvas, Bar<RoundedBarFormatter> bar, RectF rect) {
|
||||
// TODO this is where we'll add our custom behavior
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In the case of our RoundedBarFormatter, the behavior we need to change all exits within the
|
||||
`drawBar(Canvas, Bar, RectF)` method. The existing implementation uses `Canvas.drawRect(...)` to
|
||||
draw bars. We could use a stroke with rounded edges, but this would cause the edges on both the top
|
||||
and the bottom to be rounded, which won't look right. We'll draw using a path instead:
|
||||
|
||||
```java
|
||||
@Override
|
||||
protected void drawBar(Canvas canvas, Bar<RoundedBarFormatter> bar, RectF rect) {
|
||||
|
||||
// skip nulls:
|
||||
if(bar.getY() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
RoundedBarFormatter formatter = getFormatter(bar.i, bar.series);
|
||||
if(formatter == null) {
|
||||
formatter = bar.formatter;
|
||||
}
|
||||
|
||||
// don't need to draw if the bar lacks height or width:
|
||||
if (rect.height() > 0 && rect.width() > 0) {
|
||||
final Path path = new Path();
|
||||
final float arcHeightPx = 20;
|
||||
final float adjustedTop = rect.top + arcHeightPx;
|
||||
final RectF cap = new RectF(rect.left, rect.top, rect.right,rect.top + 2 * arcHeightPx);
|
||||
|
||||
// start at bottom-left and move clock-wise around the shape:
|
||||
path.moveTo(rect.left, rect.bottom);
|
||||
path.lineTo(rect.left, adjustedTop);
|
||||
path.arcTo(cap, 180, 180, false);
|
||||
path.lineTo(rect.right, rect.bottom);
|
||||
path.close();
|
||||
|
||||
canvas.drawPath(path, formatter.getFillPaint());
|
||||
canvas.drawPath(path, formatter.getBorderPaint());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Use It
|
||||
Using the new custom renderer is as easy as adding a series to a plot using `RoundedBarFormatter`:
|
||||
|
||||
```java
|
||||
plot.addSeries(series1, new RoundedBarFormatter(Color.RED));
|
||||
plot.addSeries(series2, new RoundedBarFormatter(Color.BLUE));
|
||||
```
|
||||
|
||||
Here's what this would look like used in the demo app's `SimpleXYPlotActivity`:
|
||||
|
||||

|
||||
Reference in New Issue
Block a user