1/*
2 * Copyright 2012 AndroidPlot.com
3 *
4 *    Licensed under the Apache License, Version 2.0 (the "License");
5 *    you may not use this file except in compliance with the License.
6 *    You may obtain a copy of the License at
7 *
8 *        http://www.apache.org/licenses/LICENSE-2.0
9 *
10 *    Unless required by applicable law or agreed to in writing, software
11 *    distributed under the License is distributed on an "AS IS" BASIS,
12 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 *    See the License for the specific language governing permissions and
14 *    limitations under the License.
15 */
16
17package com.androidplot.xy;
18
19import android.content.Context;
20import android.graphics.Color;
21import android.graphics.Paint;
22import com.androidplot.ui.SeriesRenderer;
23import com.androidplot.util.Configurator;
24import com.androidplot.util.PixelUtils;
25
26/**
27 * Defines the visual aesthetics of an XYSeries; outline color and width, fill style,
28 * vertex size and color, shadowing, etc.
29 */
30public class LineAndPointFormatter extends XYSeriesFormatter<XYRegionFormatter> {
31
32    private static final float DEFAULT_LINE_STROKE_WIDTH_DP   = 1.5f;
33    private static final float DEFAULT_VERTEX_STROKE_WIDTH_DP = 4.5f;
34
35     // default implementation prints point's yVal:
36    private PointLabeler pointLabeler = new PointLabeler() {
37        @Override
38        public String getLabel(XYSeries series, int index) {
39            return series.getY(index) + "";
40        }
41    };
42
43    public FillDirection getFillDirection() {
44        return fillDirection;
45    }
46
47    /**
48     * Sets which edge to use to close the line's path for filling purposes.
49     * See {@link FillDirection}.
50     * @param fillDirection
51     */
52    public void setFillDirection(FillDirection fillDirection) {
53        this.fillDirection = fillDirection;
54    }
55
56    protected FillDirection fillDirection = FillDirection.BOTTOM;
57    protected Paint linePaint;
58    protected Paint vertexPaint;
59    protected Paint fillPaint;
60    private PointLabelFormatter pointLabelFormatter;
61
62    {
63        initLinePaint(Color.BLACK);
64    }
65
66    /**
67     * Should only be used in conjunction with calls to configure()...
68     */
69    public LineAndPointFormatter() {
70        this(Color.RED, Color.GREEN, Color.BLUE, null);
71    }
72
73    public LineAndPointFormatter(Integer lineColor, Integer vertexColor, Integer fillColor, PointLabelFormatter plf) {
74        this(lineColor, vertexColor, fillColor, plf, FillDirection.BOTTOM);
75    }
76
77    public LineAndPointFormatter(Integer lineColor, Integer vertexColor, Integer fillColor, PointLabelFormatter plf, FillDirection fillDir) {
78        initLinePaint(lineColor);
79        initVertexPaint(vertexColor);
80        initFillPaint(fillColor);
81        setFillDirection(fillDir);
82        this.setPointLabelFormatter(plf);
83    }
84
85    @Override
86    public Class<? extends SeriesRenderer> getRendererClass() {
87        return LineAndPointRenderer.class;
88    }
89
90    @Override
91    public SeriesRenderer getRendererInstance(XYPlot plot) {
92        return new LineAndPointRenderer(plot);
93    }
94
95    protected void initLinePaint(Integer lineColor) {
96        if (lineColor == null) {
97            linePaint = null;
98        } else {
99            linePaint = new Paint();
100            linePaint.setAntiAlias(true);
101            linePaint.setStrokeWidth(PixelUtils.dpToPix(DEFAULT_LINE_STROKE_WIDTH_DP));
102            linePaint.setColor(lineColor);
103            linePaint.setStyle(Paint.Style.STROKE);
104        }
105    }
106
107    protected void initVertexPaint(Integer vertexColor) {
108        if (vertexColor == null) {
109            vertexPaint = null;
110        } else {
111            vertexPaint = new Paint();
112            vertexPaint.setAntiAlias(true);
113            vertexPaint.setStrokeWidth(PixelUtils.dpToPix(DEFAULT_VERTEX_STROKE_WIDTH_DP));
114            vertexPaint.setColor(vertexColor);
115            vertexPaint.setStrokeCap(Paint.Cap.ROUND);
116        }
117    }
118
119    protected void initFillPaint(Integer fillColor) {
120        if (fillColor == null) {
121            fillPaint = null;
122        } else {
123            fillPaint = new Paint();
124            fillPaint.setAntiAlias(true);
125            fillPaint.setColor(fillColor);
126        }
127    }
128
129    /**
130     * Enables the shadow layer on linePaint and shadowPaint by calling
131     * setShadowLayer() with preset values.
132     */
133    public void enableShadows() {
134        linePaint.setShadowLayer(1, 3, 3, Color.BLACK);
135        vertexPaint.setShadowLayer(1, 3, 3, Color.BLACK);
136    }
137
138    public void disableShadows() {
139        linePaint.setShadowLayer(0, 0, 0, Color.BLACK);
140        vertexPaint.setShadowLayer(0, 0, 0, Color.BLACK);
141    }
142
143    public Paint getLinePaint() {
144        return linePaint;
145    }
146
147    public void setLinePaint(Paint linePaint) {
148        this.linePaint = linePaint;
149    }
150
151    public Paint getVertexPaint() {
152        return vertexPaint;
153    }
154
155    public void setVertexPaint(Paint vertexPaint) {
156        this.vertexPaint = vertexPaint;
157    }
158
159    public Paint getFillPaint() {
160        return fillPaint;
161    }
162
163    public void setFillPaint(Paint fillPaint) {
164        this.fillPaint = fillPaint;
165    }
166
167    public PointLabelFormatter getPointLabelFormatter() {
168        return pointLabelFormatter;
169    }
170
171    public void setPointLabelFormatter(PointLabelFormatter pointLabelFormatter) {
172        this.pointLabelFormatter = pointLabelFormatter;
173    }
174
175    public PointLabeler getPointLabeler() {
176        return pointLabeler;
177    }
178
179    public void setPointLabeler(PointLabeler pointLabeler) {
180        this.pointLabeler = pointLabeler;
181    }
182}
183