Search in sources :

Example 1 with StandardValue

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

the class ValueLineChart method onGraphOverlayDraw.

@Override
protected void onGraphOverlayDraw(Canvas _Canvas) {
    super.onGraphOverlayDraw(_Canvas);
    // draw x-axis
    mLegendPaint.setStrokeWidth(mXAxisStroke);
    _Canvas.drawLine(0, (mGraphHeight - mNegativeOffset) * Utils.getScaleY(mDrawMatrixValues) + Utils.getTranslationY(mDrawMatrixValues), mGraphWidth, (mGraphHeight - mNegativeOffset) * Utils.getScaleY(mDrawMatrixValues) + Utils.getTranslationY(mDrawMatrixValues), mLegendPaint);
    if (containsPoints()) {
        // draw standard value line
        if (mShowStandardValues) {
            mIndicatorPaint.setPathEffect(mDashPathEffect);
            for (StandardValue value : mStandardValues) {
                mIndicatorPaint.setColor(value.getColor());
                mIndicatorPaint.setStrokeWidth(value.getStroke());
                _Canvas.drawLine(0, value.getY() * Utils.getScaleY(mDrawMatrixValues) + Utils.getTranslationY(mDrawMatrixValues), mGraphWidth, value.getY() * Utils.getScaleY(mDrawMatrixValues) + Utils.getTranslationY(mDrawMatrixValues), mIndicatorPaint);
            }
        }
        // TODO: if mShowIndicator is true, then check all series not only if one series is inserted
        if (mShowIndicator && mSeries.size() == 1) {
            mIndicatorPaint.setPathEffect(null);
            mIndicatorPaint.setColor(mIndicatorLineColor);
            mIndicatorPaint.setStrokeWidth(mIndicatorWidth);
            _Canvas.translate(Utils.getTranslationX(mDrawMatrixValues), 0);
            _Canvas.drawLine(mTouchedArea.getX(), 0, mTouchedArea.getX(), mGraphHeight, mIndicatorPaint);
            if (mFocusedPoint != null) {
                // set shadow
                if (mActivateIndicatorShadow) {
                    mIndicatorPaint.setShadowLayer(mIndicatorShadowStrength, 0, 0, mIndicatorShadowColor);
                }
                mIndicatorPaint.setColor(mIndicatorTextColor);
                _Canvas.drawText(Utils.getFloatString(mFocusedPoint.getValue(), mShowDecimal) + (!mIndicatorTextUnit.isEmpty() ? " " + mIndicatorTextUnit : ""), mValueLabelX, mValueLabelY, mIndicatorPaint);
                if (mShowLegendBeneathIndicator) {
                    mLegendPaint.setColor(mIndicatorTextColor);
                    _Canvas.drawText(mFocusedPoint.getLegendLabel(), mLegendLabelX, mLegendLabelY, mLegendPaint);
                }
                // reset shadow
                if (mActivateIndicatorShadow) {
                    mIndicatorPaint.setShadowLayer(0, 0, 0, 0x00000000);
                }
            }
        }
    }
}
Also used : StandardValue(org.eazegraph.lib.models.StandardValue)

Example 2 with StandardValue

use of org.eazegraph.lib.models.StandardValue 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)

Example 3 with StandardValue

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

the class ValueLineChart method addStandardValue.

/**
     * Adds a standard value to the graph. The standard value is a horizontal line as an overlay
     * dependent on the loaded data set.
     * @param _standardValue The value which will be interpreted as a y-coordinate dependent
     *                       on the maximum value of the data set.
     */
public void addStandardValue(float _standardValue) {
    mStandardValues.add(new StandardValue(_standardValue));
    onDataChanged();
}
Also used : StandardValue(org.eazegraph.lib.models.StandardValue)

Aggregations

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