Using dates with the Graphview library
Asked Answered
C

4

10

I'm using GraphView library (see: https://github.com/jjoe64/GraphView or http://www.jjoe64.com/p/graphview-library.html)

But I would like to use Date/Time for the X-as. Does anyone knows a easy way to accomplish this or can anyone push me in the right direction?

Consanguineous answered 16/5, 2012 at 13:49 Comment(0)
T
2

GraphView is a great library to use, i find it the easiest as well. The first step in doing this would be to add a String Variable in the GraphViewData Class within GraphView.java. Like So:

static public class GraphViewData {
    public final double valueX;
    public final double valueY;
    public final String valueDate;

    public GraphViewData(double valueX, double valueY,String valueDate) {
        super();
        this.valueX = valueX;
        this.valueY = valueY;
        this.valueDate = valueDate;
    }
}

When you create your GraphViewData object when creating a GraphView Graph, you will need to add the date data in string form (along with the X and Y).

Lets say you have 80 data points in your graph (index 0 - 79). There is a method within GraphView that is responsible for generating and returning the horizontal labels, i believe its called generateHorLabels. Instead of just returning the X Value (0-79), Use the X value to get the String from the GraphData object.

In the code you have now, it should have the following in a for loop

labels[i] = formatLabel(min + ((max-min)*i/numLabels), true);

instead of the above, you could do something like this.

Double temp =  Double.valueOf(formatLabel(min + ((max-min)*i/numLabels), true));
int rounded =(int)Math.round(temp); 
labels[i] = values[rounded].valueDate;

Hope this helped!

Tug answered 16/5, 2012 at 21:6 Comment(4)
Thnx for your answer.. I will try this out today, and see if i can get it done today. I will probably accept the answer when i'm doneConsanguineous
Ye got it working with a lot of custom stuff, like popups when clicking a point and interface:)Consanguineous
What should be values[rounded].valueDate; ? The library doesn't recognize values objectHachmann
I used labels[i] = graphSeries.get(0).values[i].getDate();Grating
T
13

This is the correct way to do this

You just have to use the unix timestamp (seconds from 1.01.1970) as x value.

Then you can set a custom label formatter and convert the unix timestamp to a String:

final java.text.DateFormat dateTimeFormatter = DateFormat.getTimeFormat(mActivity);

LineGraphView graphView = new LineGraphView(mActivity, entry.getValue()) {
    @Override
    protected String formatLabel(double value, boolean isValueX) {
        if (isValueX) {
            // transform number to time
            return dateTimeFormatter.format(new Date((long) value*1000));
        } else {
            return super.formatLabel(value, isValueX);
        }
    }
};
Triceps answered 17/9, 2012 at 8:41 Comment(3)
Hi @jjoe64 your library is a great job. I'm trying to use it with dates as x axis as the OP of this question but I have a different problem. If the sequence of x values is not linear I get the graphview putting the values between the boundaries of the sequence in wrong places. This is, for {1, 3, 4}, it puts right 1 and 4, but not 3. I think I must fill all missing values (or give the ones that make the sequence linear) but seems to me like a bit ugly solution. Is there any other way to do this with your library that I'm not aware of? Thanks!Bobbee
hi. graphview does not care about your sequence of datas. it just generates the labels at the position for that label. there's no way to impact the positions of the labels. you maybe could do a workaround for your special case, take a look at static labels, or GraphViewStyle#setNumHorizontalLabelsTriceps
@jjoe64 i'm new to Android, so im confused now a little bit, i'm trying to use your offered piece of code, but i dont get it, what is entry.getValue() ? dl.dropboxusercontent.com/u/6151466/graphview.jpg this is the to my situation. Can you help me with this ? thanksNotability
T
2

GraphView is a great library to use, i find it the easiest as well. The first step in doing this would be to add a String Variable in the GraphViewData Class within GraphView.java. Like So:

static public class GraphViewData {
    public final double valueX;
    public final double valueY;
    public final String valueDate;

    public GraphViewData(double valueX, double valueY,String valueDate) {
        super();
        this.valueX = valueX;
        this.valueY = valueY;
        this.valueDate = valueDate;
    }
}

When you create your GraphViewData object when creating a GraphView Graph, you will need to add the date data in string form (along with the X and Y).

Lets say you have 80 data points in your graph (index 0 - 79). There is a method within GraphView that is responsible for generating and returning the horizontal labels, i believe its called generateHorLabels. Instead of just returning the X Value (0-79), Use the X value to get the String from the GraphData object.

In the code you have now, it should have the following in a for loop

labels[i] = formatLabel(min + ((max-min)*i/numLabels), true);

instead of the above, you could do something like this.

Double temp =  Double.valueOf(formatLabel(min + ((max-min)*i/numLabels), true));
int rounded =(int)Math.round(temp); 
labels[i] = values[rounded].valueDate;

Hope this helped!

Tug answered 16/5, 2012 at 21:6 Comment(4)
Thnx for your answer.. I will try this out today, and see if i can get it done today. I will probably accept the answer when i'm doneConsanguineous
Ye got it working with a lot of custom stuff, like popups when clicking a point and interface:)Consanguineous
What should be values[rounded].valueDate; ? The library doesn't recognize values objectHachmann
I used labels[i] = graphSeries.get(0).values[i].getDate();Grating
R
1

Here's the updated answer from jjoe64, with the x-values obtained from Date#getTime()

    final DateFormat dateTimeFormatter = DateFormat.getDateTimeInstance();        
    graphView = new LineGraphView(context, "Chart");
    graphView.setCustomLabelFormatter(new CustomLabelFormatter() 
    {
        @Override
        public String formatLabel(double value, boolean isValueX) 
        {
            if (isValueX)
            {
                return dateTimeFormatter.format(new Date((long) value));
            }
            return null; // let graphview generate Y-axis label for us
        }
    });
Radian answered 23/5, 2014 at 5:31 Comment(0)
T
0

I created the horizontal labels at the same time I was setting the values:

public void initializeLineGraphView() {

    // Get last weeks entries from the DB
    ArrayList<Entry> entries = DbManager.getInstance().getLastWeeksEntries(new Date());
    String[] hLabels = new String[entries.size()];
    GraphView.GraphViewData[] graphViewData = new GraphView.GraphViewData[entries.size()];

    for(int i = 0; i < entries.size(); i++) {

        Entry entry = entries.get(i);
        int pain = entry.getPain();
        graphViewData[i] = new GraphView.GraphViewData(i, pain);

        // Generate the horizontal labels
        SimpleDateFormat sdf = new SimpleDateFormat("EEE");
        String dayOfWeek = sdf.format(entry.getDate());
        hLabels[i] = dayOfWeek;

    }

    mSeries = new GraphViewSeries("", null, graphViewData);
    GraphView graphView = new LineGraphView(getActivity(), "");
    graphView.addSeries(mSeries);
    graphView.setHorizontalLabels(hLabels);
    graphView.setVerticalLabels(new String[] {"10", "5", "0"});
    mLineGraphView = graphView;

}
Tetrachord answered 28/5, 2014 at 13:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.