Вопрос

Im using Graphview and work fine, but now i have a problem.

I would like to have a background for each series that is added to the graph, and not for all series

Is this possible?

Это было полезно?

Решение

This is currently (5 August 2014) not possible on the original GraphView library.

I needed this functionality, so I forked the library and implemented the functionality myself. You can find the updated code on the feature/series_specific_styles branch of my fork:

Hopefully in future these changes will be pulled into the original library.


The actual code changes are relatively simple.

  • Added required background fields to GraphViewSeries.GraphViewSeriesStyle

  • Updated LineGraphView.drawSeries() to look for these fields instead of relying on its own internal values.

I have included full updates below, but the easiest way to view them is on the commit page:


Here is the updated GraphViewSeriesStyle class:

static public class GraphViewSeriesStyle {
    public int color = 0xff0077cc;
    public int thickness = 3;
    private ValueDependentColor valueDependentColor;

    private final Paint paintBackground;
    private boolean drawBackground;
    private boolean drawDataPoints;
    private float dataPointsRadius = 10f;

    public GraphViewSeriesStyle() {
        super();

        paintBackground = new Paint();
        paintBackground.setColor(Color.rgb(20, 40, 60));
        paintBackground.setStrokeWidth(4);
        paintBackground.setAlpha(128);
    }

    public GraphViewSeriesStyle(int color, int thickness) {
        super();
        this.color = color;
        this.thickness = thickness;

        paintBackground = new Paint();
        paintBackground.setColor(Color.rgb(20, 40, 60));
        paintBackground.setStrokeWidth(4);
        paintBackground.setAlpha(128);
    }

    public ValueDependentColor getValueDependentColor() {
        return valueDependentColor;
    }

    /**
     * the color depends on the value of the data.
     * only possible in BarGraphView
     * @param valueDependentColor
     */
    public void setValueDependentColor(ValueDependentColor valueDependentColor) {
        this.valueDependentColor = valueDependentColor;
    }

    public boolean getDrawBackground() {
        return drawBackground;
    }

    public void setDrawBackground(boolean drawBackground) {
        this.drawBackground = drawBackground;
    }

    public Paint getPaintBackground() {
        return paintBackground;
    }

    public int getBackgroundColor() {
        return paintBackground.getColor();
    }

    /**
     * sets the background colour for the series. This is not the background
     * colour of the whole graph.
     */
    public void setBackgroundColor(int color) {
        paintBackground.setColor(color);
    }

    public float getDataPointsRadius() {
        return dataPointsRadius;
    }

    public boolean getDrawDataPoints() {
        return drawDataPoints;
    }

    /**
     * sets the radius of the circles at the data points.
     * @see #setDrawDataPoints(boolean)
     * @param dataPointsRadius
     */
    public void setDataPointsRadius(float dataPointsRadius) {
        this.dataPointsRadius = dataPointsRadius;
    }

    /**
     * You can set the flag to let the GraphView draw circles at the data points
     * @see #setDataPointsRadius(float)
     * @param drawDataPoints
     */
    public void setDrawDataPoints(boolean drawDataPoints) {
        this.drawDataPoints = drawDataPoints;
    }
}

Here is the updated LineGraphView.drawSeries() method:

public void drawSeries(Canvas canvas, GraphViewDataInterface[] values, float graphwidth, float graphheight, float border, double minX, double minY, double diffX, double diffY, float horstart, GraphViewSeriesStyle style) {
    // draw background
    double lastEndY = 0;
    double lastEndX = 0;

    // draw data
    paint.setStrokeWidth(style.thickness);
    paint.setColor(style.color);


    Path bgPath = null;
    if ((drawBackground) || (style.getDrawBackground())) {
        bgPath = new Path();
    }

    lastEndY = 0;
    lastEndX = 0;
    float firstX = 0;
    for (int i = 0; i < values.length; i++) {
        double valY = values[i].getY() - minY;
        double ratY = valY / diffY;
        double y = graphheight * ratY;

        double valX = values[i].getX() - minX;
        double ratX = valX / diffX;
        double x = graphwidth * ratX;

        if (i > 0) {
            float startX = (float) lastEndX + (horstart + 1);
            float startY = (float) (border - lastEndY) + graphheight;
            float endX = (float) x + (horstart + 1);
            float endY = (float) (border - y) + graphheight;

            // draw data point
            if (drawDataPoints) {
                //fix: last value was not drawn. Draw here now the end values
                canvas.drawCircle(endX, endY, dataPointsRadius, paint);
            } else if (style.getDrawDataPoints()) {
                canvas.drawCircle(endX, endY, style.getDataPointsRadius(), paint);
            }

            canvas.drawLine(startX, startY, endX, endY, paint);
            if (bgPath != null) {
                if (i==1) {
                    firstX = startX;
                    bgPath.moveTo(startX, startY);
                }
                bgPath.lineTo(endX, endY);
            }
        } else if ((drawDataPoints) || (style.getDrawDataPoints())) {
            //fix: last value not drawn as datapoint. Draw first point here, and then on every step the end values (above)
            float first_X = (float) x + (horstart + 1);
            float first_Y = (float) (border - y) + graphheight;
            if (drawDataPoints) {
                canvas.drawCircle(first_X, first_Y, dataPointsRadius, paint);
            } else if (style.getDrawDataPoints()) {
                canvas.drawCircle(first_X, first_Y, style.getDataPointsRadius(), paint);
            }
        }
        lastEndY = y;
        lastEndX = x;
    }

    if (bgPath != null) {
        // end / close path
        bgPath.lineTo((float) lastEndX, graphheight + border);
        bgPath.lineTo(firstX, graphheight + border);
        bgPath.close();
        if (style.getDrawBackground()) {
            canvas.drawPath(bgPath, style.getPaintBackground());
        } else {
            canvas.drawPath(bgPath, paintBackground);
        }
    }
}

For interest, that branch also allows data points to be configured for each series - code changes visible here:

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top