I've implemented AndroidPlot in my app and it works fine however I need the first value one step after origin since the date is not clear.
I tried the suggested solution in the asked questions here where they add the setDomainValueFormat method however error message displays:
"method can't resolve "
Any suggestion how to start x axis domain one step after origin?
plot = (XYPlot) findViewById(R.id.plot);
XYSeries series = new SimpleXYSeries(Arrays.asList(dates_in_m_seconds), Arrays.asList(values_as_numbers), "BP Status");
LineAndPointRenderer and configure them
LineAndPointFormatter seriesFormat = new LineAndPointFormatter(Color.RED, Color.GREEN,null, null);
plot.addSeries(series, seriesFormat);
// Specify x and y axes labels amount
plot.setRangeStep(StepMode.SUBDIVIDE,3);
plot.setDomainStep(StepMode.SUBDIVIDE,dates.size());
plot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.BOTTOM).setFormat(new Format() {
@Override
public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
Date date_Label = new Date(Math.round(((Number) obj).doubleValue()));
return format.format(date_Label, toAppendTo, pos);
}
@Override
public Object parseObject(String source, ParsePosition pos) {
return null;
}
});
plot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.LEFT).setFormat(new Format() {
@Override
public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
Number num = (Number) obj;
switch (num.intValue()) {
case 0:
toAppendTo.append("Low");
break;
case 1:
toAppendTo.append("Normal");
break;
case 2:
toAppendTo.append("High");
break;
default:
toAppendTo.append("Unknown");
break;
}
return toAppendTo;
}
@Override
public Object parseObject(String source, ParsePosition pos) {
return null;
}
});
}
There are a few ways you can approach this problem. On the surface, it seems like maintaining strict uniform spacing between xVals is desirable, however because your xVals are not only timestamps but are rounded versions of the raw inputs, you're only going to get an approximately uniform spacing. If you want to fully solve that problem you could instantiate your XYSeries using Y_VALS_ONLY and then use dates_as_m_seconds as a lookup table to render labels in your domain Format instance.
Having said that, I've included a solution that should work with your existing code. I didnt try to compile or run it so there might be typos, but the general idea will work:
Code:
// this value must be final in order to be visible to the anonymous inner class instance
// of Format below. Note that this will fail miserably if you try to plot a series of
// size < 2.
final double firstX = Math.round(((Number) series.getX(0)).doubleValue());
double secondX = Math.round(((Number) series.getX(1)).doubleValue());
double lastX = Math.round(((Number) series.getX(series.size() - 1)).doubleValue());
// assuming the step interval is uniform, this is the distance between each xVal:
double stepInterval = secondX - firstX;
// add in extra space for the first "invisible index" by setting the starting
// domain boundary exactly one interval before the first actual element:
plot.setDomainBoundaries(firstX - stepInterval, lastX, BoundaryMode.FIXED);
// add an extra "invisible index":
plot.setDomainStep(StepMode.SUBDIVIDE,dates.size() + 1);
...
plot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.BOTTOM).setFormat(new Format() {
@Override
public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
double timestampMs = Math.round(((Number) obj).doubleValue());
// only render indices corresponding to values in the series:
if(timestampMs >= firstX) {
Date date_Label = new Date();
return format.format(date_Label, toAppendTo, pos);
}
}
@Override
public Object parseObject(String source, ParsePosition pos) {
return null;
}
});