MarkerView不在图表的最后一个点上

时间:2015-05-11 13:44:33

标签: android charts mpandroidchart

我正在使用MarkerView类在图表中显示标记视图。我创建的markerview布局包含两个textview,一个在另一个之下。

我面临的问题是图表上最后一个点的标记视图是图表中的一半,而图表中的一半。下面的两张图片清楚地说明了问题:

第一张图片显示了图表中心点的标记视图,显示没有任何问题:

enter image description here

第二张图片,如下图所示,显示了图表最后一点的标记视图,它是图表中的一半。

enter image description here

如何调整此标记视图以使其在图表区域中显示。

wiki没有说明markerview的任何自定义。还有更多自定义吗?

此外,如果是多线图,如果我只点击其中一个线点,则标记视图没有问题。但是,如果我在另一行的任何点上单击标记视图,则应用程序将失败。不知道为什么会这样。

markerview类的代码如下:

public class TooltipView extends MarkerView {

private BaseGraphMetadata mBaseGraphMetadata;

private TextView mTooltipDate, mTooltipValue;

public TooltipView(Context context, int layoutResource, BaseGraphMetadata baseGraphMetadata) {
    super(context, layoutResource);
    mTooltipDate = (TextView)findViewById(R.id.tooltip_date);
    mTooltipValue = (TextView)findViewById(R.id.tooltip_value);
    mBaseGraphMetadata = baseGraphMetadata;
}

@Override
public void refreshContent(Entry entry, int i) {
    List<DrillDownInfo> drillDownInfoList = (List<DrillDownInfo>) entry.getData();
    DrillDownInfo drillDownInfo = drillDownInfoList.get(i);
    Map<String, String> group = drillDownInfo.getGroupByNameVsGroupByValue();
    Iterator iterator = group.entrySet().iterator();
    while (iterator.hasNext()) {
        Map.Entry pair = (Map.Entry)iterator.next();
        if(pair.getKey()!=null && pair.getValue()!=null) {
            String key = (String) pair.getKey();
            key = key.toUpperCase();
            Double value = Double.parseDouble((String) pair.getValue());
            String formattedValue = mBaseGraphMetadata.getDataFormatter().getFormattedValue(value);
            mTooltipDate.setText(key + " : " + formattedValue);
        }
        iterator.remove();
    }
    mTooltipValue.setText(String.valueOf("VALUE : "+entry.getVal()));
}

@Override
public int getXOffset() {
    return -(getWidth() / 2);
}

@Override
public int getYOffset() {
    return -getHeight();
}
}

7 个答案:

答案 0 :(得分:6)

由于

android:clipChildren="false"
android:clipToPadding="false"

对我来说不起作用,我最终创造了3种不同的绘图。根据Entry索引,我使用其中一个。并且,为了保持箭头居中,XOffset会相应地改变。我想这是一个非常具体的解决方案,但这个想法是可出口的

  @Override
  public void refreshContent(Entry e, int dataSetIndex) {
    if (e.getXIndex() < 4) {
      xOffsetMultiplier = 3.2f;
      tvContent.setBackgroundResource(R.drawable.stats_marker_left_side);
    } else if (e.getXIndex() > mTimestamps.length - 6) {
      //timestamps is an array containing xValues timestamps
      xOffsetMultiplier = 1.12f;
      tvContent.setBackgroundResource(R.drawable.stats_marker_right_side);
    } else {
      xOffsetMultiplier = 2;
      tvContent.setBackgroundResource(R.drawable.stats_marker);
    }

    tvContent.setText(createMarkerViewText(e));
  }

  @Override
  public int getXOffset() {
    // this will center the marker-view horizontally
    return (int) -(getWidth() / xOffsetMultiplier);
  }

这是结果

enter image description here enter image description here enter image description here

drawables从MPAndroidChart样本中复制,转换为9.patch并根据我的需要进行调整。将它们放在drawable-nodpi

enter image description here enter image description here enter image description here

答案 1 :(得分:6)

我找到了解决这个问题的简单方法。您需要在自定义标记视图中设置图表,如下所示:

setChartView(chart);

..并覆盖draw方法,如下所示:

@Override
public void draw(Canvas canvas, float posX, float posY) {
    super.draw(canvas, posX, posY);
    getOffsetForDrawingAtPoint(posX, posY);
}

答案 2 :(得分:5)

有点晚了,但这是我解决这个问题的简单方法。

您需要Override自定义draw的{​​{1}}方法。

您必须控制posx不会从您的某个边框关闭(从MarkerView右侧到位置,具体取决于您的屏幕尺寸,例如0我自己的屏幕。)

一个简单的例子:

300

在这里,我可以控制我的x位置,同时确保标记始终位于图表的顶部(如果你不想要它,请改用p @Override public void draw(Canvas canvas, float posx, float posy) { // take offsets into consideration posx += getXOffset(); posy=0; // AVOID OFFSCREEN if(posx<45) posx=45; if(posx>265) posx=265; // translate to the correct position and draw canvas.translate(posx, posy); draw(canvas); canvas.translate(-posx, -posy); }

答案 3 :(得分:3)

在你的MarkerView中添加一些逻辑。如果突出显示最后一个值,则getXOffset()方法应返回不同的值。

返回的内容是以refreshContent(...)方法计算的。

此外,您还可以查看以下xml属性:

android:clipChildren="false"
android:clipToPadding="false"

应为图表视图设置。

答案 4 :(得分:2)

我遇到了同样的问题。我通过制作我自己的customMarkerview课程来纠正它,特别是以下方法:

@Override
public int getXOffset(float xpos) {

    // this will center the marker-view horizontally
   int min_offset = 50;
    if (xpos < min_offset)
        return 0;

    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    DisplayMetrics metrics = new DisplayMetrics();
    wm.getDefaultDisplay().getMetrics(metrics);
    //For right hand side
    if (metrics.widthPixels - xpos < min_offset)
        return -getWidth();
            //For left hand side
    else if (metrics.widthPixels - xpos < 0)
        return -getWidth();
    return -(getWidth() / 2);
}

答案 5 :(得分:0)

最好的答案在于图书馆本身。从MarkerView检查方法getOffsetForDrawingAtPoint()。它定义了计算偏移量的完美方法。从那里使用该逻辑并使用自定义标记的onDraw方法,如下所示:

 @Override
    public void draw(Canvas canvas, float posX, float posY) {
        // take offsets into consideration
        int lineChartWidth = 0;
        float offsetX = getOffset().getX();
        posY=0;//fix at top
        float width = getWidth();

        if(lineChart != null) {
            lineChartWidth = lineChart.getWidth();
        }
        if(posX + offsetX < 0) {
            offsetX = - posX;
        } else if(posX + width + offsetX > lineChartWidth) {
            offsetX = lineChartWidth - posX - width;
        }
        posX += offsetX;
        // translate to the correct position and draw
        canvas.translate(posX, posY);
        draw(canvas);
        canvas.translate(-posX, -posY);
    }

答案 6 :(得分:0)

您可以通过添加chart.setDragOffsetX(50);来纠正此问题。这将在x轴上添加填充。因此,为标记视图的显示留出了空间。