Skip to content

Commit a57a841

Browse files
committed
* More polish for the candlestick example.
* Added size/position attrs for the graph widget in xyplots.
1 parent 8714435 commit a57a841

12 files changed

Lines changed: 211 additions & 34 deletions

File tree

androidplot-core/src/main/java/com/androidplot/Plot.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,10 @@ public void run() {
374374
*/
375375
private void processBaseAttrs(TypedArray attrs) {
376376

377+
// markup mode
378+
boolean markupEnabled = attrs.getBoolean(R.styleable.Plot_markupEnabled, false);
379+
setMarkupEnabled(markupEnabled);
380+
377381
// renderMode
378382
RenderMode renderMode = RenderMode.values()
379383
[attrs.getInt(R.styleable.Plot_renderMode, getRenderMode().ordinal())];

androidplot-core/src/main/java/com/androidplot/candlestick/CandlestickFormatter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
public class CandlestickFormatter extends XYSeriesFormatter<XYRegionFormatter> {
3131

3232
private static final float DEFAULT_WIDTH_PIX = PixelUtils.dpToPix(10);
33-
private static final float DEFAULT_STROKE_PIX = PixelUtils.dpToPix(2);
33+
private static final float DEFAULT_STROKE_PIX = PixelUtils.dpToPix(4);
3434

3535
private Paint wickPaint;
3636
private Paint risingBodyFillPaint;

androidplot-core/src/main/java/com/androidplot/ui/LayoutManager.java

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,15 @@ public class LayoutManager extends ZLinkedList<Widget>
3838
private Paint paddingPaint;
3939
private DisplayDimensions displayDims = new DisplayDimensions();
4040

41-
// cache of widget rects
42-
//private HashMap<Widget, DisplayDimensions> widgetRects;
43-
4441
{
45-
//widgetRects = new HashMap<Widget, DisplayDimensions>();
4642
anchorPaint = new Paint();
4743
anchorPaint.setStyle(Paint.Style.FILL);
4844
anchorPaint.setColor(Color.GREEN);
4945
outlinePaint = new Paint();
5046
outlinePaint.setColor(Color.GREEN);
5147
outlinePaint.setStyle(Paint.Style.STROKE);
48+
outlinePaint.setAntiAlias(true);
49+
outlinePaint.setStrokeWidth(2);
5250
marginPaint = new Paint();
5351
marginPaint.setColor(Color.YELLOW);
5452
marginPaint.setStyle(Paint.Style.FILL);
@@ -96,10 +94,7 @@ public void draw(Canvas canvas) throws PlotRenderException {
9694
PointF coords = widget.getElementCoordinates(elementHeight,
9795
elementWidth, displayDims.paddedRect, metrics);
9896

99-
//RectF widgetRect = new RectF(coords.x, coords.y, coords.x + elementWidth, coords.y + elementHeight);
100-
//DisplayDimensions dims = widgetRects.get(widget);
10197
DisplayDimensions dims = widget.getWidgetDimensions();
102-
//RectF widgetRect = widgetRects.get(widget);
10398

10499
if (drawOutlineShadowsEnabled) {
105100
canvas.drawRect(dims.canvasRect, outlineShadowPaint);
@@ -109,15 +104,10 @@ public void draw(Canvas canvas) throws PlotRenderException {
109104
// so this is necessary to avoid clipping borders. I suspect that its a floating point
110105
// jitter issue.
111106
if (widget.isClippingEnabled()) {
112-
//RectF clipRect = new RectF(l-1, t-1, r + 1, b + 1);
113-
//canvas.clipRect(clipRect, Region.Op.REPLACE);
114107
canvas.clipRect(dims.canvasRect, Region.Op.INTERSECT);
115108
}
116109
widget.draw(canvas, dims.canvasRect);
117110

118-
//RectF marginatedWidgetRect = widget.getMarginatedRect(dims.canvasRect);
119-
//RectF paddedWidgetRect = widget.getPaddedRect(marginatedWidgetRect);
120-
121111
if (drawMarginsEnabled) {
122112
drawSpacing(canvas, dims.canvasRect, dims.marginatedRect, getMarginPaint());
123113
}
@@ -135,23 +125,19 @@ public void draw(Canvas canvas) throws PlotRenderException {
135125

136126

137127
if (drawOutlinesEnabled) {
138-
outlinePaint.setAntiAlias(true);
139128
canvas.drawRect(dims.canvasRect, outlinePaint);
140129
}
141130
} finally {
142-
//canvas.restoreToCount(canvasState); // restore clipping etc.
143131
canvas.restore();
144132
}
145133
}
146134
}
147135

148136
private void drawSpacing(Canvas canvas, RectF outer, RectF inner, Paint paint) {
149-
//int saved = canvas.save(Canvas.ALL_SAVE_FLAG);
150137
try {
151138
canvas.save(Canvas.ALL_SAVE_FLAG);
152139
canvas.clipRect(inner, Region.Op.DIFFERENCE);
153140
canvas.drawRect(outer, paint);
154-
//canvas.restoreToCount(saved);
155141
} finally {
156142
canvas.restore();
157143
}
@@ -253,7 +239,6 @@ public boolean onTouch(View v, MotionEvent event) {
253239
* to call this method as it is a relatively slow operation.
254240
*/
255241
public void refreshLayout() {
256-
//widgetRects.clear();
257242
for (Widget widget : elements()) {
258243
widget.layout(displayDims);
259244
}

androidplot-core/src/main/java/com/androidplot/ui/widget/TextLabelWidget.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public class TextLabelWidget extends Widget {
3535
labelPaint.setColor(Color.WHITE);
3636
labelPaint.setAntiAlias(true);
3737
labelPaint.setTextAlign(Paint.Align.CENTER);
38+
setClippingEnabled(false);
3839
}
3940

4041
public TextLabelWidget(LayoutManager layoutManager, Size size) {

androidplot-core/src/main/java/com/androidplot/ui/widget/Widget.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public abstract class Widget implements BoxModelable, Resizable {
3232

3333
private Paint borderPaint;
3434
private Paint backgroundPaint;
35-
private boolean clippingEnabled = true;
35+
private boolean clippingEnabled = false;
3636
private BoxModel boxModel = new BoxModel();
3737
private Size size;
3838
private DisplayDimensions plotDimensions = new DisplayDimensions();

androidplot-core/src/main/java/com/androidplot/xy/SimpleXYSeries.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,14 @@ public SimpleXYSeries(String title) {
5656
this.title = title;
5757
}
5858

59-
public SimpleXYSeries(ArrayFormat format, String title, double... model) {
59+
public SimpleXYSeries(ArrayFormat format, String title, Number... model) {
6060
this(asNumberList(model), format, title);
6161
}
6262

63-
protected static List<Number> asNumberList(double... model) {
63+
protected static List<Number> asNumberList(Number... model) {
6464
List<Number> numbers = new ArrayList<>();
65-
for(double d : model) {
66-
numbers.add(d);
65+
for(Number n : model) {
66+
numbers.add(n);
6767
}
6868
return numbers;
6969
}

androidplot-core/src/main/java/com/androidplot/xy/XYGraphWidget.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,8 @@ public void setRangeCursorPaint(Paint rangeCursorPaint) {
251251
setMarginBottom(4);
252252
rangeValueFormat = new DecimalFormat("0.0");
253253
domainValueFormat = new DecimalFormat("0.0");
254-
axisValueLabelRegions = new ZHash<RectRegion, AxisValueLabelFormatter>();
254+
axisValueLabelRegions = new ZHash<>();
255+
setClippingEnabled(true);
255256
}
256257

257258
public XYGraphWidget(LayoutManager layoutManager, XYPlot plot, Size size) {

androidplot-core/src/main/java/com/androidplot/xy/XYPlot.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,15 @@ protected void onPreInit() {
257257

258258
@Override
259259
protected void processAttrs(TypedArray attrs) {
260+
261+
// graph size & position
262+
AttrUtils.configureWidget(attrs, getGraphWidget(),
263+
R.styleable.xy_XYPlot_graphHeightSizeLayoutType, R.styleable.xy_XYPlot_domainLabelHeight,
264+
R.styleable.xy_XYPlot_graphWidthSizeLayoutType, R.styleable.xy_XYPlot_graphWidth,
265+
R.styleable.xy_XYPlot_graphLayoutStyleX, R.styleable.xy_XYPlot_graphPositionX,
266+
R.styleable.xy_XYPlot_graphLayoutStyleY, R.styleable.xy_XYPlot_graphPositionY,
267+
R.styleable.xy_XYPlot_graphAnchorPosition, R.styleable.xy_XYPlot_graphVisible);
268+
260269
String domainLabelAttr = attrs.getString(R.styleable.xy_XYPlot_domainLabel);
261270
if(domainLabelAttr != null) {
262271
setDomainLabel(domainLabelAttr);

androidplot-core/src/main/res/values/attrs.xml

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,18 @@
3636

3737
<!-- values must match the ordinal of its corresponding
3838
element in the AnchorPosition enum. -->
39+
<attr name="graphAnchorPosition" format="enum">
40+
<enum name="top_middle" value="0"/>
41+
<enum name="left_top" value="1"/>
42+
<enum name="left_middle" value="2"/>
43+
<enum name="left_bottom" value="3"/>
44+
<enum name="right_top" value="4"/>
45+
<enum name="right_middle" value="5"/>
46+
<enum name="right_bottom" value="6"/>
47+
<enum name="bottom_middle" value="7"/>
48+
<enum name="center" value="8"/>
49+
</attr>
50+
3951
<attr name="domainLabelAnchorPosition" format="enum">
4052
<enum name="top_middle" value="0"/>
4153
<enum name="left_top" value="1"/>
@@ -72,6 +84,18 @@
7284
<enum name="center" value="8"/>
7385
</attr>
7486

87+
<attr name="graphHeightSizeLayoutType" format="enum">
88+
<enum name="absolute" value="0"/>
89+
<enum name="relative" value="1"/>
90+
<enum name="fill" value="2"/>
91+
</attr>
92+
93+
<attr name="graphWidthSizeLayoutType" format="enum">
94+
<enum name="absolute" value="0"/>
95+
<enum name="relative" value="1"/>
96+
<enum name="fill" value="2"/>
97+
</attr>
98+
7599
<attr name="domainLabelHeightSizeLayoutType" format="enum">
76100
<enum name="absolute" value="0"/>
77101
<enum name="relative" value="1"/>
@@ -120,6 +144,24 @@
120144
<enum name="fill" value="2"/>
121145
</attr>
122146

147+
<attr name="graphLayoutStyleX" format="enum">
148+
<enum name="absolute_from_left" value="0"/>
149+
<enum name="absolute_from_right" value="1"/>
150+
<enum name="absolute_from_center" value="2"/>
151+
<enum name="relative_from_left" value="3"/>
152+
<enum name="relative_from_right" value="4"/>
153+
<enum name="relative_from_center" value="5"/>
154+
</attr>
155+
156+
<attr name="graphLayoutStyleY" format="enum">
157+
<enum name="absolute_from_top" value="0"/>
158+
<enum name="absolute_from_bottom" value="1"/>
159+
<enum name="absolute_from_center" value="2"/>
160+
<enum name="relative_from_top" value="3"/>
161+
<enum name="relative_from_bottom" value="4"/>
162+
<enum name="relative_from_center" value="5"/>
163+
</attr>
164+
123165
<attr name="domainLabelLayoutStyleX" format="enum">
124166
<enum name="absolute_from_left" value="0"/>
125167
<enum name="absolute_from_right" value="1"/>
@@ -176,6 +218,7 @@
176218

177219
<!-- Plot -->
178220
<declare-styleable name="Plot">
221+
<attr name="markupEnabled" format="boolean"/>
179222
<attr name="renderMode"/>
180223
<attr name="label" format="string"/>
181224
<attr name="labelTextSize" format="dimension"/>
@@ -224,7 +267,17 @@
224267
<attr name="rangeLabelAnchorPosition"/>
225268
<attr name="rangeLabelVisible" format="boolean"/>
226269

227-
<!-- graph widget margin / padding -->
270+
<!-- graph widget -->
271+
<attr name="graphHeightSizeLayoutType"/>
272+
<attr name="graphWidthSizeLayoutType"/>
273+
<attr name="graphHeight" format="dimension|float|integer"/>
274+
<attr name="graphWidth" format="dimension|float|integer"/>
275+
<attr name="graphLayoutStyleX"/>
276+
<attr name="graphLayoutStyleY"/>
277+
<attr name="graphPositionX" format="dimension|float|integer"/>
278+
<attr name="graphPositionY" format="dimension|float|integer"/>
279+
<attr name="graphAnchorPosition"/>
280+
<attr name="graphVisible" format="boolean"/>
228281
<attr name="graphMarginTop" format="dimension"/>
229282
<attr name="graphMarginBottom" format="dimension"/>
230283
<attr name="graphMarginLeft" format="dimension"/>

demoapp/src/main/java/com/androidplot/demos/CandlestickChartActivity.java

Lines changed: 77 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,21 @@
1717
package com.androidplot.demos;
1818

1919
import android.app.Activity;
20+
import android.graphics.Color;
21+
import android.graphics.DashPathEffect;
2022
import android.os.Bundle;
2123
import com.androidplot.candlestick.CandlestickFormatter;
2224
import com.androidplot.candlestick.CandlestickMaker;
25+
import com.androidplot.util.PixelUtils;
2326
import com.androidplot.xy.*;
2427

28+
import java.text.DecimalFormat;
29+
import java.text.FieldPosition;
30+
import java.text.Format;
31+
import java.text.ParsePosition;
32+
import java.util.Arrays;
33+
import java.util.List;
34+
2535
/**
2636
* A simple example of a candlestick chart rendered on an {@link XYPlot}.
2737
*/
@@ -34,26 +44,86 @@ public class CandlestickChartActivity extends Activity
3444
public void onCreate(Bundle savedInstanceState)
3545
{
3646
super.onCreate(savedInstanceState);
37-
setContentView(R.layout.simple_xy_plot_example);
47+
setContentView(R.layout.candlestick_example);
3848

3949
// initialize our XYPlot reference:
4050
plot = (XYPlot) findViewById(R.id.plot);
4151

42-
plot.getLayoutManager().moveToBottom(plot.getTitleWidget());
4352

44-
XYSeries highVals = new SimpleXYSeries(SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "high", 12, 10, 15, 8, 7);
45-
XYSeries lowVals = new SimpleXYSeries(SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "low", 3, 1, 5, 0, 2);
46-
XYSeries openVals = new SimpleXYSeries(SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "open", 5, 2, 7, 5, 3);
47-
XYSeries closeVals = new SimpleXYSeries(SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "close", 7, 9, 6, 0, 4);
53+
// create our min, max, high and low values:
54+
List<Number> xVals = Arrays.asList(new Number[]{1, 2, 3, 4, 5});
55+
XYSeries highVals = new SimpleXYSeries(xVals,
56+
Arrays.asList(12, 10, 15, 8, 7), "high");
57+
XYSeries lowVals = new SimpleXYSeries(xVals,
58+
Arrays.asList(3, 1, 5, 0, 2), "low");
59+
XYSeries openVals = new SimpleXYSeries(xVals,
60+
Arrays.asList(5, 2, 7, 5, 3), "open");
61+
XYSeries closeVals = new SimpleXYSeries(xVals,
62+
Arrays.asList(7, 9, 6, 0, 4), "close");
63+
64+
// draw a simple line plot of the close vals:
65+
LineAndPointFormatter lpf = new LineAndPointFormatter(Color.WHITE, Color.WHITE, null, null);
66+
lpf.getLinePaint().setPathEffect(
67+
new DashPathEffect(
68+
new float[]{PixelUtils.dpToPix(5), PixelUtils.dpToPix(5)}, 0));
69+
lpf.setInterpolationParams(
70+
new CatmullRomInterpolator.Params(20, CatmullRomInterpolator.Type.Centripetal));
71+
72+
plot.addSeries(closeVals, lpf);
4873

4974
CandlestickFormatter formatter = new CandlestickFormatter();
75+
76+
// draw candlestick bodies as triangles instead of squares:
77+
// triangles will point up for items that closed higher than they opened
78+
// and down for those that closed lower:
5079
formatter.setBodyStyle(CandlestickFormatter.BodyStyle.Triangle);
80+
81+
// add the candlestick series data to the plot:
5182
CandlestickMaker.make(plot, formatter,
5283
openVals, closeVals, highVals, lowVals);
5384

54-
// reduce the number of range labels
85+
// setup the range label formatting, etc:
86+
plot.setRangeLabel("Amount");
5587
plot.setTicksPerRangeLabel(3);
5688

89+
plot.setRangeValueFormat(new DecimalFormat("$0.00"));
90+
91+
// setup the domain label formatting, etc:
92+
plot.setDomainBoundaries(0, 6, BoundaryMode.FIXED);
93+
plot.setDomainLabel("Day");
94+
plot.setDomainStep(XYStepMode.INCREMENT_BY_VAL, 1);
95+
plot.setDomainValueFormat(new Format() {
96+
@Override
97+
public StringBuffer format(Object object, StringBuffer buffer, FieldPosition field) {
98+
switch(((Number) object).intValue()) {
99+
case 1:
100+
buffer.append("Mon");
101+
break;
102+
case 2:
103+
buffer.append("Tues");
104+
break;
105+
case 3:
106+
buffer.append("Wed");
107+
break;
108+
case 4:
109+
buffer.append("Thurs");
110+
break;
111+
case 5:
112+
buffer.append("Fri");
113+
break;
114+
default:
115+
// show nothing
116+
117+
}
118+
return buffer;
119+
}
120+
121+
@Override
122+
public Object parseObject(String string, ParsePosition position) {
123+
return null;
124+
}
125+
});
126+
57127
// rotate domain labels 45 degrees to make them more compact horizontally:
58128
plot.getGraphWidget().setDomainLabelOrientation(-45);
59129
}

0 commit comments

Comments
 (0)