Search code examples
javaandroidteechart

How to set "absolute" area gradient?


See the image below. The gradient is painted incorrectly, and the vertical black lines are just ugly.

  1. How do I create a gradient that stretches from min to max? E.g. If I have a scale from 0 to 100 I want my area to use N of these 0..100 gradient values.
  2. How do I remove the vertical black lines?

Bad gradient

UPDATE: The provided answer works, except that I get this artifact:

Artifact

UPDATE 2: This only happens when using ONE LinearLayout as shown below:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/chart_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="3dip" >

    <Spinner
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Spinner
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Spinner
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

Then the TChart is added to chart_layout. Bam! Offset error :)


Solution

  • How do I create a gradient that stretches from min to max? E.g. If I have a scale from 0 to 100 I want my area to use N of these 0..100 gradient values.

    I want the gradient to fade from minimum to maximum (0 to 100 in this case). So in the image above, points at 80 would have the 80th gradient color (almost green). Points at 50 would have the 50th gradient color (yellow). I believe you need a new gradient type: SYMMETRICRECTGRADIENT

    The Area series draws the segments one before the next, and the area below each segment with each of these segments. That's why the Area series can't draw a uniform gradient. However, the other versions of TeeChart have the GradientRelative that does what you request when it's set to false. I've added to the wish list the possibility to implement this property (and the functions associated) to the Java version (TJ71016477).

    In the meanwhile, you could use the SeriesBand tool to do it. Here it is an example:

        tChart1.getAspect().setView3D(false);
        tChart1.getLegend().setVisible(false);
    
        Area area1 = new Area(tChart1.getChart());
        area1.fillSampleValues();
        area1.setOrigin(0);
        area1.setUseOrigin(true);
        area1.getAreaLines().setVisible(false);
        
        area1.getGradient().setVisible(false);
        area1.setColor(Color.transparent);
        
        SeriesBand band1 = new SeriesBand(tChart1.getChart());
        band1.setSeries(area1);
        band1.getGradient().setVisible(true);
        band1.getGradient().setDirection(GradientDirection.VERTICAL);
        band1.getGradient().setStartColor(Color.green);
        band1.getGradient().setMiddleColor(Color.yellow);
        band1.getGradient().setUseMiddle(true);
        band1.getGradient().setEndColor(Color.red);
    

    This is what I get with the code above:

    Area with SeriesBand tool to show a uniform gradient

    UPDATE: I've reproduced the strange artifact issue. I've added to the wish list to be further investigated (TJ71016541). In the meanwhile, using a second LinearLayout just for the chart seems to work fine.

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="3dip" >
    
        <Spinner
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
        <Spinner
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
        <Spinner
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
        <LinearLayout 
            android:id="@+id/chart_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" />
    </LinearLayout>
    

    Another way around this, as said in the comments, is hiding the area line and making visible the SeriesBand pen:

    area1.getLinePen().setVisible(false);
    band1.getPen().setVisible(true);