Используя пользовательские ярлыки, вы должны контролировать, при каких условиях метка должна или не должна быть нарисована. Перекрытие и ярлыки, частично вычеркнутые из прямоугольника диаграммы, являются примерами обычных ситуаций для контроля, но мы предпочитаем отдавать эту ответственность разработчику в таких настраиваемых инструментах.
Вы можете использовать это, чтобы узнать размер строки:
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 не вызывается для пользовательских меток. Это за дизайн.
Спасибо! Оно работает! – Dennis