Search in sources :

Example 1 with Point2D

use of org.eazegraph.lib.models.Point2D in project EazeGraph by blackfizz.

the class ValueLineChart method onDataChanged.

/**
     * Should be called after new data is inserted. Will be automatically called, when the view dimensions
     * changed.
     *
     * Calculates various offsets and positions for different overlay features based on the graph settings.
     * After the calculation the Path is generated as a normal path or cubic path (Based on 'egUseCubic' attribute).
     */
@Override
protected void onDataChanged() {
    if (!mSeries.isEmpty()) {
        int seriesCount = mSeries.size();
        float maxValue = 0.f;
        float minValue = Float.MAX_VALUE;
        mNegativeValue = 0.f;
        mNegativeOffset = 0.f;
        mHasNegativeValues = false;
        // calculate the maximum and minimum value present in data
        for (ValueLineSeries series : mSeries) {
            for (ValueLinePoint point : series.getSeries()) {
                if (point.getValue() > maxValue)
                    maxValue = point.getValue();
                if (point.getValue() < mNegativeValue)
                    mNegativeValue = point.getValue();
                if (point.getValue() < minValue)
                    minValue = point.getValue();
            }
        }
        // check if the standardvalue is greater than all other values
        if (mShowStandardValues) {
            for (StandardValue value : mStandardValues) {
                if (value.getValue() > maxValue)
                    maxValue = value.getValue();
                if (value.getValue() < mNegativeValue)
                    mNegativeValue = value.getValue();
                if (value.getValue() < minValue)
                    minValue = value.getValue();
            }
        }
        if (!mUseDynamicScaling) {
            minValue = 0;
        } else {
            minValue *= mScalingFactor;
        }
        // check if values below zero were found
        if (mNegativeValue < 0) {
            mHasNegativeValues = true;
            maxValue += (mNegativeValue * -1);
            minValue = 0;
        }
        float heightMultiplier = mUsableGraphHeight / (maxValue - minValue);
        // calculate the offset
        if (mHasNegativeValues) {
            mNegativeOffset = (mNegativeValue * -1) * heightMultiplier;
        }
        // calculate the y position for standardValue
        if (mShowStandardValues) {
            for (StandardValue value : mStandardValues) {
                value.setY((int) (mGraphHeight - mNegativeOffset - ((value.getValue() - minValue) * heightMultiplier)));
            }
        }
        for (ValueLineSeries series : mSeries) {
            int seriesPointCount = series.getSeries().size();
            // check if more than one point is available
            if (seriesPointCount <= 1) {
                Log.w(LOG_TAG, "More than one point should be available!");
            } else {
                float widthOffset = (float) mGraphWidth / (float) seriesPointCount;
                widthOffset += widthOffset / seriesPointCount;
                float currentOffset = 0;
                series.setWidthOffset(widthOffset);
                // used to store first point and set it later as ending point, if a graph fill is selected
                float firstX = currentOffset;
                float firstY = mGraphHeight - ((series.getSeries().get(0).getValue() - minValue) * heightMultiplier);
                Path path = new Path();
                path.moveTo(firstX, firstY);
                series.getSeries().get(0).setCoordinates(new Point2D(firstX, firstY));
                // If not then just draw basic lines
                if (mUseCubic) {
                    Point2D P1 = new Point2D();
                    Point2D P2 = new Point2D();
                    Point2D P3 = new Point2D();
                    for (int i = 0; i < seriesPointCount - 1; i++) {
                        int i3 = (seriesPointCount - i) < 3 ? i + 1 : i + 2;
                        float offset2 = (seriesPointCount - i) < 3 ? mGraphWidth : currentOffset + widthOffset;
                        float offset3 = (seriesPointCount - i) < 3 ? mGraphWidth : currentOffset + (2 * widthOffset);
                        P1.setX(currentOffset);
                        P1.setY(mGraphHeight - ((series.getSeries().get(i).getValue() - minValue) * heightMultiplier));
                        P2.setX(offset2);
                        P2.setY(mGraphHeight - ((series.getSeries().get(i + 1).getValue() - minValue) * heightMultiplier));
                        Utils.calculatePointDiff(P1, P2, P1, mSecondMultiplier);
                        P3.setX(offset3);
                        P3.setY(mGraphHeight - ((series.getSeries().get(i3).getValue() - minValue) * heightMultiplier));
                        Utils.calculatePointDiff(P2, P3, P3, mFirstMultiplier);
                        currentOffset += widthOffset;
                        series.getSeries().get(i + 1).setCoordinates(new Point2D(P2.getX(), P2.getY()));
                        path.cubicTo(P1.getX(), P1.getY(), P2.getX(), P2.getY(), P3.getX(), P3.getY());
                    }
                } else {
                    boolean first = true;
                    int count = 1;
                    for (ValueLinePoint point : series.getSeries()) {
                        if (first) {
                            first = false;
                            continue;
                        }
                        currentOffset += widthOffset;
                        if (count == seriesPointCount - 1) {
                            // to prevent a graph drop
                            if (currentOffset < mGraphWidth) {
                                currentOffset = mGraphWidth;
                            }
                        }
                        point.setCoordinates(new Point2D(currentOffset, mGraphHeight - ((point.getValue() - minValue) * heightMultiplier)));
                        path.lineTo(point.getCoordinates().getX(), point.getCoordinates().getY());
                        count++;
                    }
                }
                if (mUseOverlapFill) {
                    path.lineTo(mGraphWidth, mGraphHeight);
                    path.lineTo(0, mGraphHeight);
                    path.lineTo(firstX, firstY);
                }
                series.setPath(path);
            }
        }
        if (calculateLegendBounds())
            Utils.calculateLegendInformation(mSeries.get(0).getSeries(), 0, mGraphWidth, mLegendPaint);
        // set the first point for the indicator
        if (mShowIndicator && mSeries.size() == 1) {
            int size = mSeries.get(0).getSeries().size();
            int index;
            // Only calculate if more than one point is available
            if (size > 1) {
                // position the indicator in the middle at the nearest value
                if (size == 3) {
                    index = size / 2;
                } else {
                    index = (size / 2) - 1;
                }
                mFocusedPoint = mSeries.get(0).getSeries().get(index);
                mTouchedArea = mFocusedPoint.getCoordinates();
                calculateValueTextHeight();
            }
        }
        resetZoom(false);
    }
    super.onDataChanged();
}
Also used : Path(android.graphics.Path) ValueLineSeries(org.eazegraph.lib.models.ValueLineSeries) Point2D(org.eazegraph.lib.models.Point2D) StandardValue(org.eazegraph.lib.models.StandardValue) ValueLinePoint(org.eazegraph.lib.models.ValueLinePoint) ValueLinePoint(org.eazegraph.lib.models.ValueLinePoint) Paint(android.graphics.Paint)

Aggregations

Paint (android.graphics.Paint)1 Path (android.graphics.Path)1 Point2D (org.eazegraph.lib.models.Point2D)1 StandardValue (org.eazegraph.lib.models.StandardValue)1 ValueLinePoint (org.eazegraph.lib.models.ValueLinePoint)1 ValueLineSeries (org.eazegraph.lib.models.ValueLineSeries)1