robinhood / spark Goto Github PK
View Code? Open in Web Editor NEWA simple Android sparkline chart view.
License: Apache License 2.0
A simple Android sparkline chart view.
License: Apache License 2.0
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!
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" />
how to set shadow for when chart get low?!?!
I don't know if it is a bug, but the baseline is not show until you overwrite hasBaseline().
Hi guys,
First of all - great work! I have started using Spark in my project and love it.
I was wondering if you guys have "Spark" for iOS too that you are planning to open source or are you using something else for iOS?
Thanks,
Damian
Is there a method to notify the adapter to update only for specific new data, which works like RecyclerView.Adapter.notifyItemChanged(int position) ?
If I call adapter.notifyDataSetChanged();
after adding a new data to the data set, the view will be refreshed completely and the animation will start from the first index of the data set instead of only the last inserted data (I enabled the animation changes).
Thank you.
How do we define a fill color ? I am trying to create a graph with white line and gradient fill color ..so trying to override the SparkView , but it not able to do so ! Help
I've drawn a graph with pulse shape from a csv file, the csv has at least 1000 data point to draw but I send only 250 to the data float[] that shows on the sparkview adapter.
Now I need this graph to became dynamic, so it has to shift rightward showing new data and hiding the old data (showed at beggining on the left side), but containing the same data amount showed (250 x points).
Does any of your methods work in this way?
Thanks in advance.
Will there be a new release soon, the current version (1.2.0) doesn't seem to work with fillType
And the code hosted here appears to be much more up to date
Capturing from @naturalwarren, The annotations introduced in #55 are useful and we could expand on this with the addition of other annotations on the public APIs.
the animation library is using annotations of android support library which needs to be upgraded to androidx for animations to work.
Hello,
Thank you for this great and easy to use library!
I was wondering how I can use SparkAdapter to it's full extent.
I have both X and Y value with Y being the price of the asset, and X the time.
When the sparkline is clicked and onScrubbed is triggered I want to update the scrubInfoTextView with both values of X and Y. I am not too certain how to do that using the spark adapter.
public class AssetAdapter extends SparkAdapter {
private float[] yData;
public float[] xData;
public CryptoAdapter(float[] yData) {
this.yData = yData;
}
@Override
public int getCount() {
return yData.length;
}
@Override
public Object getItem(int index) {
return yData[index];
}
@Override
public float getY(int index) {
return yData[index];
}
@Override
public float getX(int index) { return xData[index];}
}
public void setupSpark()
{
sparkView = findViewById(R.id.sparkview);
sparkView.setAdapter(adapter);
sparkView.setScrubListener(new SparkView.OnScrubListener()
{
@Override
public void onScrubbed(Object value) {
if (value == null) {
scrubInfoTextView.setText(R.string.scrub_empty);
} else {
scrubInfoTextView.setText(getString(R.string.scrub_format, value));
}
}
});
sparkView.setScrubLineWidth(0);
sparkView.setScrubLineColor( getResources().getColor(R.color.colorPrimaryDark) );
scrubInfoTextView = findViewById(R.id.scrub_info_textview);
}
In the SparkView class, there is a method: public void onScrubbed(float x, float y)
but when I try to override it cannot find that method.
I want to add integer for y-axis and date for x-axis. Is it possible to do that? If not, is it hard to add this functionality? Thanks.
First of all congratulations on this amazing resource that spark is.
I wish I could put the X Value along with the Y Value on the Scrubbing call but I don't know how to do it.
Thanks!
So I have never opened an issue to thank on github, I thought this might be a bad idea and people might be angry at me for using issue for these kind of things. But I got a feeling that this project deserves an alteration to the conventions.
Most of the time we need just the simple, beautiful and peaceful stuffs just like lying upside in the middle of lake(thats how I define peace) and this library is one of those. And this looks like that library I am going to use in every single graphing project.
I hope I will be able to contribute to this project also once I find some shortcomings, but for now it's amazing.
Thank you again, the team @robinhood
Does the library support showing max and min values from a given data set onto the sparkView? Something similar to what the Coinbase android app does?
I am attaching an image below:
In the image we can see two bubbles which denote the high and lows for the selected day.
Any recommendation on how to achieve it?
Thanks!
Can the scrubbing be made into a button instead of a vertical line? I want to be able to get the values as the user touches the graph( not drag on the graph) and keep that value displayed.
When you initialize the scrubPaint you use this:
sparkLinePaint.setStrokeWidth(lineWidth);
It should be using the scrubLineWidth variable instead.
Thanks for the great library! :)
I am getting this error in my app (xml below), but not in the sample app. I have even copied and pasted the code from the sample app into my own, and I get the same error. I have tried cleans, rebuilds, and restarting and I can't get it to recognize the attribute. It also is not recognizing it when I try to do it programmatically, even though it seems to be defined in the source code. I also double check and made sure I'm running the same version as the sample app (1.2.0).
I'm not sure if I'm just missing something or what, it seems like it should be fairly straightforward to do.
Thanks!
`
<com.robinhood.spark.SparkView
android:id="@+id/todayHourlyTemps"
android:layout_width="wrap_content"
android:layout_height="100dp"
app:spark_lineColor="@color/colorPrimary"
app:spark_lineWidth="5dp"
app:spark_scrubEnabled="true"
app:spark_fill="true"
app:spark_fillColor="@color/colorPrimaryTransparent"
android:layout_centerHorizontal="true" />
`
More use-cases are popping up with specific effects in mind. I'd like to make Spark able to handle these specific effects for folks more easily than either adding special cases and attributes for them in SparkView itself, or having to request them to subclass SparkView and do manual drawing.
A pluggable solution with a way for folks to easily override just the drawing of the spark should be a great first step.
Is it possible to create a fill gradient for spark instead of filling with a solid color?
Anyway to add a down fill gradient without the line color following it down.
When we set cornerRadius to a non-zero value, CornerPathEffect
is applied which works great until you apply a fill to the graph which results in:
I think rather than closing the path, if a fill is applied, on line 274 we should manually enclose the path first by hitting the bottom right corner of the view, then bottom left, and finally back to the starting position. I'm also wondering if we could make this paticuliar closing path "invisible" rather than showing the sparkline path closing the graph.
Can i take double datatype in the Y axis . because my value in y axis is more than 8 digits .
My Value (12845678.46)
Right now i am getting (1.2645678E7) when i am scrubbing the SparkView.
Whenever all items in the adapter supply one Y value, nothing gets drawn. I expected (and I think the "correct" behavior would be) a straight line to be drawn.
Also, as an extra; I do believe that having one point with a value should also draw a straight line, or at least a dot to indicate that there is something. The former can be achieved by adding two points, still thought Id mention it though.
I see that when I animate a filled graph using line animator, it animates the graph from the starting point of the graph and android draws it in a "zig-zag" way - see the gif attached.
I would like it to almost reveal from left to right instead of this zig-zag animation. If the graph was not filled, the animation works correctly. How so does the animation not work correctly when the fill is on?
Also if you look at the base of the graph, you will see that there is a boundary line at the place where the fill stops. I have not set baseline on the graph so not sure why this is showing and I really want this to disappear. Is there any way to do it?
I don't know whether you guys want to support this or not. I was just playing around with it and wanted to mentioned it. This can be achieved by the code below:
diff --git a/spark/src/main/java/com/robinhood/spark/SparkView.java b/spark/src/main/java/com/robinhood/spark/SparkView.java
index 505b14f..5d99c21 100644
--- a/spark/src/main/java/com/robinhood/spark/SparkView.java
+++ b/spark/src/main/java/com/robinhood/spark/SparkView.java
@@ -184,7 +184,12 @@ public class SparkView extends View implements ScrubGestureDetector.ScrubListene
if (i == 0) {
sparkPath.moveTo(x, y);
} else {
- sparkPath.lineTo(x, y);
+ final float prevx = scaleHelper.getX(adapter.getX(i - 1));
+ final float prevy = scaleHelper.getY(adapter.getY(i - 1));
+
+ final float smoothness = 0.5f;
+ final float dX = x - prevx;
+ sparkPath.cubicTo(prevx + dX * smoothness, prevy, x - dX * smoothness, y, x, y);
}
if (scrubEnabled) {
This is how it would look like:
The smoothness can be changed by adjusting smoothness
.
I don't know if this is the right spot for this...
1 - On Android Robinhood, my charting appears to not match actual history. On the full history chart, it appears I was up 100% over all for a few months in 2018 which it wasn't. I see this hasn't changed in a while so maybe it's something related to another part of the project, or this needs to be updated to reflect some changes on another branch? This started happening on Monday/Tuesday 4/13/20 - 4/14/20
2 - On Android Robinhood, when you see notifications for % gain or loss, you see a red bear chart for a gain and a green bull chart for a loss. The graphics should be reversed. I can take a look at this repo for that is you want.
These could be issues on another repo, and this chart is just reading it as is.
First of all thank you for developing this lib!
I'm trying to reproduce the heart rate "spark" in the gif below.
Any plans to implement an animation like this? Have you seen anything similiar? Or maybe if you could point me in the right direction on how to implement this. I don't even know where to start.
Thank you!
As title suggests, it should be possible to get the fill drawing with a different color to the main line.
I have managed to get this working locally, with a subclass of spark view, and wondered if it would be worth porting it back into Spark and submitting a PR?
Hello,
I was wondering if it is possible to display 2 or more lines in one chart (to compare your portfolio with an fond for example).
Hello, any particular reason why the min SDK is 16? I want to use Spark with min SDK 15. I checked the code and there seem to be no incompatible APIs. I also ran it on the emulator and it seemed to be OK. Just to confirm, are there any known issues with previous SDK versions? Thanks
Just curious why there isn't a listener for both the x and y values?
Wondering if there is a plan to release this on iOS and/or React Native.
How can we set a minimum and maximum value for the graph?
I can't found it on docs. is there a way?
I have the following code in my app. However i see nothing being drawn. I do see the list being populated correctly. Any input is appreciated.
List<Float> dataSetForLineGraph;
public DetailsFragmentLineGraphAdapter(List<Float> dataSetForLineGraph) {
this.dataSetForLineGraph = dataSetForLineGraph;
}
@Override
public int getCount() {
return dataSetForLineGraph.size();
}
@Override
public Object getItem(int index) {
//Log.e("###",Float.toString(dataSetForLineGraph[index]));
return dataSetForLineGraph.get(index);
}
@Override
public float getY(int index) {
// Log.e("@@@",Float.toString(dataSetForLineGraph[index]));
return dataSetForLineGraph.get(index);
}
}
And this is my xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<com.robinhood.spark.SparkView
android:id="@+id/sparkView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
When writing layout XML library consumers don't get autocomplete on SparkView
's stylable attributes. We had a similar problem in Ticker #75.
Can we rename the stylable tag to SparkView? This change should be compile time safe and prompt folks to update their XML/source.
Cool library! Thanks for releasing it.
What I'd like to do
I'd like to overlay a bunch of SparkViews. So far, it works and looks basically how I want it to. The problem is that the scale of the different SparkViews is different because the range of the data for each chart is different. If there was were methods in SparkAdapter that allowed me to specify the full range of the whole dataset, the scale of the individual SparkViews would be the same and everything would look as expected.
How I'd like to do it
I thought about adding getMax()
and getMin()
methods to SparkAdapter
. They could also be protected behind a hasManualMinMax()
method similar to hasBaseline()
. The manually set min and max would then be used by ScaleHelper
.
What do you think?
Hi, I want to add animation type support, and add other animation type.
Add animation type support is to make easy for someone create other type of animations.
Add a animation other than draw the line. The animation animates the line from where it is until where it was updated, each point.
I create a animation type enum, with "none", "line" and "point" animation.
Animation type "line" is the default one. "none" is for no animation and "point" is the new animation type.
I'm having trouble creating the baseline in the sparkview when following the blog post here. Could you please provide a sample on getting this setup and how to get it to appear on the price point of the first tick.
I've noticed on the Robinhood app that scrubbing over portions of the sparkline that are after-hours will tint market and pre-market hour portions to a darker color while keeping the scrubbed over region the same. Is this conditional tinting possible with the default sparkview and if so, is there any guidance as far as coloring or tinting regions of the sparkline based on adapter data?
Seems version with animation is not adjusted from 1.1.2 to 1.1.3 yet
I have a graph that needs to use all negative data, and I was trying to fill the inside of the data.
When I set shading to true using setFill(true)
, my graph with all negative data looks like this (the baseline you can see is at 0
):
As you can see, the fill is placed underneath the line, instead of above it, as you would expect, which makes all the data look positive. To fix this in my own app, I had to do this:
sparkView.setLineColor(getResources().getColor(R.color.colorBackground));
sparkView.setBackgroundColor(getResources().getColor(R.color.colorAccent));
I set the background color to my line color, and the line color to my background color. As you can see, this works (the baseline is again at 0
):
But obviously it would be a whole lot nicer if it worked without the hack I had to implement. 😉
Thanks!
It would be awesome to be able to display different datasets simultaneously. Imagine viewing your bodyweight measurements through a graph like this, and being able to also see how your waistline has progressed during the same time frame.
Theoretically this would be possible by just laying out multiple SparkViews on top of each other, but I would much rather have the SparkView directly draw them (1 view vs many).
Would love to hear your feedback on this so that I can know how to proceed with my ideas.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.