Reputation: 61
I using mpandroidchart library to plot candlestick chart, I am getting candlestick data from API. What I am trying to do now is:
When I have data on my chart I want to save it so that I can retrieve it later. So I am able to get the chart data using:
CombinedData data = new CombinedData();
data.setData(some_data);
So my data is not null! I want to save this data so that some time if I do not want to connect to API i can still access it. I know how to set this data to chart if I have it, and I can do that as follows:
chart.setData(data)
;
My challenge is how to save this data to SharedPreferences, of course I have a string knowledge of saving it as:
editor.putString("string", string);
But this time it is not a String, and I am not able to convert this data to string then save, then retrieve a string and convert it back to CombinedData.
So my question is how to save CombinedData then later retrieve it?
Someone might suggest that when getting data from API as arrayList just save it as arrayList. The thing is: CombinedData has some attributes that I want to be saved as well, attributes like candlestick colors, width, and more, so if I save as data it will be possible to get these attributes as well.
If shared preferences can not help, how then can I save this as a file, and retrieve that file back to CombinedData?
Upvotes: 0
Views: 63
Reputation: 10910
If you want to save a complex dataset to SharedPreferences, you can either save the attributes individually, or serialize the data (e.g. convert it to a JSON string) and save that.
There are a lot of possible sets of data in a CombineData
class, but here is an example of how to save just the LineData sets from it using the JSON approach.
For example, say you made a CombinedData
of just lines, using the following code
LineData ld = new LineData();
{
List<Entry> line_entries = new ArrayList<>();
for (int i = 0; i < 4; ++i) {
line_entries.add(new Entry(i, i + 1));
}
LineDataSet ldata = new LineDataSet(line_entries, "Line");
ld.addDataSet(ldata);
}
{
List<Entry> line_entries = new ArrayList<>();
for (int i = 0; i < 4; ++i) {
line_entries.add(new Entry(i+2, i + 4));
}
LineDataSet ldata = new LineDataSet(line_entries, "Base");
ld.addDataSet(ldata);
}
CombinedData data = new CombinedData();
data.setData(ld);
You could save this data as a JSON string using the following method.
private void saveData(CombinedData data) throws JSONException {
JSONObject json_data = new JSONObject();
// Lines
JSONArray lines = new JSONArray();
LineData ld = data.getLineData();
for(int i = 0; i < ld.getDataSetCount(); ++i) {
ILineDataSet d = ld.getDataSets().get(i);
JSONObject lineI = new JSONObject();
JSONArray lineEntries = new JSONArray();
int num_entries = d.getEntryCount();
for(int j = 0; j < num_entries; ++j) {
Entry e = d.getEntryForIndex(j);
JSONObject entry = new JSONObject();
entry.put("x", e.getX());
entry.put("y", e.getY());
// Add other entry attributes you care about here
lineEntries.put(entry);
}
lineI.put("entries", lineEntries);
lineI.put("label", d.getLabel());
// Add other data set attributes you care about here
lines.put(lineI);
}
json_data.put("lines", lines);
SharedPreferences prefs = getSharedPreferences("MY_PREFS", Context.MODE_PRIVATE);
SharedPreferences.Editor ed = prefs.edit();
ed.putString("CombinedData", json_data.toString());
ed.apply();
}
This will save a string like the following
{
"lines":[
{
"entries":[{"x":0,"y":1},{"x":1,"y":2},{"x":2,"y":3},{"x":3,"y":4}],
"label":"Line"
},
{
"entries":[{"x":2,"y":4},{"x":3,"y":5},{"x":4,"y":6},{"x":5,"y":7}],
"label":"Base"
}
]
}
And you can load it and rebuild the CombinedData like this
private CombinedData loadData() throws JSONException {
SharedPreferences prefs = getSharedPreferences("MY_PREFS", Context.MODE_PRIVATE);
String json_string = prefs.getString("CombinedData", "{}");
JSONObject json_data = new JSONObject(json_string);
LineData ld = new LineData();
JSONArray lines = json_data.getJSONArray("lines");
for(int i = 0; i < lines.length(); ++i) {
JSONObject lineI = lines.getJSONObject(i);
JSONArray entries = lineI.getJSONArray("entries");
List<Entry> line_entries = new ArrayList<>();
for(int j = 0; j < entries.length(); ++j) {
JSONObject objJ = entries.getJSONObject(j);
line_entries.add(new Entry((float)objJ.getDouble("x"), (float)objJ.getDouble("y")));
}
String label = lineI.getString("label");
LineDataSet ldata = new LineDataSet(line_entries, label);
ld.addDataSet(ldata);
}
CombinedData data = new CombinedData();
data.setData(ld);
return data;
}
Since you are building the CombinedData
in your code, you could also just build the JSON string using the raw data you used to build the CombinedData
in the first place. If you store the data you need in your own class, you can use something like GSON to serialize and deserialize your class more easily than the manual approach above too.
CombinedData can contain a lot of different data types, so you will probably want to tailor this to the types you care about (for example, no need to serialize BarData if you never plan to have BarData in your plot).
Upvotes: 1