2015-03-11 2 views
0

У меня проблема с отображением меток осей для нижней оси в TeeChart. Ярлыки осей в моем случае довольно длинны и представляют даты в формате dd.MM.yyyyУправление метками оси в TeeChart

В некоторых случаях, когда метки расположены близко друг к другу, они отображаются друг над другом (происходит перекрытие). Я добавляю метки к оси вручную для каждого значения N. Что я могу сделать, чтобы предотвратить совпадение?

Вторая проблема заключается в том, что часть первой метки иногда отображается слева от диаграммы. Так, вместо, например, 11.02.2015 пользователь может видеть только часть ярлыка, например. 2.2015 и т. Д. Как я могу обнаружить такие ситуации в моем коде?

Я попытался использовать AxisLabelResolver в моей диаграмме, но я столкнулся с проблемой, что методы AxisLabelResolver не вызываются. Что может быть причиной?

ответ

1

Используя пользовательские ярлыки, вы должны контролировать, при каких условиях метка должна или не должна быть нарисована. Перекрытие и ярлыки, частично вычеркнутые из прямоугольника диаграммы, являются примерами обычных ситуаций для контроля, но мы предпочитаем отдавать эту ответственность разработчику в таких настраиваемых инструментах.

Вы можете использовать это, чтобы узнать размер строки:

int tmpWidth = tChart1.getGraphics3D().textWidth(myLabel); 

Вы можете получить прямоугольник, определяемый осями с этим:

Rectangle tmpChartRect = tChart1.getChart().getChartRect(); 

Вы можете рассчитать положение в пикселях для значение оси с этим:

int tmpX = tChart1.getAxes().getBottom().calcPosValue(myXValue); 

Таким образом, вы можете скопировать список CustomLabels перед добавлением следующего один. То есть:

private void addXCustomLabel(double myXValue, String myLabel) { 
    boolean overlaps = false; 

    tChart1.getGraphics3D().setFont(tChart1.getAxes().getBottom().getLabels().getFont()); 
    int tmpWidth = tChart1.getGraphics3D().textWidth(myLabel); 
    int tmpX = tChart1.getAxes().getBottom().calcPosValue(myXValue) - tmpWidth/2; 

    for (int i=0; i<tChart1.getAxes().getBottom().getCustomLabels().size(); i++) { 
     AxisLabelItem tmpI =tChart1.getAxes().getBottom().getCustomLabels().getItem(i); 
     int tmpWidth2 = tChart1.getGraphics3D().textWidth(tmpI.getText()); 
     int tmpX2 = tChart1.getAxes().getBottom().calcPosValue(tmpI.getValue()) - tmpWidth2/2; 

     if (((tmpX>tmpX2) && (tmpX<tmpX2+tmpWidth2)) || 
      ((tmpX+tmpWidth>tmpX2) && (tmpX+tmpWidth<tmpX2+tmpWidth2)) || 
      ((tmpX<tmpX2) && (tmpX+tmpWidth>tmpX2+tmpWidth2))) { 
      overlaps = true; 
     } 
    } 

    Rectangle chartRect = tChart1.getChart().getChartRect(); 
    if ((!overlaps) && (tmpX>chartRect.x) && (tmpX+tmpWidth<chartRect.x+chartRect.width)) { 
     tChart1.getAxes().getBottom().getCustomLabels().add(myXValue, myLabel); 
    } 
} 

Единственная проблема здесь состоит в том, что calcPosValue нуждается в график, который можно сделать один раз, чтобы работать должным образом. И поскольку Android управляет ретрансляцией, трюк заключается в том, чтобы сделать это при событии chartPainted и удалить событие, выполняющее его, чтобы не повторять этот процесс. То есть:

private void createCustomLabels() { 

    tChart1.addChartPaintListener(new ChartPaintAdapter() { 

     @Override 
     public void chartPainted(ChartDrawEvent e) { 
      for (int i=0; i<tChart1.getAxes().getBottom().getMaximum(); i++) { 
       addXCustomLabel(i, "Value " + i + " here"); 
      } 
      tChart1.removeChartPaintListener(this); 
      tChart1.refreshControl(); 
     } 

    }); 

} 

Как вы заметили, AxisLabelResolver не вызывается для пользовательских меток. Это за дизайн.

+0

Спасибо! Оно работает! – Dennis