Search code examples
javaandroidsimpledateformatline-breaksandroid-graphview

GraphView Horizontal Date Labels unable to Line Break


I am using the GraphView libary to draw graphs in an Android Application I am building.

The Graph uses dates for the x-axis. However, using DateFormat does not allow me to show on the horizontal label with a line break. Doing this will allow me to get more points and labels on the screen at a single time.

This is how the graph currently looks:

enter image description here

And this is how I want the labels on the graph to appear:

enter image description here

I am doing this by fetching the dates from a SQLite Database. I then convert them to Strings and store them in an array. The strings are then formatted to a SimpleDateFormat that contains a new line. I have debugged this several times and it is clear that each String in the array contains this new line. However, when setting the horizontal labels to this array of Strings it appears as it does in the first image not how I like it to be.

My code:

List<String> dates = new ArrayList<String>();
//getting the date Strings from the Sqlite Database
try {
    dates = db.getTimeDate();
} catch (ParseException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

//Creates the line break to add into string
String newline = System.getProperty("line.separator");

//Create date format that contains the line break
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yy"+newline+"HH:mm:ss");

//Iterate through arraylist formatting the string to new date format that contains linebreak 
for (int i = 0; i > dates.size(); i++) {
    String datad = dateFormat.format(dates.get(i));
    dates.set(i, datad);
}

final String[] _date = dates.toArray(new String[dates.size()]);

// make graphdata
List<GraphViewData> graphdata = new ArrayList<GraphViewData>();
for (int i = 0; i < dates.size(); i++) {
    graphdata.add(new GraphViewData(i, _time[i]));
}

GraphViewData[] _graphdata = graphdata
        .toArray(new GraphViewData[graphdata.size()]);

GraphViewSeries exampleSeries = new GraphViewSeries("", new GraphViewSeriesStyle(
        getResources().getColor(R.color.mathleteRed), 2), _graphdata);

GraphView graphView = new LineGraphView(this, "");
graphView.setLayoutParams(new LayoutParams(320, 200));
graphView.addSeries(exampleSeries); // data
graphView.getGraphViewStyle().setTextSize(
        getResources().getDimension((R.dimen.graph_text_size)));
graphView.getGraphViewStyle().setNumHorizontalLabels(5);
graphView.setScrollable(true);
graphView.setShowHorizontalLabels(true);
((LineGraphView) graphView).setDrawDataPoints(true);
((LineGraphView) graphView).setDataPointsRadius(4);

graphView.setCustomLabelFormatter(new CustomLabelFormatter() {
    public String formatLabel(double value, boolean isValueX) {
        if (isValueX) {
            // Assuming only 7 total values here
            return _date[(int) value];
        } else
            return String.format("%.2f", value);
    }
});

graphView.setViewPort(0, 4);
graphView.getGraphViewStyle().setHorizontalLabelsColor(
        getResources().getColor(R.color.white));

Any help would be great. I know the problem is not with the SQLite Database as I have debugged and tested it several times.


Solution

  • In the class GraphView.java the method drawHorizontalLabels is where the code must be added in order to line break. I have added another method in order to only line break if the horizontal labels is in date format, this way it wont break any labels that are not dates.

    protected void drawHorizontalLabels(Canvas canvas, float border,
            float horstart, float height, String[] horlabels, float graphwidth) {
    
        // horizontal labels + lines
        int hors = horlabels.length - 1;
        for (int i = 0; i < horlabels.length; i++) {
    
            paint.setColor(graphViewStyle.getGridColor());
            float x = ((graphwidth / hors) * i) + horstart;
            if (graphViewStyle.getGridStyle() != GridStyle.VERTICAL) {
                canvas.drawLine(x, height - border, x, border, paint);
            }
            if (showHorizontalLabels) {
                paint.setTextAlign(Align.CENTER);
                if (i == horlabels.length - 1)
                    paint.setTextAlign(Align.RIGHT);
                if (i == 0)
                    paint.setTextAlign(Align.LEFT);
                paint.setColor(graphViewStyle.getHorizontalLabelsColor());
    
    
        //this is where I have added code.
    
                if (HorDates == true) {
                    String[] Text = horlabels[i].split("\\s");
    
                    canvas.drawText(Text[1], x, height - 25, paint);
                    canvas.drawText(Text[0], x, height - 15, paint);
                } else {
                    canvas.drawText(horlabels[i], x, height - 25, paint);
                }
            }
        }
    }
    

    However this will only work if the date is formatted with a space between the Date and the Time like so: 11/12/14 01:21:40

    This way the code will split the label text into two strings at the space and then draw them separately one under another.

    there is also a simple set HorDates method:

    public void isHorLabDates(boolean _HorDates) {
        this.HorDates = _HorDates;
    }
    

    the horizontal labels now print in the canvas like so:

    11/12/14

    01:21:40