Code Monkey home page Code Monkey logo

spark's Introduction

Spark

Sparkline: a very small line chart, typically drawn without axes or coordinates. It presents the general shape of the variation (typically over time) in some measurement, such as temperature or stock market price, in a simple and highly condensed way.

-- en.wikipedia.org/wiki/Sparkline

Spark is a simple Android library that takes a series of x,y points at any scale and draws them as a sparkline chart.

Usage

Spark is setup with reasonable default values out of the box. Just add a SparkView to your layout:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

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

Then, just give it a SparkAdapter to graph your data:

SparkView sparkView = (SparkView) findViewById(R.id.sparkview);
sparkView.setAdapter(new MyAdapter(data));
...
public class MyAdapter extends SparkAdapter {
    private float[] yData;

    public MyAdapter(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];
    }
}

See spark-sample for a complete sample app.

Theming

Spark is very theme-friendly! It has default styles set for you, and welcomes any overrides:

In your Activity/Fragment/View:

sparkView.setLineColor(getColor(R.color.brand_color_primary));

In your layout xml:

    <com.robinhood.spark.SparkView
        android:id="@+id/sparkview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:spark_lineColor="@color/brand_color_primary"/>

Set a default style for all SparkViews in your app's theme:

<resources>
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="spark_SparkViewStyle">@style/MySparkViewStyle</item>
    </style>

    <style name="MySparkViewStyle" parent="@style/SparkView">
        <item name="spark_lineColor">@color/line_color</item>
        <item name="spark_lineWidth">@dimen/line_width</item>
        <item name="spark_cornerRadius">@dimen/corner_radius</item>
        <item name="spark_fill">false</item>

        <item name="spark_baseLineColor">@color/base_line_color</item>
        <item name="spark_baseLineWidth">@dimen/base_line_width</item>

        <item name="spark_scrubLineColor">@color/scrub_line_color</item>
        <item name="spark_scrubLineWidth">@dimen/scrub_line_width</item>
        <item name="spark_scrubEnabled">true</item>

        <item name="spark_animateChanges">true</item>
    </style>
</resources>

Scrubbing

Scrubbing is when the user taps and drags their finger along the sparkline chart. It is very useful to display additional detail information about the point the user is currently scrubbing over.

Enable scrubbing via xml:

<com.robinhood.spark.SparkView
    ...
    app:spark_scrubEnabled="true" />

or programatically:

sparkView.setScrubEnabled(true);

and then add a SparkView.OnScrubListener to get callbacks:

sparkView.setScrubListener(new SparkView.OnScrubListener() {
        @Override
        public void onScrubbed(Object value) {
            scrubInfoTextView.setText(getString(R.string.scrub_format, value));
        }
    });

Base Line

It's frequently useful to show a "base line" against which the rest of the sparkline chart will be compared. In your SparkAdapter, override hasBaseLine() to return true and then return the appropriate base line value in getBaseline().

X Values

Spark assumes that your graph's points are evenly distributed across the x-axis. If that's not true, just override getX(int index) in your SparkAdapter to give SparkView the correct value.

Animation

To animate sparkline changes, set an animator with sparkView.setSparkAnimator(sparkAnimator). There are two built-in animators: LineSparkAnimator (default) and MorphSparkAnimator. Pass your own implementation to achieve custom effects.

Data Boundaries

By default, Spark will calculate the min and max of your data set, and draw the sparkline as large as possible within the View boundaries. If you want different behavior, such as "zooming in" on a portion of your data, or "zooming out" to leave space between the sparkline and the side of the view, you can override SparkAdapter.getDataBounds():

public class MyAdapter extends SparkAdapter {
    ...

    @Override
    public RectF getDataBounds() {
        RectF bounds = super.getDataBounds();
        // will 'zoom in' to the middle portion of the graph
        bounds.inset(bounds.width() / 4, bounds.height() / 4);
        return bounds;
    }
}

Vision

Spark is a very simple library and cannot possibly meet everyone's use-cases. A more robust charting library (such as MP Android Chart) may be a better fit if you're looking for things like axes or advanced touch gestures. Spark aims to be lightweight alternative for showing simple sparklines. Spark will prioritize simplicity over new use-cases the vast majority of the time.

Download

Gradle:

implementation 'com.robinhood.spark:spark:1.2.0'

License

Copyright 2016 Robinhood Markets, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

spark's People

Contributors

danh32 avatar enricomonese avatar evant avatar guavabot avatar horie1024 avatar jinatonic avatar naturalwarren avatar raoninovellino avatar richyhbm avatar scompt avatar veyndan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spark's Issues

Using SparkAdapter with X and Y value and displaying both on onScrubbed()

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.

Fill Color

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

minSdkVersion

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

can i take double DataType in y axis

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.

error: attribute spark_fillColor not found

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" />

`

Conditionally color sparkline

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?

Fill with gradient

Is it possible to create a fill gradient for spark instead of filling with a solid color?

Does library support using List instead of float array?

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>

Is it possible to add axis?

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.

Show min and max values.

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:

screen shot 2018-04-12 at 5 15 54 pm

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!

Android graph mismatch to actual charting data

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.

Multiple lines in one chart?

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).

Filling Graph With Negative Data Fills Under the Line Instead of Over It

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):

screenshot_20170609-194201 1

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):

screenshot_20170609-195053 1

But obviously it would be a whole lot nicer if it worked without the hack I had to implement. 😉
Thanks!

New release soon?

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

Thank you..

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

Manually set min/max values of dataset

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?

Option to have smooth lines instead of hard ones.

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:

screen shot 2017-03-14 at 11 41 35

The smoothness can be changed by adjusting smoothness.

Proposal: Rename stylable tag to SparkView.

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.

Dinamic graph

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.

Gradient support

Anyway to add a down fill gradient without the line color following it down.

Allow generic drawing effects

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.

DataSet with one value isnt being drawn

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.

Custom Line Chart

I want to draw this line chart and I added 3 limit lines.Chart's default color must be grey and if chart lower than 2.limit line chart color is must be green and higher than 3. limit line chart color is must be orange.How can I do that? This is the reference picture.Is it possible this library?
line

Add support for multiple lines (comparison)

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.

Spark for iOS

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

Spark has trouble displaying time-series data

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" />

BaseLine dotted line sample

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.

Upgrade spark to androidx

the animation library is using annotations of android support library which needs to be upgraded to androidx for animations to work.

ScrubWidth is using LineWidth in Constructor

When you initialize the scrubPaint you use this:

sparkLinePaint.setStrokeWidth(lineWidth);

It should be using the scrubLineWidth variable instead.

Thanks for the great library! :)

Add animation types

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.

sparkAnime.zip

Allow different fill color to spark line color

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?

Setting cornerRadius to non-zero results in fill closing path also using radius

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.

shadow

how to set shadow for when chart get low?!?!

Scrubbing with X Value

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!

[Request] New animation

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!

ezgif-3-107271d80a

Fill graph animation and boundary lines

200w_d
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?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.