PhilJay / MPAndroidChart

A powerful 🚀 Android chart view / graph view library, supporting line- bar- pie- radar- bubble- and candlestick charts as well as scaling, panning and animations.
Other
37.63k stars 9.02k forks source link

Display highlited Entry values on the axis #222

Open MGaetan89 opened 9 years ago

MGaetan89 commented 9 years ago

I started to use this library for my project and here is a first suggestion/question (depending on whether it is already possible or not).

When I select a point (Entry) on my LineChart, I would like its values (x & y) to be display on the x axis and y axis respectively. Is this possible? If not, is it easy to implement?

Thanks for this awesome library!

PhilJay commented 9 years ago

That's actually a very good idea. I will consider to add this in a future update. In my opinion it should be possible to implement such a feature with moderate effort.

clay-to-n commented 9 years ago

Seems like this is similar to the feature implemented in this pull request: https://github.com/PhilJay/MPAndroidChart/pull/478

I couldn't find the commits, but I assume the Y-axis drawing eventually got merged in. If so it shouldn't be hard to get similar functionality on the X-axis I'd imagine.

Enteleform commented 9 years ago

+1, this would be great!

Drakot commented 8 years ago

Is this implemented?

xdnan7 commented 8 years ago

+1

regas99 commented 5 years ago

[Update: the behavior of the axis highlight has changed in the final version - PR #4477. The axis now draw a recttangle and text at the highlighted value. See the PR for details.]

I am pretty close to completing work on this. The proposed functionality is documented below, and an example screen shot is provided. Please provide feedback and suggestions for changes / improvements.

Sample screen shot.

Maps the largest cities in California. Two points on the right log log axis have been touched, and only cities whose populations are between those values are rendered. The city of Bakersfield has also been highlighted.

screenshot2

Proposed wiki page:

This section focuses on the topic of highlighting entries in the chart, both via tap-gesture and programmatically based on Pull Request ###.

Highlightable Items

Both data vales and individual axes can be highlighted.

Enabling / Disabling highlighting

For The Chart
For the DataSets

Highlighting can be configured for individual DataSet objects:

  dataSet.setHighlightEnabled(true); // allow highlighting for DataSet

  // set this to false to disable the drawing of highlight indicator (lines)
  dataSet.setDrawHighlightIndicators(true); 
  dataSet.setHighlightColor(Color.BLACK); // color for highlight indicator
  // and more...
For the axes

Highlighting can be configured for each axis:

axis.setHighlightEnabled(true); // allow highlighting for Axis. Default false.

// if set, touching an axis will change the color of the nearest label
axis.setSnapHighlightToLabel(true);
axis.setHighlightColor(Color.RED);
Removing highlights

To remove single or multiple highlights, touch in a 'blank' area of the data (as defined by setMaxHighlightDistance above), touch the same entry twice, or the same axis at the same position twice. The latter action may be difficult to perform.

Multiple Highlights

For each highlightable item (each data set and each axis), either single or multiple highlights can be enabled:

item.setMultipleHighlightsEnabled(true);

If false, highlighting one item removes any existing highlight on that item. If true, multiple highlights can coexist.

Selection callbacks

This library two listeners for callbacks upon highlighting: OnChartValueSelectedListener and OnAxisSelectedListener. If both listeners exist, the onNothingSelected callback is made to the OnChartValueSelectedListener and not to the OnAxisSelectedListener.

OnChartValueSelectedListener

For callbacks when a data value has been selected for highlighting

public interface OnChartValueSelectedListener {
    /**
    * Called when a value has been selected inside the chart.
    *
    * @param e The selected Entry.
    * @param h The corresponding highlight object that contains information
    * about the highlighted position
    */
    public void onValueSelected(@Nullable Entry e, Highlight h);
    /**
    * Called when nothing has been selected or an "un-select" has been made.
    */
    public void onNothingSelected();
}

Simply let your class that should receive the callbacks implement this interface and set it as a listener to the chart:

chart.setOnChartValueSelectedListener(this);

OnAxisSelectedListener

For callbacks when an axis has been selected.

    /**
     * Called when an axis has been selected outside the chart.
     *
     * @param h highlight object that contains information
     *          about the highlighted position.
     */
    onAxisSelected(Highlight h);

    /**
    * Called when nothing has been selected or an "un-select" has been made.
    */
    public void onNothingSelected();

Simply let your class that should receive the callbacks implement this interface and set it as a listener to the chart::

chart.setOnAxisSelectedListener(this);

Highlighting programmatically

Highlight types

A highlight has a type: VALUE, X_AXIS, LEFT_AXIS, RIGHT _AXIS or NULL.

Each highlight can be queried for its type:

There are a number of constructors available, including:

// for an axis highlight, create a highlight at the given x or y point.
// for a value highlight, search for the entry closest to x, y and highlight it.
Highlight(float xVal, float yVal, Type highlightType, float xPix, float yPix)

// if we already know which entry to highlight, set dataSetIndex 
// and dataIndex to skip the search
Highlight(float x, float y, float xPx, float yPx, int dataSetIndex, int dataIndex, YAxis.AxisDependency axis)

The Highlights class

The Highlights class holds a collection of Highlight s of a particular type. There can only be one 'Highlight Type' in an instance of Highlights, determined by the first Highlight added to the collection. Attempting to add a different type to a non-empty Highlights instance will throw a run time exception.

Methods
Getters

Each Highlight Type is gotten through different methods:

    VALUE: chart.getHighlights();

    X_AXIS: if (chart.hasXAxis)
                 chart.getXAxis().getHighlights();

    LEFT_AXIS: if (chart.hasLeftAxis)
                 chart.getLeftAxis().getHighlights();

    RIGHTT_AXIS: if (chart.hasRightAxis)
                 chart.getRightAxis().getHighlights();

You can skip the hasAxis checks if you are sure that the given axis exists, but you will get a run time exception if you are wrong.

Multiple highlights

Multiple highlights are supported at the Highlights level. Setting or getting these fields for a highlightable item simply passes the call through to the underlying `Highlights' class.

    setMultipleHighlightsEnabled(true);
    boolean isMultipleHighlightsEnabled();
Add / remove
    /**
     * Adds the given Highlight.
     * Deletes any pre-existing highlights if 
     * `isMultipleHighlightsEnabled` is false.
    */
    boolean add(Highlight highlight);

    /**
     * Removes the given highlight if it exists.
     *
     * @param highlight to be removed
     * @return true if highlight existed and was removed
     */
    public boolean remove(Highlight highlight)

    // clear all highlights
    void clear();  
Size
    int size();
    boolean isEmpty();
    boolean hasHighlights();  // same as isEmpty()
Iterating
    Iterator<Highlight> = highlights.iterator()

The Highlight class

The Highlight class represents all data associated with a highlight.

Fields

The indices are ignored for a non-VALUE Highlight and are generally set to -1.

VALUE highlight

The Highlight class provides several constructors for a VALUE Highlight:


 /** 
  *  Constructor for standard highlight.
  *  The data set will be searched for the entry closest to x.
 */
 public Highlight(float x, int dataSetIndex) { ... }

/**
 * Constructor where we know which entry to highlight.
 * This avoids the search overhead.
*/
public Highlight(float x, float y, float xPx, float yPx, int dataSetIndex, int dataIndex, YAxis.AxisDependency axis)

 /** constructor for stacked BarEntry highlight */
 public Highlight(float x, int dataSetIndex, int stackIndex) { ... }

The generic constructors below can also be used to create a Highlight by providing a VALUE type to those constructors.

Generic highlight

The Highlight class provides several constructors for a generic Highlight:

// Creates an 'empty' highlight of the given type.
// Generally used to return a NULL highlight rather
// than a null object - ala Kotlin.
Highlight(Type highlightType);

// constructor to support axis highlights with touch position
Highlight(float xVal, float yVal, Type highlightType, float xPix, float yPix)

Adding Highlights

To highlight a highlight item, simply create a Highlight with the appropriate type and add it to the chart. You need to provide both the xy data values and corresponding pixel position for constructors requiring either.

highlight the third[2] entry in the second[1] DataSet
Highlight highlight = new Highlight(xVal, yVal, xPx, yPx,
                            dataSetIndex = 1, dataIndex = 2, 
                            stackIndex = -1, YAxis.AxisDependency axis)
chart.addHighlight(highlight, true)
highlight the 12.2 point on the X axis
Highlight highlight = new Highlight(12.2f, yVal, highlightType = X_AXIS,
                            xPix, yPix)
chart.addHighlight(highlight, true)
add multiple highlghts

To add multiple highlights, simply add highlights one at a time, or create a new Highlights and add it to the chart:

Highlights highlights = new Highlights();
highlights.setMultipleHighlightsEnabled(true);  // else they will be disabled
highlights.add(new Highlight(...));
... repeat as needed
chart.addHighlights(highlights);

Note that after addHighlights is called, mMultipleHighlightsEnabled is true only if it is true before the methd is called and if it is true in the added highlights.

Custom highlighter

All user input in the form of highlight gestures is internally processed by the default ChartHighlighter class. It is possible to replace the default highligher with a custom implementation using the below method:

Zikstar commented 4 years ago

Please @PhilJay , can you review and merge @regas99's PR

eggham0518 commented 4 years ago

Please merge this

hgcho0707 commented 1 year ago

merge plz..