首页 文章

MPAndroidChart中限制行的自定义视图

提问于
浏览
9

是否可以用自定义布局替换 LimitLine ?所以它看起来像这样:

enter image description here

我看到几个解决方案:

  • 也许库里面有像这样的自定义方法,有没有呢?

  • 获取存储值的 TextView 坐标,并在该位置添加自定义布局 . 但我怎么能达到这个 TextView

Perhaps someone faced that problem. Please share your experience.


EDIT: latest partial solution

经过长时间的搜索解决方案,我开始通过Limit Line的坐标以编程方式添加自定义视图 .

屏幕总体布局如下:

enter image description here

坐标计算非常简单 . X 从图表坐标和 Y 中得知:

Y =((max - lastValue)* height)/((max min)y)

所以在这一点上我基本上知道我需要的位置 . 虽然我'm not sure it'是正确的,因为父母 ScrollView .

下一步是在那些坐标处添加自定义布局 (x, y)

enter image description here

这是新的 problem . 我试图将视图添加到顶部 RelativeLayout . 它被添加但它不与 ScrollView 一起移动 . 因此,需要在Chart上添加该视图 . 看看我是如何尝试实现这一目标的:

private void addCustomLayoutOnLimitLine(final double lastValue) {

    mChart.post(new Runnable() { //check location when view is created
        public void run() {
            int[] chartLocationOnScreen = new int[2];
            mChart.getLocationOnScreen(chartLocationOnScreen);

            int x = chartLocationOnScreen[0];
            int y = chartLocationOnScreen[1];

            int width = mChart.getWidth();
            int height = mChart.getHeight();


            double max = mChart.getYMax();
            double min = mChart.getYMin();

            int limitXPoint = x + width;
            int limitYPoint = (int) ((((max - lastValue) * height) / (max + min))+ y);



            LayoutInflater inflater = (LayoutInflater)   getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            RelativeLayout rlValue = (RelativeLayout) inflater.inflate(R.layout.item_chart_value, null);
            TextView tvValue = (TextView) rlValue.findViewById(R.id.tv_value);
            tvValue.setText(String.valueOf(lastValue));

            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(50, 50);
            params.leftMargin = limitXPoint - 100;
            params.topMargin = limitYPoint;
            mChart.addView(rlValue, params); //this doesn't seem to be working
            rlValue.bringToFront();
        }
    });
}

也许我应该达到Chart的父布局并在那里膨胀我的自定义布局 . 但 how


EDIT 2: added custom view over chart but can't find proper location due to scroll view

现在情况看起来像这样:

enter image description here

也许我在计算中出错了 . 但至少该视图会改变其新值的位置,尽管它从未达到过正确的协调 .

private void addCustomLayoutOnLimitLine() {
    if (mChart == null){
        return;
    }

    mChart.post(new Runnable() { //check location when view is created
        public void run() {
            int[] chartLocationOnScreen = new int[2];
            mChart.getLocationOnScreen(chartLocationOnScreen);

            int xChart = chartLocationOnScreen[0];
            int yChart = chartLocationOnScreen[1];

            int chartWidth = mChart.getWidth();
            int chartHeight = mChart.getHeight();

            int rootWidth = rlSvContent.getWidth();
            int rootHeight = rlSvContent.getHeight(); //this is height of ScrollView

            int infoWidth = llInfoWrapper.getWidth(); //width of info panel ABOVE chart
            int infoHeight = llInfoWrapper.getHeight();

            double lastValue = mSingleAsset.getGraph().get(mSingleAsset.getGraph().size() - 1).getValue();
            double maxValue = mChart.getYMax();
            double minValue = mChart.getYMin();

            int limitXPoint = (rootWidth - chartWidth) / 2 + chartWidth;
            int limitYPoint = (int) ((maxValue - lastValue) * chartHeight/(maxValue - minValue)) + yChart;

            tvCustomValue.setText(SingleAsset.round((float) lastValue, 2).toString()); //display last value on custom view

            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            params.leftMargin = limitXPoint - xChart - 50; //move custom view. xChart = right margin value and 50 is taken to count values bar to the right of chart
            params.topMargin = limitYPoint;
            rlCustomValue.setLayoutParams(params);
            rlCustomValue.bringToFront();
            rlCustomValue.invalidate();
        }
    });
}

2 回答

  • 3
    <ScrollView>
    
        <LinearLayout/>
    
        <FrameLayout>
    
            <Chart/>
            <TextView/>
    
        <FrameLauyout>
    
    </ScrollView>
    

    使用ViewPortHandler获取图表的偏移量

    float offsetTop = mChart.getViewPortHandler().offsetTop();
        float offsetLeft = mChart.getViewPortHandler().offsetLeft();
        float offsetRight = mChart.getViewPortHandler().offsetRight();
        float chartHeight = mChart.getViewPortHandler().contentHeight();
    
  • 2

    这不是一个很好的方法 . 我通过扩展实际绘制标签的YAxisRenderer.java文件来完成它 . 它们不是视图,它们是在画布上绘制的 . 这是我的标签代码:

    `

    protected void drawYLabels(Canvas c, float fixedPosition, float[] positions, float offset) {
    
        // draw labels
        for (int i = 0; i < mYAxis.mEntryCount; i++) {
    
            String text = mYAxis.getFormattedLabel(i);
    
            if (!mYAxis.isDrawTopYLabelEntryEnabled() && i >= mYAxis.mEntryCount - 1)
                return;
    
            c.drawText(text, fixedPosition, positions[i * 2 + 1] + offset, mAxisLabelPaint);
        }
    
        // limitline labels
    
        List<LimitLine> limitLines = mYAxis.getLimitLines();
        float[] pts = new float[2];
        for (LimitLine l : limitLines) {
            Paint paint = new Paint();
            paint.setStyle(Paint.Style.FILL);
            paint.setColor(l.getTextColor());
    
            Paint textPaint = mAxisLabelPaint;
            textPaint.setColor(l.getLineLabelTextColor());
            textPaint.setTextSize(mAxisLabelPaint.getTextSize());
            textPaint.setPathEffect(null);
            textPaint.setTypeface(l.getTypeface());
            textPaint.setStrokeWidth(0.5f);
            textPaint.setStyle(l.getTextStyle());
    
            pts[1] = l.getLimit();
            mTrans.pointValuesToPixel(pts);
            float paddingVert = Utils.convertDpToPixel(3);
            float paddingHoriz = Utils.convertDpToPixel(5);
            float height = Utils.calcTextHeight(textPaint, l.getLabel());
            float width = Utils.calcTextWidth(textPaint, l.getLabel());
            float posY = pts[1] + height / 2;
    
            c.drawRect(fixedPosition - paddingHoriz, posY - height - paddingVert, fixedPosition + width + paddingHoriz*2, posY + paddingVert, paint);
            c.drawText(l.getLabel(), fixedPosition, posY, textPaint);
        }
    
    }
    

    `

    请注意,您必须使用 mTrans.pointValuesToPixel(pts) 将Y值转换为像素 .

相关问题