Click here to Skip to main content
Click here to Skip to main content

Creating a XY Chart/Plot as a Bitmap for Android

By , 26 Jul 2010
 

Introduction

Plotting an XY set is a very common task, a description of the main steps for implementing such a module for the Android platform is outlined in this article. This goes along with the similar BlackBerry article posted earlier.

Developing on the Android platform is very straightforward and its model of allowing all of the GUI to be defined in XML (although it can also be created by code) is quite good. Most of the graphics samples deal with a View, but in most cases the chart is supposed to be part of a screen defined as a layout XML so here we show the implementation onto an ImageView layout object.

Background

In the Android environment, there is whole set of graphics routines usually a Bitmap holds the pixels, a Canvas is where we can apply the draw calls (writing into the bitmap) and with this we can draw the primitives (text, lines,etc) with a paint which describes the colors, styles and so on. Since the Android developing platform is all Java, it is very well structured and all of the features from Java such as inheritance, subclassing, etc. can be used extensively. For our sample here, it is all kept simple.

The GUI is defined as an XML layout file, the attached sample code shows the basic implementation of an XY chart for the sake of simplicity the X-points are evenly spaced sequential numbers.

1. The XML Layout File Defining the GUI

The ImageView object with the id of testy_img is the one that we will be using to draw the chart on:

<?xml version="1.0" encoding="utf-8"?>

<TableLayout 

    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="fill_parent" 
    android:layout_width="fill_parent"
    android:background="#4B088A">
  
    <TableRow android:layout_width="fill_parent" 
    android:layout_height="wrap_content"
     android:padding="20px"> 
   
     <TextView  
 	android:id="@+id/some" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="Some layout  items here"
    android:layout_marginLeft="10px"
    android:layout_marginRight="10px"
    android:textColor="#ff8000"
    android:textStyle="bold"
    />

    </TableRow>

 <View     
  android:layout_width="fill_parent"
	android:layout_height="1dip"
	android:background="#FFE6E6E6"
	 />
	    
    <TableRow>

    <ImageView  
 	android:id="@+id/testy_img" 
 	android:layout_marginLeft="20px"	
 	 android:padding="20px"
    />

   </TableRow>

 <View     
  android:layout_width="fill_parent"
	android:layout_height="1dip"
	android:background="#FFE6E6E6" />

    <TableRow android:layout_width="fill_parent" 

    android:layout_height="wrap_content"
     android:padding="20px"> 

     <TextView  
 	android:id="@+id/more" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="More layout items here"
    android:layout_marginLeft="10px"
    android:layout_marginRight="10px"
   	android:textColor="#ff8000"
    android:textStyle="bold"
    />

    </TableRow>

</TableLayout>

2. The Chart Implementation

To implement our chart, first we create a bitmap where we will be writing and then we associate it with the layout XML object. Once we have the bitmap, we just carry out the chart implementation where we do the scaling, coloring and data digesting. This charting element is comprised of a grid where the data will be plotted, a scale/transpose method so that the data points can be coherently mapped onto the available screen space and a data digesting routine to loop through the data points.

2.1 Defining the Bitmap to Draw

As shown below, first we make the connection to the object from the XML layout, then we create the Bitmap where we will be doing all the drawing which is carried out by the quicky_XY and finally we print this bitmap to the image and hence to the screen.

 @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.testy); 
        setTitle("Quick XY Plot");
        
        ImageView image = (ImageView) findViewById(R.id.testy_img);
     
       Bitmap emptyBmap = Bitmap.createBitmap(250,
                200, Config.ARGB_8888); 
        
        int width =  emptyBmap.getWidth();
        int height = emptyBmap.getHeight();
        Bitmap charty = Bitmap.createBitmap(width , height , Bitmap.Config.ARGB_8888);
        
        charty = quicky_XY(emptyBmap);
       
         image.setImageBitmap(charty);     
  }

2.2 Drawing the Grid for Plotting

Once the basic Bitmap is defined, we need the associated canvas, this is done with:

Canvas canvas = new Canvas(bitmap) 

and from there on, all of the drawing can be done onto the canvas. We need the grid to define the space where the data points will be drawn, a chart will usually have a label and some range for its data points. In the code shown, the Vector argument contains objects of the form [Label, units, maxValue, minValue] upon completion the drawSizes array will have the location and dimension of the plotting area.

public static void  draw_the_grid(Canvas this_g,  Vector these_labels)
     {         
        double rounded_max = 0.0;
        double rounded_min = 0.0;
        double rounded_max_temp;
        Object curElt;  
        String[] cur_elt_array;
        int left_margin_d, right_margin_d;      

        if( draw_only_this_idx == -1)      
           curElt = these_labels.elementAt(0);  // default  it to 1st one if non set 
        else
           curElt = these_labels.elementAt(draw_only_this_idx);  // now just the 1st elt
           
        cur_elt_array = (String[])curElt;

        rounded_max = get_ceiling_or_floor (Double.parseDouble(cur_elt_array[2]) , true);
        rounded_min = get_ceiling_or_floor (Double.parseDouble(cur_elt_array[3]) , false);

       // ok so now we have the max value of the set just get a cool ceiling and we go on
        final Paint paint = new Paint();  
        paint.setTextSize(15);
        
       left_margin_d =  getCurTextLengthInPixels(paint, Double.toString(rounded_max));
       //keep the position for later drawing -- leave space for the legend
       int p_height = 170;
       int p_width = 220;
       int[] tmp_draw_sizes = {2 + left_margin_d, 25,p_width - 2 - 
		left_margin_d ,p_height - 25 -5};
       drawSizes = tmp_draw_sizes; //keep it for later processing
        
        //with the mzrgins worked out draw the plotting grid
       paint.setStyle(Paint.Style.FILL); 
       paint.setColor(Color.WHITE );  
       
       // Android does by coords
       this_g.drawRect(drawSizes[0], drawSizes[1],drawSizes[0]+ 
		drawSizes[2], drawSizes[1]+ drawSizes[3] , paint);
       
       paint.setColor(Color.GRAY );       
       
        // finally draw the grid      
       
       paint.setStyle(Paint.Style.STROKE); 
       this_g.drawRect(drawSizes[0], drawSizes[1],drawSizes[0]+ 
		drawSizes[2], drawSizes[1]+ drawSizes[3] , paint);

           for(int i=1; i < 5 ; i++)
           {
               this_g.drawLine(drawSizes[0], drawSizes[1] + 
		(i * drawSizes[3] / 5), drawSizes[0] + drawSizes[2], 
		drawSizes[1] + (i * drawSizes[3] / 5), paint);
               this_g.drawLine(drawSizes[0]+ (i * drawSizes[2] / 5), 
		drawSizes[1], drawSizes[0] + (i * drawSizes[2] / 5), 
		drawSizes[1] + drawSizes[3], paint);
           }

          // good for one value
           print_axis_values_4_grid(this_g, cur_elt_array[1] , 
		Double.toString(rounded_max) , Double.toString(rounded_min), 
		cur_elt_array[0] , 2 ,0 );
         
     }  // --- end of draw_grid --- 

2.3. Plotting and Scaling

The data points need a proper mapping from the data ranges to the screen coordinates, this is accomplished with the scale method shown below. Looping through the data points and calling a drawLine between two successive points will wrap up our Chart. The data points are passed as a Vector containing the data and will now call the plot_array_list.

private static Point  scale_point(int this_x , double this_y  , Point drawPoint , 
            int scr_x  , int scr_y  , int scr_width  , int src_height  , 
            double maxX  , double minX  , double  maxY  , double minY  )
       {
           int temp_x, temp_y;
           Point temp = new Point();   
           
           if (maxY == minY)  //skip bad data
               return null;

           //don't touch it if is nothing
           try
           {
                   temp_x = scr_x + (int)( ((double)this_x - minX) * 
			((double)scr_width / (maxX - minX)) );
                   temp_y = scr_y + (int)( (maxY - this_y) * 
			((double)src_height / (maxY - minY)) );
                
                   temp.x = temp_x;
                   temp.y= temp_y;
                   drawPoint = temp;
           } 
           catch  (Exception e)
           {
        
              return (null);
           }
           
           return temp;
           
       } // --- end of scale_point --


    public static boolean plot_array_list(Canvas this_g, Vector this_array_list , 
	Vector these_labels , String this_title , int only_this_idx ) 
    {
             int idx;
             int lRow ;
             int nParms;
             int  i, points_2_plot, shifted_idx ; 
             int prev_x, prev_y ;
             int cur_x=0, cur_y=0 ; 
             //Dim ShowMarker As Object
             Point cur_point = new Point();
            cur_point.set(0,0);
     
             double cur_maxX, cur_minX, cur_maxY=20, cur_minY=0, cur_rangeY;
             int cur_start_x, cur_points_2_plot; 
   
            int POINTS_TO_CHANGE = 30;
            double cur_OBD_val;
  
             //Object curElt;  
             String curElt; 
             String[] cur_elt_array;
             Object curElt2;  
             String[] cur_elt_array2;
     
             final Paint paint = new Paint();

             try // catch in this block for some thing
             {       
                   points_2_plot = this_array_list.size();
                   {
                        cur_start_x = 0;
                        cur_points_2_plot = points_2_plot;
                        cur_maxX = cur_points_2_plot;
                        cur_minX = 0;
                   }
  
                   //'Create the plot points for this series from the ChartPoints array:
   
                   curElt = (String)this_array_list.elementAt(0);
                   
                   //the lines have to come out good
                    paint.setStyle(Paint.Style.STROKE);
//                  
                   //for(  nParms = 0 ; nParms < cur_elt_array.length ; nParms++ )
                   nParms = only_this_idx;
                   {
    
                       //get cur item labels
                        curElt2 = these_labels.elementAt(nParms);
                        cur_elt_array2  = (String[]) curElt2;
                        
                        cur_maxY = get_ceiling_or_floor 
			(Double.parseDouble(cur_elt_array2[2]) , true);
                        cur_minY = get_ceiling_or_floor 
			(Double.parseDouble(cur_elt_array2[3]) , false);
                        
                        cur_points_2_plot = this_array_list.size();
                        cur_maxX = cur_points_2_plot;
    
                      curElt = (String)this_array_list.elementAt(0);
                      cur_OBD_val = Double.parseDouble( curElt);
                      
                      cur_point = scale_point(0, cur_OBD_val, cur_point, 
                              drawSizes[0], drawSizes[1], drawSizes[2], drawSizes[3], 
                              cur_maxX, cur_minX, cur_maxY, 
		      cur_minY); //'(CInt(curAxisValues.Mins(nParms - 2) / 5) + 1) * 5)
                       
                       cur_x = cur_point.x;
                       cur_y = cur_point.y;

                       paint.setColor(Color.GREEN);
                       
                      // the point is only cool when samples are low
                       if ( cur_points_2_plot < POINTS_TO_CHANGE)
                         this_g.drawRect(cur_x-2, cur_y-2, cur_x-2 + 4,
						cur_y-2+ 4 , paint); 
                       
                       prev_x = cur_x;
                       prev_y = cur_y;

                       //'go and plot point for this parm -- pont after the 1st one 
                       for (lRow = cur_start_x +1 ; lRow< cur_start_x + 
					cur_points_2_plot -1 ; lRow++)
                       {        
                           curElt = (String)this_array_list.elementAt(lRow);
                           
                           cur_OBD_val = Double.parseDouble( curElt); 
                                 
                            //'work out an approx if cur Y values not avail(e.g. nothing)
                           // if (! (cur_elt_array[nParms ] == null ) )   //skip bad one
                             if( cur_OBD_val == Double.NaN) continue;  //skip bad one
                            {                  
       
                               
                                cur_point=scale_point(lRow, cur_OBD_val, cur_point,  
                                    drawSizes[0], drawSizes[1], 
				drawSizes[2], drawSizes[3], 
                                    cur_maxX, cur_minX, cur_maxY, cur_minY);
    
                                cur_x = cur_point.x;
                                cur_y = cur_point.y;
                                
                                if ( cur_points_2_plot < POINTS_TO_CHANGE)
                                   this_g.drawRect(cur_x-2, cur_y-2, cur_x-2 +4, 
				cur_y-2 + 4, paint ); 
 
                               this_g.drawLine( prev_x, prev_y, cur_x, cur_y, paint);
                               prev_x = cur_x;
                               prev_y = cur_y;
                          
                            } // ' if end of this_array(lRow, nParms - 1)<> nothing
                                 
                   } // end of for lrow
                               
               } // end of for nParmns

            //this_g.invalidate();
            return( true);
        }
        catch (Exception e)
        {
            return( false);
        }

    } // --- end of plot_array_list  --

With this, the plotting is carried out and the output now looks like the figure below:

android_xy.gif

Final Thoughts

The methods shown work rather well, when we needed to do real-time plotting a slight modification of the routine was used where instead of a Vector, a Queue data structure was used since we needed to be able to plot the data as it came in as well as having a scrolling feature but the basic components were the same. Many more modifications can be applied depending on the requirements. One of these mods could be using the drawLines call, but here we will need to setup the lines array argument which may not differ much from our plot_array_list method.

History

  • 27th July, 2010: Initial post

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)

About the Author

becker666
Software Developer (Senior) BSC Inc
United States United States
Member

Becker Cuéllar is an independent developer(C#/C++/J2ME/VB/perl) on the Washington DC corridor and focuses on developing/integrating web interfaces with Databases(MSSQL, MySQL, Oracle, Sybase), with mobile devices, scripting(perl/php/javascript) and with MS and Linux(RHE) based backends. Aditionally a full Mobile architect/developer for custom applications for Windows Mobile NETCF , Blackberry J2ME, Android, PalmOS and iPhone.
 
You'll find him traveling and hiking somewhere on this planet when not working on a project or on a road course race track tweaking his engine and attempting to improve his lap times.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
Questionresolve target 'android-4'memberMember 999513018 Apr '13 - 7:14 
i am getting an error /....
unable to resolve target 'android-4'.
from second time execution..please help me..
QuestionHow to make graph scroll able for vertically and horizontallymemberMember 951713616 Oct '12 - 4:13 
How to make graph scroll able in vertically and horizontally
Questionproblem with plotting x-axismemberNorton Ng27 Feb '12 - 22:57 
hi, sorry to trouble you, but i have been working on editing the javascript to show the x-axis and its values. also, i am having problems with creating more grids on the x and y axes. i will appreciate it if you can help me with these problems.
 
Thanks!
GeneralMy vote of 5membergrndvl129 Aug '11 - 11:30 
Just a great article on how to plot data, would love to see dynamic data plotting too.
QuestionDynamic datamembergrndvl129 Aug '11 - 11:28 
Can you show us the modification for dynamic data as you mentioned at the bottom of the article?   I have need of that and can't seem to get my modifications to work with a Queue.   Thanks...
AnswerRe: Dynamic datamemberbecker66629 Aug '11 - 18:10 
Easy way is use a Vector, data comes in e.g. you populate the vector and reload/redraw
with new vector, may have to play with indexes and stuff but that is just a little debug
session.
GeneralRe: Dynamic datamembergrndvl130 Aug '11 - 4:33 
Not quite the answer I was looking for as I have already tried it with Vectors and its really slow for the data packets I need to show, at 250 data points per sec. I am trying to only refresh the graph at 10 fps.
QuestionHow can i show titles for x-axis, like u show for y axis, value is 0.0, 20,00, and so on ?memberkp_iteng29 Aug '11 - 0:44 
Hello,
 
I am getting help from this code.
 
But i want to show label on x-axix, like you show for y-axix.
 
Actually i want to show number of visitors on y-axis and date on x-axis. So everyone get ideas about number of visitor for that specific date.
 
Thanks In advanced for help.
 
Help me solve this issue.
 
Thank Your,
Kashyap Patel
AnswerRe: How can i show titles for x-axis, like u show for y axis, value is 0.0, 20,00, and so on ?memberbecker66629 Aug '11 - 18:12 
Look at the code it loops thru the data for Y, just do the same for X
as u iterate for each x sample point right there you can draw the X-data
GeneralRe: How can i show titles for x-axis, like u show for y axis, value is 0.0, 20,00, and so on ?memberkp_iteng7 Sep '11 - 23:12 
Hello Dear,
 
I have your code. I am try but not get Values for x-axis.
Will you please Help me to do this?
Will you change on below code?
 
package com.testy;
 
import java.util.Vector;
 
import com.testy.R;
 
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.graphics.Bitmap.Config;
import android.graphics.Paint.FontMetrics;
import android.os.Bundle;
import android.widget.ImageView;
 
public class main extends Activity {


// these_labela has elemnes[label,maxX,maxY]
static int draw_only_this_idx = -1;
static int[] drawSizes;



@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.testy);
setTitle("Quick XY Plot");

ImageView image = (ImageView) findViewById(R.id.testy_img);


Bitmap emptyBmap = Bitmap.createBitmap(250,
200, Config.ARGB_8888);

int width = emptyBmap.getWidth();
int height = emptyBmap.getHeight();
Bitmap charty = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

charty = quicky_XY(emptyBmap);

image.setImageBitmap(charty);
}

public static Bitmap quicky_XY(Bitmap bitmap)
{
// xode to get bitmap onto screen
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);

final int color = 0xff0B0B61;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
final float roundPx = 12;

// get the little rounded cornered outside
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);


// ---- NOw just draw on this bitmap


// Set the labels info manually
String[] cur_elt_array = new String[4];
cur_elt_array[0]="Voltage";
cur_elt_array[1]="volts";
cur_elt_array[2]="93"; // max
cur_elt_array[3]="0"; //min

Vector labels = new Vector();
labels.add(cur_elt_array);

draw_the_grid(canvas,labels);


// se the data to be plotted and we should on our way

Vector data_2_plot = new Vector();
 
data_2_plot.add("0.2") ;
data_2_plot.add("1.2") ;
data_2_plot.add("9.6") ;
data_2_plot.add("83.2") ;
data_2_plot.add("44.2") ;
data_2_plot.add("20.2") ;
data_2_plot.add("16.2") ;

plot_array_list(canvas , data_2_plot , labels , "the title" , 0 );

canvas.drawBitmap(bitmap, rect, rect, paint);

return output;
}


// these_labels is vector of [label,units,max.min]

public static void draw_the_grid(Canvas this_g, Vector these_labels)
{

double rounded_max = 0.0;
double rounded_min = 0.0;
double rounded_max_temp;
Object curElt;
String[] cur_elt_array;
int left_margin_d, right_margin_d;


 
if( draw_only_this_idx == -1)
curElt = these_labels.elementAt(0); // default it to 1st one if non set
else
curElt = these_labels.elementAt(draw_only_this_idx); // now just the 1st elt

cur_elt_array = (String[])curElt;
 
rounded_max = get_ceiling_or_floor (Double.parseDouble(cur_elt_array[2]) , true);
rounded_min = get_ceiling_or_floor (Double.parseDouble(cur_elt_array[3]) , false);
 

// ok so now we have the max value of the set just get a cool ceiling and we go on
final Paint paint = new Paint();
paint.setTextSize(15);

left_margin_d = getCurTextLengthInPixels(paint, Double.toString(rounded_max));
//keep the position for later drawing -- leave space for the legend
int p_height = 170;
int p_width = 220;
int[] tmp_draw_sizes = {2 + left_margin_d, 25,p_width - 2 - left_margin_d ,p_height - 25 -5};
drawSizes = tmp_draw_sizes; //keep it for later processing
 

//with the mzrgins worked out draw the plotting grid
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE );

// Android does by coords
this_g.drawRect(drawSizes[0], drawSizes[1],drawSizes[0]+ drawSizes[2], drawSizes[1]+ drawSizes[3] , paint);


paint.setColor(Color.GRAY );


// finally draw the grid


paint.setStyle(Paint.Style.STROKE);
this_g.drawRect(drawSizes[0], drawSizes[1],drawSizes[0]+ drawSizes[2], drawSizes[1]+ drawSizes[3] , paint);
 
for(int i=1; i < 5 ; i++)
{
 
this_g.drawLine(drawSizes[0], drawSizes[1] + (i * drawSizes[3] / 5), drawSizes[0] + drawSizes[2], drawSizes[1] + (i * drawSizes[3] / 5), paint);
this_g.drawLine(drawSizes[0]+ (i * drawSizes[2] / 5), drawSizes[1], drawSizes[0] + (i * drawSizes[2] / 5), drawSizes[1] + drawSizes[3], paint);
 
}
 

// good for one value
print_axis_values_4_grid(this_g, cur_elt_array[1] , Double.toString(rounded_max) , Double.toString(rounded_min), cur_elt_array[0] , 2 ,0 );
 

} // --- end of draw_grid ---

// provate void print_axis_values_4_grid(Graphics thisDrawingArea, string cur_units , string cur_max , string cur_min , string cur_label , ByVal x_guide As Integer, ByVal this_idx As Integer)
public static void print_axis_values_4_grid(Canvas thisDrawingArea, String cur_units , String cur_max , String cur_min , String cur_label , int x_guide , int this_idx )
{
String this_str;
double delta = ( Double.valueOf(cur_max).doubleValue() - Double.valueOf(cur_min).doubleValue() ) / 5;
final Paint paint = new Paint();
 
paint.setColor( Color.WHITE );
paint.setTypeface( Typeface.SANS_SERIF );
 
//Font smallyFont = Font.getDefault().derive(Font.PLAIN, 12);
// thisDrawingArea.setFont(smallyFont);
paint.setTextSize(8);

 
for(int i = 0; i<6 ; i++)
{
// 'work our the values so is proper
 

this_str =Double.toString( (Double.valueOf(cur_min).doubleValue() + delta * i) );
 

final int point = this_str.indexOf('.');
if (point > 0) {
// If has a decimal point, may need to clip off after or force 2 decimal places
this_str = this_str + "00";
this_str = this_str.substring(0,point+3);
} else {
this_str = this_str + ".00";
}
 

if (i == 5)
// thisDrawingArea.drawText(this_str, x_guide - 2, drawSizes[1] + drawSizes[3] - (i *drawSizes[3] / 5) );
thisDrawingArea.drawText(this_str, x_guide - 2, drawSizes[1] + drawSizes[3] - (i *drawSizes[3] / 5) , paint );
else
thisDrawingArea.drawText(this_str, x_guide- 2, drawSizes[1] + drawSizes[3] - (i * drawSizes[3] / 5) -3, paint);
}
 
// smallyFont = Font.getDefault().derive(Font.BOLD, 12);
// thisDrawingArea.setFont(smallyFont);
paint.setTextSize(10);
switch(this_idx )
{
case 0:

thisDrawingArea.drawText(" " + cur_label +" - " +cur_units, x_guide - 2, drawSizes[1] -15 , paint);
break;

case 1:

// int len = getFont().getAdvance(cur_label +" - " +cur_units)

thisDrawingArea.drawText(" " + cur_label +" - " +cur_units, x_guide - 2 -30, drawSizes[1] -15, paint );
break;

}

 

} // --- end of print_axis_values_4_grid ---
 
private static Point scale_point(int this_x , double this_y , Point drawPoint ,
int scr_x , int scr_y , int scr_width , int src_height ,
double maxX , double minX , double maxY , double minY )
{
int temp_x, temp_y;
Point temp = new Point();

if (maxY == minY) //skip bad data
return null;
 
//don't touch it if is nothing
try
{
temp_x = scr_x + (int)( ((double)this_x - minX) * ((double)scr_width / (maxX - minX)) );
temp_y = scr_y + (int)( (maxY - this_y) * ((double)src_height / (maxY - minY)) );

temp.x = temp_x;
temp.y= temp_y;
drawPoint = temp;


}
catch (Exception e)
{

return (null);
}

return temp;

} // --- end of scale_point --
 
public static boolean plot_array_list(Canvas this_g, Vector this_array_list , Vector these_labels , String this_title , int only_this_idx )
{
int idx;
int lRow ;
int nParms;
int i, points_2_plot, shifted_idx ;
int prev_x, prev_y ;
int cur_x=0, cur_y=0 ;
//Dim ShowMarker As Object
Point cur_point = new Point();
cur_point.set(0,0);

double cur_maxX, cur_minX, cur_maxY=20, cur_minY=0, cur_rangeY;
int cur_start_x, cur_points_2_plot;

int POINTS_TO_CHANGE = 30;
double cur_OBD_val;

//Object curElt;
String curElt;
String[] cur_elt_array;
Object curElt2;
String[] cur_elt_array2;

final Paint paint = new Paint();
 
try // catch in this block for some thing
{

points_2_plot = this_array_list.size();
{
cur_start_x = 0;
cur_points_2_plot = points_2_plot;
cur_maxX = cur_points_2_plot;
cur_minX = 0;
}

//'Create the plot points for this series from the ChartPoints array:

curElt = (String)this_array_list.elementAt(0);

//the lines have to come out good
paint.setStyle(Paint.Style.STROKE);
//
//for( nParms = 0 ; nParms < cur_elt_array.length ; nParms++ )
nParms = only_this_idx;
{

//get cur item labels
curElt2 = these_labels.elementAt(nParms);
cur_elt_array2 = (String[]) curElt2;

cur_maxY = get_ceiling_or_floor (Double.parseDouble(cur_elt_array2[2]) , true);
cur_minY = get_ceiling_or_floor (Double.parseDouble(cur_elt_array2[3]) , false);

cur_points_2_plot = this_array_list.size();
cur_maxX = cur_points_2_plot;

curElt = (String)this_array_list.elementAt(0);
cur_OBD_val = Double.parseDouble( curElt);

cur_point = scale_point(0, cur_OBD_val, cur_point,
drawSizes[0], drawSizes[1], drawSizes[2], drawSizes[3],
cur_maxX, cur_minX, cur_maxY, cur_minY); //'(CInt(curAxisValues.Mins(nParms - 2) / 5) + 1) * 5)

cur_x = cur_point.x;
cur_y = cur_point.y;
 
paint.setColor(Color.GREEN);

// the point is only cool when samples are low
if ( cur_points_2_plot < POINTS_TO_CHANGE)
this_g.drawRect(cur_x-2, cur_y-2, cur_x-2 + 4,cur_y-2+ 4 , paint);

prev_x = cur_x;
prev_y = cur_y;
 

 
//'go and plot point for this parm -- pont after the 1st one
for (lRow = cur_start_x +1 ; lRow< cur_start_x + cur_points_2_plot -1 ; lRow++)
{

curElt = (String)this_array_list.elementAt(lRow);

cur_OBD_val = Double.parseDouble( curElt);




//'work out an approx if cur Y values not avail(e.g. nothing)
// if (! (cur_elt_array[nParms ] == null ) ) //skip bad one
if( cur_OBD_val == Double.NaN) continue; //skip bad one
{


cur_point=scale_point(lRow, cur_OBD_val, cur_point,
drawSizes[0], drawSizes[1], drawSizes[2], drawSizes[3],
cur_maxX, cur_minX, cur_maxY, cur_minY);

cur_x = cur_point.x;
cur_y = cur_point.y;

if ( cur_points_2_plot < POINTS_TO_CHANGE)
this_g.drawRect(cur_x-2, cur_y-2, cur_x-2 +4, cur_y-2 + 4, paint );

this_g.drawLine( prev_x, prev_y, cur_x, cur_y, paint);
prev_x = cur_x;
prev_y = cur_y;

} // ' if end of this_array(lRow, nParms - 1)<> nothing

} // end of for lrow

} // end of for nParmns
 

//this_g.invalidate();
return( true);
}
catch (Exception e)
{
return( false);

}
 
} // --- end of plot_array_list --
 

// need the width of the labels
private static int getCurTextLengthInPixels(Paint this_paint, String this_text) {
FontMetrics tp = this_paint.getFontMetrics();
Rect rect = new Rect();
this_paint.getTextBounds(this_text, 0, this_text.length(), rect);
return rect.width();
} // --- end of getCurTextLengthInPixels ---
 

public static double get_ceiling_or_floor(double this_val , boolean is_max )
{
double this_min_tmp;
int this_sign;
int this_10_factor=0;
double this_rounded;
 
if (this_val == 0.0)
{
this_rounded = 0.0;
return this_rounded;
}
 
this_min_tmp = Math.abs(this_val);
 
if (this_min_tmp >= 1.0 && this_min_tmp < 10.0)
this_10_factor = 1;
else if (this_min_tmp >= 10.0 && this_min_tmp < 100.0)
this_10_factor = 10;
else if (this_min_tmp >= 100.0 && this_min_tmp < 1000.0)
this_10_factor = 100;
else if (this_min_tmp >= 1000.0 && this_min_tmp < 10000.0)
this_10_factor = 1000;
else if (this_min_tmp >= 10000.0 && this_min_tmp < 100000.0)
this_10_factor = 10000;

 

//'cover when min is pos and neg
if (is_max)
{
if (this_val > 0.0)
this_sign = 1;
else
this_sign = -1;

}
else
{
if (this_val > 0.0)
this_sign = -1;
else
this_sign = 1;

}
 

if (this_min_tmp > 1)
this_rounded = (double)(((int)(this_min_tmp / this_10_factor) + this_sign) * this_10_factor);
else
{
this_rounded = (int)(this_min_tmp * 100.0);
//' cover same as above bfir number up to .001 less than tha it will skip
if (this_rounded >= 1 && this_rounded < 9)
this_10_factor = 1;
else if (this_rounded >= 10 && this_rounded < 99)
this_10_factor = 10;
else if (this_rounded >= 100 && this_rounded < 999)
this_10_factor = 100;

this_rounded = (double)(((int)((this_rounded) / this_10_factor) + this_sign) * this_10_factor);
this_rounded = (int)(this_rounded) / 100.0;
 
}
 
if (this_val < 0)
this_rounded = -this_rounded;

return this_rounded;
 
} // --- end of get_ceiling_or_floor ---
 



}
Generalscale pbmemberkingpio7 Jun '11 - 0:20 
great tutorial!
 
how do you edit the scale on the horizontal axis though? And with 7 values why are only 6 shown?
 
thx
Questionquicky_XY?memberAndroidAnnie23 Mar '11 - 12:27 
I admire greatly the results, but judging from the other responses, I'm evidently the only one who doesn't get this.
 
Where is quicky_XY defined?

modified on Wednesday, March 23, 2011 6:34 PM

AnswerRe: quicky_XY?memberbecker66623 Mar '11 - 12:48 
AndroidAnnie
 
Download the source code and you'll see it.
 
Cheers
 
Becker
GeneralRe: quicky_XY?memberAndroidAnnie23 Mar '11 - 14:40 
*Face palm* Oh, great. What am I supposed to do with all this code I just typed in by hand?
JJ - download worked superbly. Nice work. Many thanks.
GeneralNice introductionmemberAlex Kucherenko6 Mar '11 - 21:49 
I think you should also have to take a look on existing commercial solutions, for example:
 
http://www.artfulbits.com/products/android/aicharts.aspx[^]
http://code.google.com/p/chartdroid/[^]
http://www.jfree.org/jfreechart/[^]
http://www.java4less.com/charts/chart.php?info=android[^]
http://www.achartengine.org/index.html[^] or http://code.google.com/p/achartengine/[^]
http://androidplot.com/wiki/Home[^]
http://www.steema.com/[^]
http://www.keepedge.com/products/android_charting/[^]
http://www.kidroid.com/kichart/[^]
 
Some of them are free and open source.
Good Luck
Alex Kucherenko

GeneralMy vote of 5memberBosah Chude4 Mar '11 - 2:06 
Excellent Post
GeneralMy vote of 5membergourav vaidya28 Feb '11 - 22:37 
Nice Tutorial
GeneralMy vote of 5memberMember 438714325 Aug '10 - 2:02 
Excelent One

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130516.1 | Last Updated 27 Jul 2010
Article Copyright 2010 by becker666
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid