본문 바로가기
개발/android

초간단 꺽은선 그래프 만들기

by 매몰 2016. 4. 25.

그래프는 텍스트로 표현하기 복잡한 정보를 한결 보기좋게 만드는 매력이 있다.

그래서 간편함의 상징인 모바일에서는 빠질수 없는 요소이다.

 

특히 많이 쓰이는 것이 막대 그래프와 꺽은선 그래프 일것이다.

그런데 꺽은선 그래프는 선이 하나로 이어져 있기 때문에 만드는데 애를 먹을때가 있다

 

그때를 대비해 초간단 꺽은선 그래프뷰를 만들어 놓자~ 

구미에 맞게 확장해서 쓰면 매우 유용하다

 

 

public class GraphView extends View {

    private ShapeDrawable mLineShape;
    private Paint mPointPaint;

    private float mThickness;
    private int[] mPoints, mPointX, mPointY;
    private int mPointSize, mPointRadius, mLineColor, mUnit, mOrigin, mDivide;

    public GraphView(Context context, AttributeSet attrs) {
        super(context, attrs);

        setTypes(context, attrs);
    }

    //그래프 옵션을 받는다
    private void setTypes(Context context, AttributeSet attrs) {
        TypedArray types = context.obtainStyledAttributes(attrs, R.styleable.GraphView);

        mPointPaint = new Paint();
        mPointPaint.setColor(types.getColor(R.styleable.GraphView_pointColor, Color.BLACK));
        mPointSize = (int)types.getDimension(R.styleable.GraphView_pointSize, 10);
        mPointRadius = mPointSize / 2;

        mLineColor = types.getColor(R.styleable.GraphView_lineColor, Color.BLACK);
        mThickness = types.getDimension(R.styleable.GraphView_lineThickness, 1);
    }

    //그래프 정보를 받는다
    public void setPoints(int[] points, int unit, int origin, int divide) {
        mPoints = points;   //y축 값 배열

        mUnit = unit;       //y축 단위
        mOrigin = origin;   //y축 원점
        mDivide = divide;   //y축 값 갯수
    }

    //그래프를 만든다
    private void draw() {
        Path path = new Path();

        int height = getHeight();
        int[] points = mPoints;

        //x축 점 사이의 거리
        float gapx = (float)getWidth() / points.length;

        //y축 단위 사이의 거리
        float gapy = (height - mPointSize) / mDivide;

        float halfgab = gapx / 2;

        int length = points.length;
        mPointX = new int[length];
        mPointY = new int[length];

        for(int i = 0 ; i < length ; i++) {
            //점 좌표를 구한다
            int x = (int)(halfgab + (i * gapx));
            int y = (int)(height - mPointRadius - (((points[i] / mUnit) - mOrigin) * gapy));

            mPointX[i] = x;
            mPointY[i] = y;

            //선을 그린다
            if(i == 0)
                path.moveTo(x, y);
            else
                path.lineTo(x, y);
        }

        //그려진 선으로 shape을 만든다
        ShapeDrawable shape = new ShapeDrawable(new PathShape(path, 1, 1));
        shape.setBounds(0, 0, 1, 1);

        Paint paint = shape.getPaint();
        paint.setStyle(Paint.Style.STROKE);
        paint.setColor(mLineColor);
        paint.setStrokeWidth(mThickness);
        paint.setAntiAlias(true);

        mLineShape = shape;
    }

    //그래프를 그린다(onCreate 등에서 호출시)
    public void drawForBeforeDrawView() {
        //뷰의 크기를 계산하여 그래프를 그리기 때문에 뷰가 실제로 만들어진 시점에서 함수를 호출해 준다
        getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                draw();

                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN)
                    getViewTreeObserver().removeGlobalOnLayoutListener(this);
                else
                    getViewTreeObserver().removeOnGlobalLayoutListener(this);
            }
        });
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        //선을 그린다
        if(mLineShape != null)
            mLineShape.draw(canvas);

        //점을 그린다
        if(mPointX != null && mPointY != null) {
            int length = mPointX.length;
            for (int i = 0; i < length; i++)
                canvas.drawCircle(mPointX[i], mPointY[i], mPointRadius, mPointPaint);
        }
    }
}

 

 

그래프 옵션을 위해 attrs.xml 에도 다음을 추가한다

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="GraphView">
        <attr name="pointColor" format="color"/>
        <attr name="pointSize" format="dimension"/>

        <attr name="lineColor" format="color"/>
        <attr name="lineThickness" format="dimension"/>
    </declare-styleable>
</resources>

 

 

다 만들어 졌으니 사용해 보자

 

Layout 에 그래프뷰를 추가~

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:gyjmoble="http://schemas.android.com/apk/res/kr.gyjmoble.graphtest"
    android:layout_width="match_parent" android:layout_height="match_parent">

    <kr.gyjmoble.graphtest.GraphView android:id="@+id/GraphView"
        android:layout_width="match_parent" android:layout_height="match_parent"
        gyjmoble:pointColor="#ec4800" gyjmoble:pointSize="8dp"
        gyjmoble:lineColor="#0073cc" gyjmoble:lineThickness="2dp"/>

</LinearLayout>

 

 

 

Activity 에선 그래프를 그리자~

 

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    //그래프에 들어갈 점 배열
    int[] points = {5, 3, 7, 8, 4, 3, 3, 6, 4, 1};

    GraphView graphview = (GraphView) findViewById(R.id.GraphView);

    //단위는 1씩, 원점은 0, 총 10줄로 나누어진 그래프를 그린다
    graphview.setPoints(points, 1, 0, 10);
    graphview.drawForBeforeDrawView();
}

 

이렇게 나온다~

 

 

 

 

 

 

 

도움이 되셨다면~ 정성으로 빚은 저희 앱!  많은 이용 바래요:)

 

https://meorimal.com/index.html?tab=spaceship

 

우주선 - 방치형 인공지능 투자 체험기

미리 맛보는 인공지능 투자!

(주)머리말 meorimal.com

 

https://meorimal.com/subway.html

 

지하철어디있니

더이상 고민하지 마세요. 뛸지 말지 딱 보면 알죠.

(주)머리말 meorimal.com

 

 

사업자 정보 표시
주식회사 머리말 | 고영진 | 서울특별시 송파구 중대로 135 서관 10층 (가락동, 아이티벤처타워) | 사업자 등록번호 : 524-88-00727 | TEL : 010-9990-3674 | Mail : gyjmeba@hanmail.net | 통신판매신고번호 : 2017-서울강남-03941호 | 사이버몰의 이용약관 바로가기