robinhood/spark

Spark has trouble displaying time-series data

Azeirah opened this issue · 8 comments

I've got some data like this, using UNIX timestamps as x-values, and arbitrary values as y-values.

"dataPoints": {
   "1466546066": 2.0,
   "1466546068": 4.0,
   "1466546069": 2.0,
   "1466546070": 1.0,
   "1466546071": 3.0,
   "1466546072": 2.0,
   "1466546073": 4.0,
   "1466546304": 5.0,
   "1466546305": 4.0,
   "1466546306": 2.0,
   "1466546307": 3.0
}

The resulting sparkline looks like this, it really shouldn't look like that!

sparky

It could be that I'm doing something wrong, though the sparkline shows correctly when I use indices going from 0-10 instead of using timestamps

This is my adapter

public class TimedSparkAdapter extends SparkAdapter {

    private Double[] xData;
    private Double[] yData;

    public TimedSparkAdapter(Double[] xData, Double[] yData) {
        this.xData = xData;
        this.yData = yData;
    }

    @Override
    public int getCount() {
        return yData.length;
    }

    @Override
    public Double getItem(int index) {
        return yData[index];
    }

    @Override
    public float getY(int index) {
        return yData[index].floatValue();
    }

    @Override
    public float getX(int index) {
        return xData[index].floatValue();
    }
}

And this is what's in my layout

    <com.robinhood.spark.SparkView
        android:id="@+id/sparkline"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

Sorry for the delay! Was out on vacation.

I will look into this at some point this week. My first thought is perhaps a rounding issue since Spark is using floats for the x,y coords here. But those Y values look incorrect as well, so I'm not entirely sure.

I think for timestamps the view needs a different way to calculate the distances between the value points. Maybe a getX override method that needs a date object?

Ugh, sorry guys. I found out exactly why this graph appears the way it does.

My points on the x-line have a huge jump, notice halfway, instead of x-incrementing by 1 like it does all the time, it increments with ~230. Clumping all the first few values together on the left, and the other half on the right. I noticed this when I enlarged the graph by a lot.

  "1466546073": 4.0,
  "1466546304": 5.0,

graph

This library is working as expected, the data was at fault.

No worries, thanks for the follow up!

Thinking about it a bit more, even though this representation is technically correct, it's not very helpful to the viewer, is it? Should an alternative representation be used when cases like these are detected? Stem graphs would work a little bit better in this case for example.

The larger graph would look like this

stem-lg

The sparkstem could look like this, it's a lot clearer.

stem-sm

Not sure if it would be worth the time implementing all heuristics needed to decide what kind of plot to use however, I'm not even sure if that can be reliably done. Or if it is even within the scope of this project.

This seems outside of the scope of Spark to me, since it's no longer a sparkline chart. I also don't think many apps that use Spark would want this behavior. And as you mentioned, detecting this case reliably is quite difficult.

I think Spark should maintain the current behavior, and apps can use custom logic in their SparkAdapters to massage the data however they might want.

Thought so, thanks for taking the time to discuss this issue