TeeChart for Java (NetBeans, Eclipse, Android Studio, etc)
-
crni
- Newbie
- Posts: 10
- Joined: Fri Nov 09, 2012 12:00 am
Post
by crni » Fri Dec 14, 2012 2:53 pm
I am having problems with displaying monthly time step. I have 12 values on the chart and each of them is started on the first day of month, but for some reason some months are displayed twice in a row.
This is the code used the set the time step:
series.getXValues().setDateTime(true);
chart.getAxes().getBottom().setIncrement(DateTimeStep.ONEMONTH);
chart.getAxes().getBottom().getLabels().setDateTimeFormat("MMM");
The result shows labels on x axis like this:
Jan Feb Mar Apr Apr May Jun Jul Aug Sep Sep Oct Nov
Visually the combined range of 2 Aprils is twice as wide as single month.
How can I fix this to have all months be displayed once, and be of the same width?
-
Yeray
- Site Admin
- Posts: 9622
- Joined: Tue Dec 05, 2006 12:00 am
- Location: Girona, Catalonia
-
Contact:
Post
by Yeray » Fri Dec 14, 2012 4:24 pm
Hi,
The easiest will probably be to work with custom labels.
Ie, if all the values have the same separation between them, in X, you can use the same XValues:
Code: Select all
Bar bar1 = new Bar(tChart1.getChart());
bar1.getXValues().setDateTime(true);
DateTime XDate = new DateTime(2012,0,1); //January 1st, 2012
for (int i=1; i<=12; i++) {
bar1.add(XDate, i);
XDate.addMonths(1);
}
double XVal;
tChart1.getAxes().getBottom().getCustomLabels().clear();
for (int i=0; i<bar1.getCount(); i++) {
XVal = bar1.getXValues().getValue(i);
tChart1.getAxes().getBottom().getCustomLabels().add(XVal, new DateTime(XVal).toString("MMM"));
}
-
crni
- Newbie
- Posts: 10
- Joined: Fri Nov 09, 2012 12:00 am
Post
by crni » Tue Dec 18, 2012 1:11 pm
The problem is in spacing between labels. Labels tend to fall behind the values on the y axis.
Each label falls a bit further back from the actual value, althoug all the values are placed on 1th of every month. So every 4th or so label gets displayed twice.
I didnt really test the solution you provided, because I am guessing that it doesnt fix the spacing problem. Or am I wrong?
-
crni
- Newbie
- Posts: 10
- Joined: Fri Nov 09, 2012 12:00 am
Post
by crni » Tue Dec 18, 2012 2:00 pm
I tried your solution now, well, a version of it. It actually fixed the problem. I simply used the method getCustomLabels and added each date in the same loop where I am adding the actual values
Code: Select all
chart.getSeries(0).add(new DateTime(dataStore.getDataDatetime().getTime()), dataStore.getDoubleValue());
chart.getAxes().getBottom().getCustomLabels().add(dataStore.getDataDatetime().getTime(), new DateTime(dataStore.getDataDatetime().getTime()).toString("MMM"));
And at start I called this:
Code: Select all
and called tChart1.getAxes().getBottom().getCustomLabels().clear(); to start with.
So it now works. But it does look like a bug in the labels. Or am I missing something?
-
crni
- Newbie
- Posts: 10
- Joined: Fri Nov 09, 2012 12:00 am
Post
by crni » Wed Dec 19, 2012 8:23 am
With this solution I am now facing a different problem: the custom labels are always displayed, they are not automatically hidden when they overlap.
So as the chart is zoomed out, the labels are all over each other. Any solution to this?
-
Yeray
- Site Admin
- Posts: 9622
- Joined: Tue Dec 05, 2006 12:00 am
- Location: Girona, Catalonia
-
Contact:
Post
by Yeray » Thu Dec 20, 2012 10:52 am
Hi,
Excuse us for the delay here.
The inconvenient of the custom axis labels is the one you've noticed: the task to avoid the overlapping recalls to the developer.
A way to check the labels overlapping and only add the according, could be calling a method like this at
zoomed,
unzoomed and/or
scrolled events (ChartMotionListener):
Code: Select all
private static void addCustomLabels() {
Series s = tChart1.getSeries(0);
Axis a = tChart1.getAxes().getBottom();
double XVal;
String text;
int lastLabelRPos = -1;
a.getCustomLabels().clear();
for (int i=s.getFirstVisible(); i<=s.getLastVisible(); i++) {
XVal = s.getXValues().getValue(i);
text = new DateTime(XVal).toString("MMM yy");
if (lastLabelRPos == -1) {
a.getCustomLabels().add(XVal, text);
lastLabelRPos = a.calcPosValue(XVal) + (tChart1.getCanvas().textWidth(text) / 2);
}
else {
int actLabelLPos = a.calcPosValue(XVal) - (tChart1.getCanvas().textWidth(text) / 2);
if (lastLabelRPos < actLabelLPos) {
a.getCustomLabels().add(XVal, text);
lastLabelRPos = a.calcPosValue(XVal) + (tChart1.getCanvas().textWidth(text) / 2);
}
}
}
}
-
crni
- Newbie
- Posts: 10
- Joined: Fri Nov 09, 2012 12:00 am
Post
by crni » Thu Dec 27, 2012 8:20 am
Thank you, that solved the problem.
It would be nice to have this solution built in - anyone using custom labels would want it and it would've been a paint to do this on my own.
-
Yeray
- Site Admin
- Posts: 9622
- Joined: Tue Dec 05, 2006 12:00 am
- Location: Girona, Catalonia
-
Contact:
Post
by Yeray » Thu Dec 27, 2012 9:20 am
Hello,
At the moment, we think it's better if this kind of custom options are fully controlled by the developer. As soon as the component starts controlling them, the performance could be affected [1] and they won't be so customizable [2].
Ie [1], we could add a loop when the custom axis labels are going to be drawn, and skip drawing those that are going to overlap the others. However, it would be faster if this is checked just once, when the custom labels are added to the custom labels list.
Ie [2], some customers could agree this antioverlap system should start from the right (draw the most-right label and check the next label to draw avoiding the overlapping with this first), but some customers will probably prefer the system to start from the left.