MPAndroidChart中限制线的自定义视图

MPAndroidChart中限制线的自定义视图,android,mpandroidchart,Android,Mpandroidchart,是否可以用自定义布局替换LimitLine?看起来是这样的: 我认为这方面的解决方案很少: 也许库中有这样的定制方法,有吗 获取存储值的TextView的坐标,并在该位置添加自定义布局。但我如何才能访问此TextView 也许有人遇到了这个问题。请分享您的经验。 编辑:最新的部分解决方案 在对解决方案进行了长时间的搜索之后,我找到了通过限制线坐标以编程方式添加自定义视图的方法 屏幕的总体布局如下所示: 坐标的计算非常简单X由图表坐标和Y可知: Y=((最大-最新值)*高度)/((最大+最小

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

我认为这方面的解决方案很少:

  • 也许库中有这样的定制方法,有吗
  • 获取存储值的
    TextView
    的坐标,并在该位置添加自定义布局。但我如何才能访问此
    TextView
  • 也许有人遇到了这个问题。请分享您的经验。


    编辑:最新的部分解决方案

    在对解决方案进行了长时间的搜索之后,我找到了通过限制线坐标以编程方式添加自定义视图的方法

    屏幕的总体布局如下所示:

    坐标的计算非常简单<代码>X由图表坐标和
    Y
    可知:

    Y=((最大-最新值)*高度)/((最大+最小)+Y)

    所以在这一点上,我基本上知道我需要的位置。尽管我不确定它是否正确,因为父级
    ScrollView

    下一步是在这些坐标
    (x,y)

    新的问题来了。我试图将视图添加到top
    RelativeLayout
    。它已添加,但不会与
    滚动视图一起移动。因此,需要将该视图准确地添加到图表中。看看我是如何做到这一点的:

    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();
            }
        });
    }
    
    也许我应该到达图表的父布局并在那里膨胀我的自定义布局。但是怎么做呢


    编辑2:在图表上添加了自定义视图,但由于滚动视图而找不到正确的位置

    现在情况是这样的:

    也许我的计算有点错误。但至少这个观点用新的价值观改变了它的立场,尽管它从来并没有达到正确的协调

    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();
            }
        });
    }
    

    这不是一个好办法。我通过扩展YAxisRenderer.java文件完成了这项工作,在该文件中实际绘制了标签。它们不是视图,而是在画布上绘制的。以下是我的标签代码:

    `

    受保护的空心DrawyLabel(画布c、浮动固定位置、浮动[]位置、浮动偏移){
    //画标签
    对于(int i=0;i=mYAxis.mEntryCount-1)
    返回;
    c、 drawText(文本,固定位置,位置[i*2+1]+偏移量,MaxIsLabelPoint);
    }
    //限制线标签
    List limitLines=mYAxis.getLimitLines();
    浮动[]分=新浮动[2];
    用于(限制线l:限制线){
    油漆=新油漆();
    绘制.设置样式(绘制.样式.填充);
    setColor(l.getTextColor());
    Paint textPaint=mAxisLabelPaint;
    setColor(l.getLineLabelTextColor());
    textPaint.setTextSize(mAxisLabelPaint.getTextSize());
    textPaint.setPathEffect(null);
    setTypeface(l.getTypeface());
    textPaint.设定行程宽度(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());
    浮动位置=点[1]+高度/2;
    c、 drawRect(固定位置-填充孔,位置-高度-填充垂直,固定位置+宽度+填充孔*2,位置+填充垂直,油漆);
    c、 drawText(l.getLabel()、fixedPosition、posY、textPaint);
    }
    }
    
    `


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

    谢谢,这是有用的信息。将有助于将视图定位在正确的位置末端\右侧。但是自上而下分配的问题仍然存在。为什么?您可以获得偏移顶部和偏移底部。我稍后会尝试一下,并留下反馈
    offsetTop()
    返回0,因为图表被包装在父布局中。无论如何,您的回答很有帮助,赏金就是您的了。float chartHeight=mChart.getViewPortHandler().contentHeight();不是mChart.getHeight()。也是mChart.getHeight()-mChart.getViewPortHandler().offsetBottom()。感谢您的回复。你能展示一下这个方法的使用示例吗?我发布的代码是对mpandroidchart本身的修改。修改后,您只需在应用程序中添加限制行,此代码将在您添加的每个限制行上添加一个标签,颜色与您在限制行上设置的颜色相同。创建您的行:
    ll=新限制行(限制、标签);ll.setLineColor(…);yourChart.getAxisRight().addLimitLine(ll)
    
    <ScrollView>
    
        <LinearLayout/>
    
        <FrameLayout>
    
            <Chart/>
            <TextView/>
    
        <FrameLauyout>
    
    </ScrollView>
    
        float offsetTop = mChart.getViewPortHandler().offsetTop();
        float offsetLeft = mChart.getViewPortHandler().offsetLeft();
        float offsetRight = mChart.getViewPortHandler().offsetRight();
        float chartHeight = mChart.getViewPortHandler().contentHeight();
    
    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);
        }
    
    }