Android Open Source - trifork-ibeacon-demo Line Graph






From Project

Back to project page trifork-ibeacon-demo.

License

The source code is released under:

Apache License

If you think the Android project trifork-ibeacon-demo listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 *      Created by Daniel Nadeau/*from  w  w w. ja  v a 2s  . c o m*/
 *      daniel.nadeau01@gmail.com
 *      danielnadeau.blogspot.com
 * 
 *      Licensed to the Apache Software Foundation (ASF) under one
       or more contributor license agreements.  See the NOTICE file
       distributed with this work for additional information
       regarding copyright ownership.  The ASF licenses this file
       to you under the Apache License, Version 2.0 (the
       "License"); you may not use this file except in compliance
       with the License.  You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

       Unless required by applicable law or agreed to in writing,
       software distributed under the License is distributed on an
       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
       KIND, either express or implied.  See the License for the
       specific language governing permissions and limitations
       under the License.
 */

package com.echo.holographlibrary;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Path.Direction;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Region;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;

import java.util.ArrayList;

public class LineGraph extends View {

    private static final int DEFAULT_PADDING = 10;
    private final int mDipPadding;
    private int mFillColor;
    private final int mAxisColor;
    private final float mStrokeWidth;
    private int mStrokeSpacing;
    private int mGraphBackgroundColor;
    private ArrayList<Line> mLines = new ArrayList<Line>();
    private Paint mPaint = new Paint();
    private float mMinY = 0, mMinX = 0;
    private float mMaxY = 0, mMaxX = 0;
    private double mRangeYRatio = 0;
    private double mRangeXRatio = 0;
    private boolean mUserSetMaxX = false;
    private int mLineToFill = -1;
    private int mSelectedIndex = -1;
    private OnPointClickedListener mListener;
    private Bitmap mFullImage;
    // Since this is a new addition, it has to default to false to be backwards compatible
    private boolean mUseDips;
    private Path mPath = new Path();
    private PorterDuffXfermode mXfermode = new PorterDuffXfermode(PorterDuff.Mode.CLEAR);
    private Canvas mCanvas;

    public LineGraph(Context context) {
        this(context, null);
    }

    public LineGraph(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public LineGraph(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mDipPadding = getPixelForDip(DEFAULT_PADDING);

        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.LineGraph, 0, 0);
        mFillColor = a.getColor(R.styleable.LineGraph_strokeColor, Color.BLACK);
        mAxisColor = a.getColor(R.styleable.LineGraph_lineAxisColor, Color.LTGRAY);
        mStrokeWidth = a.getDimension(R.styleable.LineGraph_strokeWidth, 2);
        mStrokeSpacing = a.getDimensionPixelSize(R.styleable.LineGraph_strokeSpacing, 10);
        mUseDips = a.getBoolean(R.styleable.LineGraph_useDip, false);
        mGraphBackgroundColor = Color.WHITE;
    }

    public boolean isUsingDips() {
        return mUseDips;
    }

    public void setUsingDips(boolean treatSizesAsDips) {
        this.mUseDips = treatSizesAsDips;
    }

    public void removeAllLines() {
        while (mLines.size() > 0) {
            mLines.remove(0);
        }
        postInvalidate();
    }

    public void addLine(Line line) {
        mLines.add(line);
        postInvalidate();
    }

    public void addPointToLine(int lineIndex, double x, double y) {
        addPointToLine(lineIndex, (float) x, (float) y);
    }

    public void addPointToLine(int lineIndex, float x, float y) {
        LinePoint p = new LinePoint(x, y);

        addPointToLine(lineIndex, p);
    }

    public double getRangeYRatio() {
        return mRangeYRatio;
    }

    public void setRangeYRatio(double rr) {
        this.mRangeYRatio = rr;
    }

    public double getRangeXRatio() {
        return mRangeXRatio;
    }

    public void setRangeXRatio(double rr) {
        this.mRangeXRatio = rr;
    }

    public void addPointToLine(int lineIndex, LinePoint point) {
        Line line = getLine(lineIndex);
        line.addPoint(point);
        mLines.set(lineIndex, line);
        resetLimits();
        postInvalidate();
    }

    public void addPointsToLine(int lineIndex, LinePoint[] points) {
        Line line = getLine(lineIndex);
        for (LinePoint point : points) {
            line.addPoint(point);
        }
        mLines.set(lineIndex, line);
        resetLimits();
        postInvalidate();
    }

    public void removeAllPointsAfter(int lineIndex, double x) {
        removeAllPointsBetween(lineIndex, x, getMaxX());
    }

    public void removeAllPointsBefore(int lineIndex, double x) {
        removeAllPointsBetween(lineIndex, getMinX(), x);
    }

    public void removeAllPointsBetween(int lineIndex, double startX, double finishX) {
        Line line = getLine(lineIndex);
        LinePoint[] pts = new LinePoint[line.getPoints().size()];
        pts = line.getPoints().toArray(pts);
        for (LinePoint point : pts) {
            if (point.getX() >= startX && point.getX() <= finishX) {
                line.removePoint(point);
            }
        }
        mLines.set(lineIndex, line);
        resetLimits();
        postInvalidate();
    }

    public void removePointsFromLine(int lineIndex, LinePoint[] points) {
        Line line = getLine(lineIndex);
        for (LinePoint point : points) {
            line.removePoint(point);
        }
        mLines.set(lineIndex, line);
        resetLimits();
        postInvalidate();
    }

    public void setFillColor(int fillColor) {
        mFillColor = fillColor;
    }

    public void setFillStrokeSpacing(int px) {
        mStrokeSpacing = px;
    }

    public void setGraphBackgroundColor(int color) {
        mGraphBackgroundColor = color;
    }

    public void removePointFromLine(int lineIndex, float x, float y) {
        LinePoint p = null;
        Line line = getLine(lineIndex);
        p = line.getPoint(x, y);
        removePointFromLine(lineIndex, p);
    }

    public void removePointFromLine(int lineIndex, LinePoint point) {
        Line line = getLine(lineIndex);
        line.removePoint(point);
        mLines.set(lineIndex, line);
        resetLimits();
        postInvalidate();
    }

    public void resetYLimits() {
        float range = getMaxY() - getMinY();
        setRangeY(getMinY() - range * getRangeYRatio(), getMaxY() + range * getRangeYRatio());
    }

    public void resetXLimits() {
        float range = getMaxX() - getMinX();
        setRangeX(getMinX() - range * getRangeXRatio(), getMaxX() + range * getRangeXRatio());
    }

    public void resetLimits() {
        resetYLimits();
        resetXLimits();
    }

    public ArrayList<Line> getLines() {
        return mLines;
    }

    public void setLineToFill(int indexOfLine) {
        this.mLineToFill = indexOfLine;
        postInvalidate();
    }

    public int getLineToFill() {
        return mLineToFill;
    }

    public void setLines(ArrayList<Line> lines) {
        this.mLines = lines;
    }

    public Line getLine(int index) {
        return mLines.get(index);
    }

    public int getSize() {
        return mLines.size();
    }

    public void setRangeY(float min, float max) {
        mMinY = min;
        mMaxY = max;
    }

    private void setRangeY(double min, double max) {
        mMinY = (float) min;
        mMaxY = (float) max;
    }

    public void setRangeX(float min, float max) {
        mMinX = min;
        mMaxX = max;
        mUserSetMaxX = true;
    }

    private void setRangeX(double min, double max) {
        mMinX = (float) min;
        mMaxX = (float) max;
    }

    public float getMaxY() {
        float max = mLines.get(0).getPoint(0).getY();
        for (Line line : mLines) {
            for (LinePoint point : line.getPoints()) {
                max = point.getY() > max ? point.getY() : max;
            }
        }
        mMaxY = max;
        return mMaxY;
    }

    public float getMinY() {
        float min = mLines.get(0).getPoint(0).getY();
        for (Line line : mLines) {
            for (LinePoint point : line.getPoints()) {
                min = point.getY() < min ? point.getY() : min;
            }
        }
        mMinY = min;
        return mMinY;
    }

    public float getMinLimY() {
        return mMinY;
    }

    public float getMaxLimY() {
        return mMaxY;
    }

    public float getMinLimX() {
        return mMinX;
    }

    public float getMaxLimX() {
        if (mUserSetMaxX) {
            return mMaxX;
        } else {
            return getMaxX();
        }
    }

    public float getMaxX() {
        float max = mLines.size() > 0 ? mLines.get(0).getPoint(0).getX() : 0;
        for (Line line : mLines) {
            for (LinePoint point : line.getPoints()) {
                max = point.getX() > max ? point.getX() : max;
            }
        }
        mMaxX = max;
        return mMaxX;

    }

    public float getMinX() {
        float min = mLines.size() > 0 ? mLines.get(0).getPoint(0).getX() : 0;
        for (Line line : mLines) {
            for (LinePoint point : line.getPoints()) {
                min = point.getX() < min ? point.getX() : min;
            }
        }
        mMinX = min;
        return mMinX;
    }

    public void onDraw(Canvas canvas) {
        if (null == mFullImage) {
            mFullImage = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
            mCanvas = new Canvas(mFullImage);
        }

        mCanvas.drawColor(mGraphBackgroundColor);
        mPaint.reset();
        float bottomPadding = 10, topPadding = 10;
        float sidePadding = 10;
        if (mUseDips) {
            bottomPadding = mDipPadding;
            topPadding = mDipPadding;
            sidePadding = mDipPadding;
        }
        float usableHeight = getHeight() - bottomPadding - topPadding;
        float usableWidth = getWidth() - 2 * sidePadding;

        float maxY = getMaxLimY();
        float minY = getMinLimY();
        float maxX = getMaxLimX();
        float minX = getMinLimX();


        int lineCount = 0;
        for (Line line : mLines) {
            int count = 0;
            float lastXPixels = 0, newYPixels = 0;
            float lastYPixels = 0, newXPixels = 0;

            if (lineCount == mLineToFill) {
                // Draw lines
                mPaint.setColor(mFillColor);
                mPaint.setStrokeWidth(mStrokeWidth);
                for (int i = 10; i - getWidth() < getHeight(); i = i + mStrokeSpacing) {
                    mCanvas.drawLine(
                            i, getHeight() - bottomPadding,
                            0, getHeight() - bottomPadding - i, mPaint);
                }

                // Erase lines above the line
                mPaint.reset();
                mPaint.setXfermode(mXfermode);
                for (LinePoint p : line.getPoints()) {
                    float yPercent = (p.getY() - minY) / (maxY - minY);
                    float xPercent = (p.getX() - minX) / (maxX - minX);
                    if (count == 0) {
                        lastXPixels = sidePadding + (xPercent * usableWidth);
                        lastYPixels = getHeight() - bottomPadding - (usableHeight * yPercent);
                        mPath.moveTo(lastXPixels, lastYPixels);
                    } else {
                        newXPixels = sidePadding + (xPercent * usableWidth);
                        newYPixels = getHeight() - bottomPadding - (usableHeight * yPercent);
                        mPath.lineTo(newXPixels, newYPixels);
                        mPath.moveTo(lastXPixels, lastYPixels);
                        mPath.lineTo(newXPixels, newYPixels);
                        mPath.lineTo(newXPixels, 0);
                        mPath.lineTo(lastXPixels, 0);
                        mPath.close();
                        mCanvas.drawPath(mPath, mPaint);
                        lastXPixels = newXPixels;
                        lastYPixels = newYPixels;
                    }
                    count++;
                }

                mPath.reset();
                mPath.moveTo(0, getHeight() - bottomPadding);
                mPath.lineTo(sidePadding, getHeight() - bottomPadding);
                mPath.lineTo(sidePadding, 0);
                mPath.lineTo(0, 0);
                mPath.close();
                mCanvas.drawPath(mPath, mPaint);

                mPath.reset();
                mPath.moveTo(getWidth(), getHeight() - bottomPadding);
                mPath.lineTo(getWidth() - sidePadding, getHeight() - bottomPadding);
                mPath.lineTo(getWidth() - sidePadding, 0);
                mPath.lineTo(getWidth(), 0);
                mPath.close();

                mCanvas.drawPath(mPath, mPaint);
            }
            lineCount++;
        }

        // Draw x-axis line
        mPaint.reset();
        mPaint.setColor(mAxisColor);
        mPaint.setStrokeWidth(2 * getResources().getDisplayMetrics().density);
        mPaint.setAntiAlias(true);
        mCanvas.drawLine(
                sidePadding, getHeight() - bottomPadding,
                getWidth() - sidePadding, getHeight() - bottomPadding, mPaint);
        mPaint.reset();

        // Draw lines
        for (Line line : mLines) {
            int count = 0;
            float lastXPixels = 0, newYPixels = 0;
            float lastYPixels = 0, newXPixels = 0;

            mPaint.setColor(line.getColor());
            mPaint.setStrokeWidth(getStrokeWidth(line));

            for (LinePoint p : line.getPoints()) {
                float yPercent = (p.getY() - minY) / (maxY - minY);
                float xPercent = (p.getX() - minX) / (maxX - minX);
                if (count == 0) {
                    lastXPixels = sidePadding + (xPercent * usableWidth);
                    lastYPixels = getHeight() - bottomPadding - (usableHeight * yPercent);
                } else {
                    newXPixels = sidePadding + (xPercent * usableWidth);
                    newYPixels = getHeight() - bottomPadding - (usableHeight * yPercent);
                    mCanvas.drawLine(lastXPixels, lastYPixels, newXPixels, newYPixels, mPaint);
                    lastXPixels = newXPixels;
                    lastYPixels = newYPixels;
                }
                count++;
            }
        }

        // Draw points
        int pointCount = 0;
        for (Line line : mLines) {
            mPaint.setColor(line.getColor());
            mPaint.setStrokeWidth(getStrokeWidth(line));
            mPaint.setStrokeCap(Paint.Cap.ROUND);

            if (line.isShowingPoints()) {
                for (LinePoint p : line.getPoints()) {
                    float yPercent = (p.getY() - minY) / (maxY - minY);
                    float xPercent = (p.getX() - minX) / (maxX - minX);
                    float xPixels = sidePadding + (xPercent * usableWidth);
                    float yPixels = getHeight() - bottomPadding - (usableHeight * yPercent);

                    int outerRadius;
                    if (line.isUsingDips()) {
                        outerRadius = getPixelForDip(line.getStrokeWidth() + 4);
                    } else {
                        outerRadius = line.getStrokeWidth() + 4;
                    }
                    int innerRadius = outerRadius / 2;

                    mPaint.setColor(p.getColor());
                    mCanvas.drawCircle(xPixels, yPixels, outerRadius, mPaint);
                    mPaint.setColor(Color.WHITE);
                    mCanvas.drawCircle(xPixels, yPixels, innerRadius, mPaint);

                    // Create selection region
                    Path path = p.getPath();
                    path.reset();
                    outerRadius *= 2;
                    path.addCircle(xPixels, yPixels, outerRadius, Direction.CW);
                    p.getRegion().set((int) (xPixels - outerRadius),
                            (int) (yPixels - outerRadius),
                            (int) (xPixels + outerRadius),
                            (int) (yPixels + outerRadius));

                    // Draw selection
                    if (mSelectedIndex == pointCount && mListener != null) {
                        mPaint.setColor(p.getSelectedColor());
                        mCanvas.drawPath(p.getPath(), mPaint);
                        mPaint.setAlpha(255);
                    }

                    pointCount++;
                }
            }
        }
        canvas.drawBitmap(mFullImage, 0, 0, null);
    }

    private int getStrokeWidth(Line line) {
        int strokeWidth;
        if (line.isUsingDips()) {
            strokeWidth = getPixelForDip(line.getStrokeWidth());
        } else {
            strokeWidth = line.getStrokeWidth();
        }
        return strokeWidth;
    }

    private int getPixelForDip(int dipValue) {
        return (int) TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP,
                dipValue,
                getResources().getDisplayMetrics());
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        Point point = new Point();
        point.x = (int) event.getX();
        point.y = (int) event.getY();

        int count = 0;
        int lineCount = 0;
        int pointCount;

        Region r = new Region();
        for (Line line : mLines) {
            pointCount = 0;
            for (LinePoint p : line.getPoints()) {
                r.setPath(p.getPath(), p.getRegion());

                switch (event.getAction()) {
                    default:
                        break;
                    case MotionEvent.ACTION_DOWN:
                        if (r.contains(point.x, point.y)) {
                            mSelectedIndex = count;
                            postInvalidate();
                        }
                        break;
                    case MotionEvent.ACTION_UP:
                        if (count == mSelectedIndex
                                && mListener != null
                                && r.contains(point.x, point.y)) {
                            mListener.onClick(lineCount, pointCount);
                        }
                        break;
                }
                pointCount++;
                count++;
            }
            lineCount++;
        }
        // Reset selection
        if (MotionEvent.ACTION_UP == event.getAction()
                || MotionEvent.ACTION_CANCEL == event.getAction()) {
            mSelectedIndex = -1;
            postInvalidate();
        }
        return true;
    }

    public void setOnPointClickedListener(OnPointClickedListener listener) {
        this.mListener = listener;
    }

    public interface OnPointClickedListener {
        abstract void onClick(int lineIndex, int pointIndex);
    }
}




Java Source Code List

com.echo.holographlibrary.BarGraph.java
com.echo.holographlibrary.Bar.java
com.echo.holographlibrary.LineGraph.java
com.echo.holographlibrary.LinePoint.java
com.echo.holographlibrary.Line.java
com.echo.holographlibrary.PieGraph.java
com.echo.holographlibrary.PieSlice.java
com.echo.holographlibrary.Utils.java
com.trifork.ibeacon.ApplicationContext.java
com.trifork.ibeacon.ApplicationModule.java
com.trifork.ibeacon.BaseActivity.java
com.trifork.ibeacon.BaseApplication.java
com.trifork.ibeacon.BaseFragment.java
com.trifork.ibeacon.BootBroadcastReceiver.java
com.trifork.ibeacon.MainActivity.java
com.trifork.ibeacon.database.Dao.java
com.trifork.ibeacon.database.Database.java
com.trifork.ibeacon.database.RegionHistoryCursorLoader.java
com.trifork.ibeacon.database.RegionHistoryEntry.java
com.trifork.ibeacon.detectors.BeaconController.java
com.trifork.ibeacon.detectors.IBeaconParser.java
com.trifork.ibeacon.eventbus.FullScanCompleteEvent.java
com.trifork.ibeacon.eventbus.NewBeaconSelectedEvent.java
com.trifork.ibeacon.eventbus.OttoEvent.java
com.trifork.ibeacon.eventbus.RangeScanCompleteEvent.java
com.trifork.ibeacon.eventbus.RequestBeaconScanEvent.java
com.trifork.ibeacon.eventbus.RequestBeaconTransmit.java
com.trifork.ibeacon.eventbus.RequestFullScanEvent.java
com.trifork.ibeacon.eventbus.StopFullScanEvent.java
com.trifork.ibeacon.eventbus.StopScanEvent.java
com.trifork.ibeacon.eventbus.StopTransmitEvent.java
com.trifork.ibeacon.ui.BeaconDataFragment.java
com.trifork.ibeacon.ui.LocationFragment.java
com.trifork.ibeacon.ui.NotificationFragment.java
com.trifork.ibeacon.ui.RangingFragment.java
com.trifork.ibeacon.ui.RegionLogFragment.java
com.trifork.ibeacon.ui.ScanFragment.java
com.trifork.ibeacon.util.CircularBuffer.java
com.trifork.ibeacon.util.PersistentState.java
com.trifork.ibeacon.util.Utils.java
com.trifork.ibeacon.widgets.BeaconView.java
com.trifork.ibeacon.widgets.LocationTrackerView.java