<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>graph Archives - Truiton</title>
	<atom:link href="https://www.truiton.com/tag/graph/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>Technology Reaching Us In Time - Online</description>
	<lastBuildDate>Mon, 25 Nov 2019 13:04:01 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://i0.wp.com/www.truiton.com/wp-content/uploads/2022/11/cropped-truiton_new_logo_half_white.png?fit=32%2C32&#038;ssl=1</url>
	<title>graph Archives - Truiton</title>
	<link></link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">54534495</site>	<item>
		<title>Android Chart Example: MP Android Chart library</title>
		<link>https://www.truiton.com/2015/04/android-chart-example-mp-android-chart-library/</link>
					<comments>https://www.truiton.com/2015/04/android-chart-example-mp-android-chart-library/#comments</comments>
		
		<dc:creator><![CDATA[Mohit Gupt]]></dc:creator>
		<pubDate>Mon, 20 Apr 2015 13:27:43 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[chart]]></category>
		<category><![CDATA[graph]]></category>
		<guid isPermaLink="false">http://www.truiton.com/?p=1174</guid>

					<description><![CDATA[<p>Now days when building business apps, or fitness apps, one of the common UI component used is a chart. But drawing a chart through graphics could take a lot of time and would slow down your development. Therefore to fast pace your development, many open source libraries are available online. One of those libraries is&#8230;&#160;<a href="https://www.truiton.com/2015/04/android-chart-example-mp-android-chart-library/" rel="bookmark">Read More &#187;<span class="screen-reader-text">Android Chart Example: MP Android Chart library</span></a></p>
<p>The post <a href="https://www.truiton.com/2015/04/android-chart-example-mp-android-chart-library/">Android Chart Example: MP Android Chart library</a> appeared first on <a href="https://www.truiton.com">Truiton</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-image"><figure class="aligncenter"><a href="https://www.flickr.com/photos/teegardin/6093690339"><img data-recalc-dims="1" fetchpriority="high" decoding="async" width="950" height="534" data-attachment-id="1177" data-permalink="https://www.truiton.com/2015/04/android-chart-example-mp-android-chart-library/android-chart-example-mpandroidchart/" data-orig-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2015/04/Android-Chart-Example-MPAndroidChart.jpg?fit=950%2C534&amp;ssl=1" data-orig-size="950,534" data-comments-opened="1" data-image-title="Android Chart Example MPAndroidChart" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2015/04/Android-Chart-Example-MPAndroidChart.jpg?fit=950%2C534&amp;ssl=1" src="https://i0.wp.com/www.truiton.com/wp-content/uploads/2015/04/Android-Chart-Example-MPAndroidChart.jpg?resize=950%2C534" alt="Photo Credit: Ken Teegardin - Android Chart Example MPAndroidChart" class="wp-image-1177" srcset="https://i0.wp.com/www.truiton.com/wp-content/uploads/2015/04/Android-Chart-Example-MPAndroidChart.jpg?w=950&amp;ssl=1 950w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2015/04/Android-Chart-Example-MPAndroidChart.jpg?resize=600%2C337&amp;ssl=1 600w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2015/04/Android-Chart-Example-MPAndroidChart.jpg?resize=300%2C169&amp;ssl=1 300w" sizes="(max-width: 950px) 100vw, 950px" /></a></figure></div>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Now days when building business apps, or fitness apps, one of the common UI component used is a chart. But drawing a chart through graphics could take a lot of time and would slow down your development. Therefore to fast pace your development, many open source libraries are available online. One of those libraries is <a title="MP Android Chart" href="https://github.com/PhilJay/MPAndroidChart" target="_blank" rel="noopener noreferrer">MPAndroidChart</a> by <a title="Phil Jay" href="https://github.com/PhilJay" target="_blank" rel="noopener noreferrer">Phil Jay</a>, this library when compared to other chart libraries, is comparatively new. But still it is very stable and is starred by more than 3K users on GitHub. By using MP Chart library for Android, displaying graphs or charts is much simpler now as it also supports customization and animation of graphs. Therefore in this Android chart example, I would make a bar chart, using MPAndroidChart library.</p>



<p class="wp-block-paragraph">As I mentioned above, MP Android Chart library is not the only library available for drawing charts on Android. I would like to mention here that this Android Chart Example is the fifth in line to my series on displaying graphs on Android. Please go through them to choose a best approach for your project, as different projects have different requirements:</p>



<ol class="wp-block-list"><li><a title="Android Tutorial- Using Google Chart Tools With SVG and Image API" href="http://www.truiton.com/2013/04/android-tutorial-using-google-chart-tools-with-svg-and-image-api/" target="_blank" rel="noopener noreferrer">Google Chart Tools- Latest Chart Tools</a></li><li><a title="Android Tutorial- Using Google Chart Tools With SVG and Image API" href="http://www.truiton.com/2013/04/android-tutorial-using-google-chart-tools-with-svg-and-image-api/" target="_blank" rel="noopener noreferrer">Google Chart Tools: Image Tools</a>&#8211; <em>Deprecated</em></li><li><a title="Android Tutorial- Introduction to AFreeChart with Sample" href="http://www.truiton.com/2013/04/android-tutorial-introduction-to-afreechart-with-sample/" target="_blank" rel="noopener noreferrer">AFreeChart Library</a></li><li><a title="Android Tutorial- Drawing AChartEngine Bar Chart with Example" href="http://www.truiton.com/2013/04/android-tutorial-drawing-achartengine-bar-chart-with-example/" target="_blank" rel="noopener noreferrer">AChartEngine Library</a></li><li><a title="Android Chart Example: MP Android Chart library" href="http://www.truiton.com/2015/04/android-chart-example-mp-android-chart-library/">Android MP Chart Library</a></li></ol>



<h2 class="wp-block-heading">MP Android Chart Library Example</h2>



<p class="wp-block-paragraph">Using these libraries, drawing charts on Android could never be simpler.&nbsp;MPAndroidChart library works on Android API 8 and above, but if you are using animations, it works on API 11 and above. Animations is one of the greatest features apart from easy data input, this library could have. Some how I feel animations give good user experience to an application. Through MPAndroidChart library, we can use more than 25 inbuilt animations, also can define custom animations. When making charts on <a title="Android MP Chart Library" href="https://github.com/PhilJay/MPAndroidChart" target="_blank" rel="noopener noreferrer">Android MPAndroidChart library</a> which falls under the Apache 2.0 license, we can draw a:</p>



<ul class="wp-block-list"><li>Simple Bar Chart</li><li>Grouped Bar Chart</li><li>Horizontal Bar Chart</li><li>Simple Line Chart</li><li>Line Chart with Cubic Lines</li><li>Grouped Line Chart</li><li>Combined Line and Bar Chart</li><li>Pie Chart</li><li>Scatter Chart</li><li>Candlestick Chart</li><li>Radar Chart</li></ul>


<div style="width: 640px;" class="wp-video"><video class="wp-video-shortcode" id="video-1174-1" width="640" height="400" loop autoplay preload="metadata" controls="controls"><source type="video/mp4" src="http://www.truiton.com/wp-content/uploads/2015/04/MP-Android-Chart.mp4?_=1" /><a href="http://www.truiton.com/wp-content/uploads/2015/04/MP-Android-Chart.mp4">http://www.truiton.com/wp-content/uploads/2015/04/MP-Android-Chart.mp4</a></video></div>



<p class="wp-block-paragraph">Moving forward in this tutorial, we will make a grouped bar chart, with animation as shown in the animation above. To start first add these in your gradle file:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">repositories {
    maven { url "https://jitpack.io" }
}

dependencies {
    compile 'com.github.PhilJay:MPAndroidChart:v2.0.9'
}</pre>



<p class="wp-block-paragraph">Next lets create a layout for MP Android Chart Example:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="xml" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:paddingLeft="@dimen/activity_horizontal_margin"
                android:paddingRight="@dimen/activity_horizontal_margin"
                android:paddingTop="@dimen/activity_vertical_margin"
                android:paddingBottom="@dimen/activity_vertical_margin"
                tools:context=".MainActivity">

    &lt;com.github.mikephil.charting.charts.BarChart
        android:id="@+id/chart"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

&lt;/RelativeLayout>
</pre>



<p class="wp-block-paragraph">As you can see in the above layout, I have used <code>com.github.mikephil.charting.charts.BarChart</code> xml tag to create an Android bar chart example. But if you plan on to create different charts with MPAndroidChart library don&#8217;t forget to change the tag as shown below.</p>



<div class="wp-block-image"><figure class="aligncenter"><img data-recalc-dims="1" decoding="async" width="701" height="263" data-attachment-id="1180" data-permalink="https://www.truiton.com/2015/04/android-chart-example-mp-android-chart-library/android-mpchart-types/" data-orig-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2015/04/Android-MPChart-Types.jpg?fit=701%2C263&amp;ssl=1" data-orig-size="701,263" data-comments-opened="1" data-image-title="Android MPChart Types" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2015/04/Android-MPChart-Types.jpg?fit=701%2C263&amp;ssl=1" src="https://i0.wp.com/www.truiton.com/wp-content/uploads/2015/04/Android-MPChart-Types.jpg?resize=701%2C263" alt="Android MPChart Types" class="wp-image-1180" srcset="https://i0.wp.com/www.truiton.com/wp-content/uploads/2015/04/Android-MPChart-Types.jpg?w=701&amp;ssl=1 701w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2015/04/Android-MPChart-Types.jpg?resize=600%2C225&amp;ssl=1 600w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2015/04/Android-MPChart-Types.jpg?resize=300%2C113&amp;ssl=1 300w" sizes="(max-width: 701px) 100vw, 701px" /></figure></div>



<p class="wp-block-paragraph">Next lets have a look at the activity code:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="java" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">package com.truiton.mpchartexample;

import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;

import com.github.mikephil.charting.charts.BarChart;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.utils.ColorTemplate;

import java.util.ArrayList;

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        BarChart chart = (BarChart) findViewById(R.id.chart);

        BarData data = new BarData(getXAxisValues(), getDataSet());
        chart.setData(data);
        chart.setDescription("My Chart");
        chart.animateXY(2000, 2000);
        chart.invalidate();
    }

    private ArrayList&lt;BarDataSet&gt; getDataSet() {
        ArrayList&lt;BarDataSet&gt; dataSets = null;

        ArrayList&lt;BarEntry&gt; valueSet1 = new ArrayList&lt;&gt;();
        BarEntry v1e1 = new BarEntry(110.000f, 0); // Jan
        valueSet1.add(v1e1);
        BarEntry v1e2 = new BarEntry(40.000f, 1); // Feb
        valueSet1.add(v1e2);
        BarEntry v1e3 = new BarEntry(60.000f, 2); // Mar
        valueSet1.add(v1e3);
        BarEntry v1e4 = new BarEntry(30.000f, 3); // Apr
        valueSet1.add(v1e4);
        BarEntry v1e5 = new BarEntry(90.000f, 4); // May
        valueSet1.add(v1e5);
        BarEntry v1e6 = new BarEntry(100.000f, 5); // Jun
        valueSet1.add(v1e6);

        ArrayList&lt;BarEntry&gt; valueSet2 = new ArrayList&lt;&gt;();
        BarEntry v2e1 = new BarEntry(150.000f, 0); // Jan
        valueSet2.add(v2e1);
        BarEntry v2e2 = new BarEntry(90.000f, 1); // Feb
        valueSet2.add(v2e2);
        BarEntry v2e3 = new BarEntry(120.000f, 2); // Mar
        valueSet2.add(v2e3);
        BarEntry v2e4 = new BarEntry(60.000f, 3); // Apr
        valueSet2.add(v2e4);
        BarEntry v2e5 = new BarEntry(20.000f, 4); // May
        valueSet2.add(v2e5);
        BarEntry v2e6 = new BarEntry(80.000f, 5); // Jun
        valueSet2.add(v2e6);

        BarDataSet barDataSet1 = new BarDataSet(valueSet1, "Brand 1");
        barDataSet1.setColor(Color.rgb(0, 155, 0));
        BarDataSet barDataSet2 = new BarDataSet(valueSet2, "Brand 2");
        barDataSet2.setColors(ColorTemplate.COLORFUL_COLORS);

        dataSets = new ArrayList&lt;&gt;();
        dataSets.add(barDataSet1);
        dataSets.add(barDataSet2);
        return dataSets;
    }

    private ArrayList&lt;String&gt; getXAxisValues() {
        ArrayList&lt;String&gt; xAxis = new ArrayList&lt;&gt;();
        xAxis.add("JAN");
        xAxis.add("FEB");
        xAxis.add("MAR");
        xAxis.add("APR");
        xAxis.add("MAY");
        xAxis.add("JUN");
        return xAxis;
    }
}
</pre>



<p class="wp-block-paragraph">This would result in a great looking bar chart like this:</p>



<div class="wp-block-image"><figure class="aligncenter"><img data-recalc-dims="1" decoding="async" width="700" height="373" data-attachment-id="1181" data-permalink="https://www.truiton.com/2015/04/android-chart-example-mp-android-chart-library/android-chart-mp/" data-orig-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2015/04/Android-Chart-MP.png?fit=700%2C373&amp;ssl=1" data-orig-size="700,373" data-comments-opened="1" data-image-title="Android Chart MP" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2015/04/Android-Chart-MP.png?fit=700%2C373&amp;ssl=1" src="https://i0.wp.com/www.truiton.com/wp-content/uploads/2015/04/Android-Chart-MP.png?resize=700%2C373" alt="Android Bar Chart MP" class="wp-image-1181" srcset="https://i0.wp.com/www.truiton.com/wp-content/uploads/2015/04/Android-Chart-MP.png?w=700&amp;ssl=1 700w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2015/04/Android-Chart-MP.png?resize=600%2C320&amp;ssl=1 600w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2015/04/Android-Chart-MP.png?resize=300%2C160&amp;ssl=1 300w" sizes="(max-width: 700px) 100vw, 700px" /></figure></div>



<p class="wp-block-paragraph">Now lets understand how MPAndroidChart library works. As shown in the above class, first a <code>BarChart</code> is initialized. Then data according to the bar chart is generated using the <code>BarEntry</code> class. This is a subclass of <code>Entry</code> class, which is the base class for all chart data types in MPAndroidChart library. Further this <code>BarEntry</code> is added into <code>BarDataSet</code>. Then all of these values along with X axis values are set in the bar chart using <code>chart.setData(data)</code> method. Now to make the bar chart reflect this latest data, we need to call&nbsp;<code>chart.invalidate()</code> method. This would result into a great looking bar chart as shown above.</p>



<p class="wp-block-paragraph">As I mentioned, MPAndroidChart library is customizable, lets have a look at some of its key features:</p>



<h3 class="wp-block-heading">MP Android Chart Animations</h3>



<p class="wp-block-paragraph">To animate a chart from MPAndroidChart library these methods are used:</p>



<ul class="wp-block-list"><li><code>chart.animateX(2000)</code> &#8211; For X axis animation</li><li><code>chart.animateY(2000)</code> &#8211; For Y axis animation</li><li><code>chart.animateXY(2000, 2000)</code> &#8211; For XY axis animation</li></ul>



<p class="wp-block-paragraph">Although, above code would do a standard animation. But if you wish to change the animation style or want to make a custom animation, refer to <a title="MPAndroid Chart Animations" href="https://github.com/PhilJay/MPAndroidChart/wiki/Animations" target="_blank" rel="noopener noreferrer">this page</a>. Please note animations would work only on API 11 and above.</p>



<h3 class="wp-block-heading">MP Android Chart Colors</h3>



<p class="wp-block-paragraph">While making charts on Android using MPAndroidChart library, you can also change the color of bars in the chart by using these methods:</p>



<ul class="wp-block-list"><li><code>setColor</code> &#8211; used to set a single color to full data set.</li><li><code>setColors</code> &#8211; used to set&nbsp;entries in different colors, in a data set.</li></ul>



<p class="wp-block-paragraph">These methods are used while creating the <code>DataSet</code> object as shown above.</p>



<h2 class="wp-block-heading">Conclusion</h2>



<p class="wp-block-paragraph">With this I would like to conclude by saying, <a title="Android MP Chart Library" href="https://github.com/PhilJay/MPAndroidChart" target="_blank" rel="noopener noreferrer">MPAndroidChart</a> is a great library. Above I showed an <a title="Android Chart Example: MP Android Chart library" href="http://www.truiton.com/2015/04/android-chart-example-mp-android-chart-library/">Android chart example</a>, for bar chart, using this library. But if you wish to make other types of charts, you may just need to change the class names. As MP Chart library is designed in such a way that most of the charts input data in same way. Hope this helped. Connect with us on Facebook, Google+ and Twitter for more updates.</p>
<div class="saboxplugin-wrap" itemtype="http://schema.org/Person" itemscope itemprop="author"><div class="saboxplugin-tab"><div class="saboxplugin-gravatar"><img alt='Mohit Gupt' src='https://secure.gravatar.com/avatar/a816092ad56645d2635ccfceb9f7e9d44821c19dec126cb394c882ba574eaa04?s=100&#038;d=mm&#038;r=g' srcset='https://secure.gravatar.com/avatar/a816092ad56645d2635ccfceb9f7e9d44821c19dec126cb394c882ba574eaa04?s=200&#038;d=mm&#038;r=g 2x' class='avatar avatar-100 photo' height='100' width='100' itemprop="image"/></div><div class="saboxplugin-authorname"><a href="https://www.truiton.com/author/mohitgupt/" class="vcard author" rel="author"><span class="fn">Mohit Gupt</span></a></div><div class="saboxplugin-desc"><div itemprop="description"><p>Born in New Delhi, India. A software engineer by profession, an android enthusiast and mobile development evangelist. My motive here is to create a group of skilled engineers, who can build better software. Reason being programming is my passion, and also it feels good to make a device do something you want. Professionally I have worked with many software engineering and product development firms. As of now too, I am employed as a senior engineer in a leading tech company. In total I may have worked on more than 20 projects professionally, but whenever I get spare time I share my thoughts here at Truiton.</p>
</div></div><div class="saboxplugin-web "><a href="http://www.truiton.com" target="_self" >www.truiton.com</a></div><div class="clearfix"></div><div class="saboxplugin-socials "><a title="Wordpress" target="_blank" href="https://www.truiton.com/author/mohitgupt/" rel="nofollow noopener" class="saboxplugin-icon-grey"><svg aria-hidden="true" class="sab-wordpress" role="img" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 512 512"><path fill="currentColor" d="M61.7 169.4l101.5 278C92.2 413 43.3 340.2 43.3 256c0-30.9 6.6-60.1 18.4-86.6zm337.9 75.9c0-26.3-9.4-44.5-17.5-58.7-10.8-17.5-20.9-32.4-20.9-49.9 0-19.6 14.8-37.8 35.7-37.8.9 0 1.8.1 2.8.2-37.9-34.7-88.3-55.9-143.7-55.9-74.3 0-139.7 38.1-177.8 95.9 5 .2 9.7.3 13.7.3 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l77.5 230.4L249.8 247l-33.1-90.8c-11.5-.7-22.3-2-22.3-2-11.5-.7-10.1-18.2 1.3-17.5 0 0 35.1 2.7 56 2.7 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l76.9 228.7 21.2-70.9c9-29.4 16-50.5 16-68.7zm-139.9 29.3l-63.8 185.5c19.1 5.6 39.2 8.7 60.1 8.7 24.8 0 48.5-4.3 70.6-12.1-.6-.9-1.1-1.9-1.5-2.9l-65.4-179.2zm183-120.7c.9 6.8 1.4 14 1.4 21.9 0 21.6-4 45.8-16.2 76.2l-65 187.9C426.2 403 468.7 334.5 468.7 256c0-37-9.4-71.8-26-102.1zM504 256c0 136.8-111.3 248-248 248C119.2 504 8 392.7 8 256 8 119.2 119.2 8 256 8c136.7 0 248 111.2 248 248zm-11.4 0c0-130.5-106.2-236.6-236.6-236.6C125.5 19.4 19.4 125.5 19.4 256S125.6 492.6 256 492.6c130.5 0 236.6-106.1 236.6-236.6z"></path></svg></span></a><a title="Twitter" target="_blank" href="http://twitter.com/mohitgupt" rel="nofollow noopener" class="saboxplugin-icon-grey"><svg aria-hidden="true" class="sab-twitter" role="img" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 30 30"><path d="M26.37,26l-8.795-12.822l0.015,0.012L25.52,4h-2.65l-6.46,7.48L11.28,4H4.33l8.211,11.971L12.54,15.97L3.88,26h2.65 l7.182-8.322L19.42,26H26.37z M10.23,6l12.34,18h-2.1L8.12,6H10.23z" /></svg></span></a><a title="Facebook" target="_blank" href="https://www.facebook.com/Mr.Mohit.Gupt" rel="nofollow noopener" class="saboxplugin-icon-grey"><svg aria-hidden="true" class="sab-facebook" role="img" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 264 512"><path fill="currentColor" d="M76.7 512V283H0v-91h76.7v-71.7C76.7 42.4 124.3 0 193.8 0c33.3 0 61.9 2.5 70.2 3.6V85h-48.2c-37.8 0-45.1 18-45.1 44.3V192H256l-11.7 91h-73.6v229"></path></svg></span></a></div></div></div><p>The post <a href="https://www.truiton.com/2015/04/android-chart-example-mp-android-chart-library/">Android Chart Example: MP Android Chart library</a> appeared first on <a href="https://www.truiton.com">Truiton</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.truiton.com/2015/04/android-chart-example-mp-android-chart-library/feed/</wfw:commentRss>
			<slash:comments>24</slash:comments>
		
		<enclosure url="http://www.truiton.com/wp-content/uploads/2015/04/MP-Android-Chart.mp4" length="361997" type="video/mp4" />

		<post-id xmlns="com-wordpress:feed-additions:1">1174</post-id>	</item>
		<item>
		<title>Android Tutorial- Drawing AChartEngine Bar Chart with Example</title>
		<link>https://www.truiton.com/2013/04/android-tutorial-drawing-achartengine-bar-chart-with-example/</link>
					<comments>https://www.truiton.com/2013/04/android-tutorial-drawing-achartengine-bar-chart-with-example/#comments</comments>
		
		<dc:creator><![CDATA[Mohit Gupt]]></dc:creator>
		<pubDate>Sun, 07 Apr 2013 07:24:49 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[graph]]></category>
		<guid isPermaLink="false">http://blog.truiton.com/?p=169</guid>

					<description><![CDATA[<p>As I said earlier all business applications are required to display some amount of graphical data, steps in Android AChartEngine Library. At Truiton our specialization is development of business mobile apps, therefore I thought to share some knowledge about it. In one of my previous tutorials I suggested a way to display graphical data with&#8230;&#160;<a href="https://www.truiton.com/2013/04/android-tutorial-drawing-achartengine-bar-chart-with-example/" rel="bookmark">Read More &#187;<span class="screen-reader-text">Android Tutorial- Drawing AChartEngine Bar Chart with Example</span></a></p>
<p>The post <a href="https://www.truiton.com/2013/04/android-tutorial-drawing-achartengine-bar-chart-with-example/">Android Tutorial- Drawing AChartEngine Bar Chart with Example</a> appeared first on <a href="https://www.truiton.com">Truiton</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-image"><figure class="aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" width="500" height="361" data-attachment-id="175" data-permalink="https://www.truiton.com/2013/04/android-tutorial-drawing-achartengine-bar-chart-with-example/box-design/" data-orig-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2013/04/99568280_488943b5a2_z.jpg?fit=500%2C361&amp;ssl=1" data-orig-size="500,361" data-comments-opened="1" data-image-title="box design" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2013/04/99568280_488943b5a2_z.jpg?fit=500%2C361&amp;ssl=1" src="https://i0.wp.com/www.truiton.com/wp-content/uploads/2013/04/99568280_488943b5a2_z.jpg?resize=500%2C361" alt="box design" class="wp-image-175" srcset="https://i0.wp.com/www.truiton.com/wp-content/uploads/2013/04/99568280_488943b5a2_z.jpg?w=500&amp;ssl=1 500w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2013/04/99568280_488943b5a2_z.jpg?resize=300%2C216&amp;ssl=1 300w" sizes="auto, (max-width: 500px) 100vw, 500px" /></figure></div>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">As I said earlier all business applications are required to display some amount of graphical data, steps in Android AChartEngine Library. At <a title="Truiton" href="http://www.truiton.com" target="_blank" rel="noopener noreferrer">Truiton</a> our specialization is development of business mobile apps, therefore I thought to share some knowledge about it. In one of my previous <a title="Android Tutorial- Using Google Chart Tools With SVG and Image API" href="http://www.truiton.com/2013/04/android-tutorial-using-google-chart-tools-with-svg-and-image-api/" target="_blank" rel="noopener noreferrer">tutorials</a> I suggested a way to display graphical data with Google Charts, but it had a major draw back i.e. it required internet connectivity. To overcome this here I suggest we use Android <a title="AChartEngine Project Page" href="http://code.google.com/p/achartengine/" target="_blank" rel="noopener noreferrer">AChartEngine</a>, which is a charting library licensed under <a title="Apache Lincense 2.0" href="http://www.apache.org/licenses/LICENSE-2.0" target="_blank" rel="noopener noreferrer">Apache License 2.0</a>.</p>



<p class="wp-block-paragraph">This Android AChartEngine Tutorial is the final addition to my series of tutorials on displaying charts on Android. This tutorial is number four in the list below:</p>



<ol class="wp-block-list"><li>Google Chart Tools- Latest Chart Tools – <a title="Android Tutorial- Using Google Chart Tools With SVG and Image API" href="http://www.truiton.com/2013/04/android-tutorial-using-google-chart-tools-with-svg-and-image-api/" target="_blank" rel="noopener noreferrer">Android Tutorial- Google Chart Tools</a></li><li>Google Chart Tools: Image Tools- Deprecated – <a title="Android Tutorial- Using Google Chart Tools With SVG and Image API" href="http://www.truiton.com/2013/04/android-tutorial-using-google-chart-tools-with-svg-and-image-api/" target="_blank" rel="noopener noreferrer">Android Tutorial- Google Chart Tools Image API</a></li><li>AFreeChart- <a title="Android Tutorial- Introduction to AFreeChart with Sample" href="http://www.truiton.com/2013/04/android-tutorial-introduction-to-afreechart-with-sample/" target="_blank" rel="noopener noreferrer">Android Tutorial- AFreeChart</a></li><li>AChartEngine- <a title="Android Tutorial- Drawing AChartEngine Bar Chart with Example" href="http://www.truiton.com/2013/04/android-tutorial-drawing-achartengine-bar-chart-with-example/" target="_blank" rel="noopener noreferrer">Android Tutorial- Drawing AChartEngine Bar Chart with Example</a></li><li>MPAndroidChart &#8211; <a title="Android Chart Example: MP Android Chart library" href="http://www.truiton.com/2015/04/android-chart-example-mp-android-chart-library/" target="_blank" rel="noopener noreferrer">Android MP Chart Library</a></li></ol>



<p class="wp-block-paragraph">Android AChartEngine Library is a free library which can be used to display graphs/charts on any Android OS based devices. AChartEngine supports many chart types like: Line Chart, Area Chart, Scatter Chart, Time Chart, Bar Chart, Pie Chart, Bubble Chart, Doughnut Chart, Range(high-low) Bar Chart, Dial/Gauge Chart, Combined Chart, and Cubic Line Chart. One of the most intriguing feature of Android AChartEngine is that it can combine all these charts into a single chart and can use multiple data series.</p>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">For this Android AChartEngine tutorial I am using library version 1.0.0 which is compatible for all android devices above 1.6 version. This could be downloaded from here:</p>



<p class="wp-block-paragraph"><a href="http://achartengine.googlecode.com/files/achartengine-1.0.0.jar">http://achartengine.googlecode.com/files/achartengine-1.0.0.jar</a></p>



<p class="wp-block-paragraph">This a highly stable release which can display thousands of values in a single graph, while maintaining the smoothness in interaction with graph. Now to start plotting the graph all we have to do is include the above <em>.jar</em> file in our project&#8217;s build path.</p>



<p class="wp-block-paragraph">As this tutorial is an introduction to Android AChartEngine I am only going to show how to create an independent class and display bar charts. For this purpose lets create a <strong>TruitonAChartEngineActivity.java</strong> class as <em>MAIN LAUNCHER</em> class.</p>



<p class="wp-block-paragraph">In that class lets create a method for data set in our Android AChartEngine bar chart:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="java" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""> private XYMultipleSeriesDataset getTruitonBarDataset() {
 XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
 final int nr = 4;
 Random r = new Random();
 ArrayList&lt;String> legendTitles = new ArrayList&lt;String>();
 legendTitles.add("Sales");
 legendTitles.add("Expenses");
 for (int i = 0; i &lt; SERIES_NR; i++) {
 CategorySeries series = new CategorySeries(legendTitles.get(i));
 for (int k = 0; k &lt; nr; k++) {
 series.add(100 + r.nextInt() % 100);
 }
 dataset.addSeries(series.toXYSeries());
 }
 return dataset;
 }</pre>



<p class="wp-block-paragraph">Next to display Android AChartEngine bar chart we need to create a bars renderer :</p>



<pre class="EnlighterJSRAW" data-enlighter-language="java" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""> public XYMultipleSeriesRenderer getTruitonBarRenderer() {
 XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
 renderer.setAxisTitleTextSize(16);
 renderer.setChartTitleTextSize(20);
 renderer.setLabelsTextSize(15);
 renderer.setLegendTextSize(15);
 renderer.setMargins(new int[] { 30, 40, 15, 0 });
 SimpleSeriesRenderer r = new SimpleSeriesRenderer();
 r.setColor(Color.BLUE);
 renderer.addSeriesRenderer(r);
 r = new SimpleSeriesRenderer();
 r.setColor(Color.RED);
 renderer.addSeriesRenderer(r);
 return renderer;
 }</pre>



<p class="wp-block-paragraph">All this code would look a little more in place inside the whole class:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="java" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">package com.truiton.myachartengine;

import java.util.ArrayList;
import java.util.Random;

import org.achartengine.ChartFactory;
import org.achartengine.chart.BarChart.Type;
import org.achartengine.model.CategorySeries;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.renderer.SimpleSeriesRenderer;
import org.achartengine.renderer.XYMultipleSeriesRenderer;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Paint.Align;
import android.view.Menu;

public class TruitonAChartEngineActivity extends Activity {
 private static final int SERIES_NR = 2;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_truiton_achart_engine);
 XYMultipleSeriesRenderer renderer = getTruitonBarRenderer();
 myChartSettings(renderer);
 Intent intent = ChartFactory.getBarChartIntent(this, getTruitonBarDataset(), renderer, Type.DEFAULT);
 startActivity(intent);
 }

 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
 // Inflate the menu; this adds items to the action bar if it is present.
 getMenuInflater().inflate(R.menu.truiton_achart_engine, menu);
 return true;
 }

 private XYMultipleSeriesDataset getTruitonBarDataset() {
 XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
 final int nr = 4;
 Random r = new Random();
 ArrayList&lt;String> legendTitles = new ArrayList&lt;String>();
 legendTitles.add("Sales");
 legendTitles.add("Expenses");
 for (int i = 0; i &lt; SERIES_NR; i++) {
 CategorySeries series = new CategorySeries(legendTitles.get(i));
 for (int k = 0; k &lt; nr; k++) {
 series.add(100 + r.nextInt() % 100);
 }
 dataset.addSeries(series.toXYSeries());
 }
 return dataset;
 }

 public XYMultipleSeriesRenderer getTruitonBarRenderer() {
 XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
 renderer.setAxisTitleTextSize(16);
 renderer.setChartTitleTextSize(20);
 renderer.setLabelsTextSize(15);
 renderer.setLegendTextSize(15);
 renderer.setMargins(new int[] { 30, 40, 15, 0 });
 SimpleSeriesRenderer r = new SimpleSeriesRenderer();
 r.setColor(Color.BLUE);
 renderer.addSeriesRenderer(r);
 r = new SimpleSeriesRenderer();
 r.setColor(Color.RED);
 renderer.addSeriesRenderer(r);
 return renderer;
 }

 private void myChartSettings(XYMultipleSeriesRenderer renderer) {
 renderer.setChartTitle("Truiton's Performance by AChartEngine BarChart");
 renderer.setXAxisMin(0.5);
 renderer.setXAxisMax(10.5);
 renderer.setYAxisMin(0);
 renderer.setYAxisMax(210);
 renderer.addXTextLabel(1, "2010");
 renderer.addXTextLabel(2, "2011");
 renderer.addXTextLabel(3, "2012");
 renderer.addXTextLabel(4, "2013");
 renderer.setYLabelsAlign(Align.RIGHT);
 renderer.setBarSpacing(0.5);
 renderer.setXTitle("Years");
 renderer.setYTitle("Performance");
 renderer.setShowGrid(true);
     renderer.setGridColor(Color.GRAY);
     renderer.setXLabels(0); // sets the number of integer labels to appear
 }

}</pre>



<p class="wp-block-paragraph">As you can see in this class I have added another method called myChartSettings() which can be used to set the various graphical properties of Android AChartEngine bar chart. As a whole this class would display a graph in <em>org.achartengine.GraphicalActivity. </em>Yes this is surprisingly true as Android AChartEngine is an Intent based library, all the charts are displayed in GraphicalActivity. Therefore make sure you add this in your Android Manifest :</p>



<pre class="EnlighterJSRAW" data-enlighter-language="xml" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;?xml version="1.0" encoding="utf-8"?>
&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.truiton.myachartengine"
    android:versionCode="1"
    android:versionName="1.0" >

    &lt;uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    &lt;application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        &lt;activity
            android:name="com.truiton.myachartengine.TruitonAChartEngineActivity"
            android:label="@string/app_name" >
            &lt;intent-filter>
                &lt;action android:name="android.intent.action.MAIN" />

                &lt;category android:name="android.intent.category.LAUNCHER" />
            &lt;/intent-filter>
        &lt;/activity>
        &lt;activity android:name="org.achartengine.GraphicalActivity" />
    &lt;/application>

&lt;/manifest></pre>



<p class="wp-block-paragraph">After all these steps your Android AChartEngine graph/chart would look somthing like this:</p>



<ul data-carousel-extra='{&quot;blog_id&quot;:1,&quot;permalink&quot;:&quot;https://www.truiton.com/2013/04/android-tutorial-drawing-achartengine-bar-chart-with-example/&quot;}'  class="wp-block-gallery columns-3 is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex"><li class="blocks-gallery-item"><figure><a href="https://i0.wp.com/www.truiton.com/wp-content/uploads/2013/04/11.png?ssl=1"><img data-recalc-dims="1" loading="lazy" decoding="async" width="821" height="511" data-attachment-id="171" data-permalink="https://www.truiton.com/2013/04/android-tutorial-drawing-achartengine-bar-chart-with-example/1-6/" data-orig-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2013/04/11.png?fit=821%2C511&amp;ssl=1" data-orig-size="821,511" data-comments-opened="1" data-image-title="" data-image-description="" data-image-caption="&lt;p&gt;Android AChartEngine Tutorial&lt;/p&gt;
" data-large-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2013/04/11.png?fit=821%2C511&amp;ssl=1" src="https://i0.wp.com/www.truiton.com/wp-content/uploads/2013/04/11.png?resize=821%2C511&#038;ssl=1" alt="Android AChartEngine Tutorial" data-id="171" class="wp-image-171" srcset="https://i0.wp.com/www.truiton.com/wp-content/uploads/2013/04/11.png?w=821&amp;ssl=1 821w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2013/04/11.png?resize=300%2C186&amp;ssl=1 300w" sizes="auto, (max-width: 821px) 100vw, 821px" /></a></figure></li></ul>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">The part I liked about Android AChartEngine library is that it creates beautiful smooth scrolling charts. And even better- it could be customized to look like whatever you want it to look like. The project page of AChartEngine states that they are going to add new chart/graph types to this library in following releases, lets hope they make them even more interactive. This tutorial concludes my series on displaying charts on Android. If you find this interesting share this on Facebook, Google+ and like our Facebook page to stay connected with us.</p>
<div class="saboxplugin-wrap" itemtype="http://schema.org/Person" itemscope itemprop="author"><div class="saboxplugin-tab"><div class="saboxplugin-gravatar"><img alt='Mohit Gupt' src='https://secure.gravatar.com/avatar/a816092ad56645d2635ccfceb9f7e9d44821c19dec126cb394c882ba574eaa04?s=100&#038;d=mm&#038;r=g' srcset='https://secure.gravatar.com/avatar/a816092ad56645d2635ccfceb9f7e9d44821c19dec126cb394c882ba574eaa04?s=200&#038;d=mm&#038;r=g 2x' class='avatar avatar-100 photo' height='100' width='100' itemprop="image"/></div><div class="saboxplugin-authorname"><a href="https://www.truiton.com/author/mohitgupt/" class="vcard author" rel="author"><span class="fn">Mohit Gupt</span></a></div><div class="saboxplugin-desc"><div itemprop="description"><p>Born in New Delhi, India. A software engineer by profession, an android enthusiast and mobile development evangelist. My motive here is to create a group of skilled engineers, who can build better software. Reason being programming is my passion, and also it feels good to make a device do something you want. Professionally I have worked with many software engineering and product development firms. As of now too, I am employed as a senior engineer in a leading tech company. In total I may have worked on more than 20 projects professionally, but whenever I get spare time I share my thoughts here at Truiton.</p>
</div></div><div class="saboxplugin-web "><a href="http://www.truiton.com" target="_self" >www.truiton.com</a></div><div class="clearfix"></div><div class="saboxplugin-socials "><a title="Wordpress" target="_blank" href="https://www.truiton.com/author/mohitgupt/" rel="nofollow noopener" class="saboxplugin-icon-grey"><svg aria-hidden="true" class="sab-wordpress" role="img" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 512 512"><path fill="currentColor" d="M61.7 169.4l101.5 278C92.2 413 43.3 340.2 43.3 256c0-30.9 6.6-60.1 18.4-86.6zm337.9 75.9c0-26.3-9.4-44.5-17.5-58.7-10.8-17.5-20.9-32.4-20.9-49.9 0-19.6 14.8-37.8 35.7-37.8.9 0 1.8.1 2.8.2-37.9-34.7-88.3-55.9-143.7-55.9-74.3 0-139.7 38.1-177.8 95.9 5 .2 9.7.3 13.7.3 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l77.5 230.4L249.8 247l-33.1-90.8c-11.5-.7-22.3-2-22.3-2-11.5-.7-10.1-18.2 1.3-17.5 0 0 35.1 2.7 56 2.7 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l76.9 228.7 21.2-70.9c9-29.4 16-50.5 16-68.7zm-139.9 29.3l-63.8 185.5c19.1 5.6 39.2 8.7 60.1 8.7 24.8 0 48.5-4.3 70.6-12.1-.6-.9-1.1-1.9-1.5-2.9l-65.4-179.2zm183-120.7c.9 6.8 1.4 14 1.4 21.9 0 21.6-4 45.8-16.2 76.2l-65 187.9C426.2 403 468.7 334.5 468.7 256c0-37-9.4-71.8-26-102.1zM504 256c0 136.8-111.3 248-248 248C119.2 504 8 392.7 8 256 8 119.2 119.2 8 256 8c136.7 0 248 111.2 248 248zm-11.4 0c0-130.5-106.2-236.6-236.6-236.6C125.5 19.4 19.4 125.5 19.4 256S125.6 492.6 256 492.6c130.5 0 236.6-106.1 236.6-236.6z"></path></svg></span></a><a title="Twitter" target="_blank" href="http://twitter.com/mohitgupt" rel="nofollow noopener" class="saboxplugin-icon-grey"><svg aria-hidden="true" class="sab-twitter" role="img" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 30 30"><path d="M26.37,26l-8.795-12.822l0.015,0.012L25.52,4h-2.65l-6.46,7.48L11.28,4H4.33l8.211,11.971L12.54,15.97L3.88,26h2.65 l7.182-8.322L19.42,26H26.37z M10.23,6l12.34,18h-2.1L8.12,6H10.23z" /></svg></span></a><a title="Facebook" target="_blank" href="https://www.facebook.com/Mr.Mohit.Gupt" rel="nofollow noopener" class="saboxplugin-icon-grey"><svg aria-hidden="true" class="sab-facebook" role="img" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 264 512"><path fill="currentColor" d="M76.7 512V283H0v-91h76.7v-71.7C76.7 42.4 124.3 0 193.8 0c33.3 0 61.9 2.5 70.2 3.6V85h-48.2c-37.8 0-45.1 18-45.1 44.3V192H256l-11.7 91h-73.6v229"></path></svg></span></a></div></div></div><p>The post <a href="https://www.truiton.com/2013/04/android-tutorial-drawing-achartengine-bar-chart-with-example/">Android Tutorial- Drawing AChartEngine Bar Chart with Example</a> appeared first on <a href="https://www.truiton.com">Truiton</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.truiton.com/2013/04/android-tutorial-drawing-achartengine-bar-chart-with-example/feed/</wfw:commentRss>
			<slash:comments>29</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">169</post-id>	</item>
		<item>
		<title>Android Tutorial- Introduction to AFreeChart with Sample</title>
		<link>https://www.truiton.com/2013/04/android-tutorial-introduction-to-afreechart-with-sample/</link>
					<comments>https://www.truiton.com/2013/04/android-tutorial-introduction-to-afreechart-with-sample/#comments</comments>
		
		<dc:creator><![CDATA[Mohit Gupt]]></dc:creator>
		<pubDate>Fri, 05 Apr 2013 20:33:21 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[example]]></category>
		<category><![CDATA[graph]]></category>
		<guid isPermaLink="false">http://blog.truiton.com/?p=136</guid>

					<description><![CDATA[<p>Today&#8217;s Android based business apps are incomplete without graphical aids like graphs/charts. Therefore in this tutorial I would be introducing a free charting library called AFreeChart, for Android platform. This library is based on JFreeChart 1.0.13. Although Android AFreeChart project is not being maintained at present, still its very easy to include this library in&#8230;&#160;<a href="https://www.truiton.com/2013/04/android-tutorial-introduction-to-afreechart-with-sample/" rel="bookmark">Read More &#187;<span class="screen-reader-text">Android Tutorial- Introduction to AFreeChart with Sample</span></a></p>
<p>The post <a href="https://www.truiton.com/2013/04/android-tutorial-introduction-to-afreechart-with-sample/">Android Tutorial- Introduction to AFreeChart with Sample</a> appeared first on <a href="https://www.truiton.com">Truiton</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-image"><figure class="aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" width="640" height="426" data-attachment-id="153" data-permalink="https://www.truiton.com/2013/04/android-tutorial-introduction-to-afreechart-with-sample/business-chart-showing-success/" data-orig-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2013/04/5961260280_f38d3cbee9_z.jpg?fit=640%2C426&amp;ssl=1" data-orig-size="640,426" data-comments-opened="1" data-image-title="business chart showing success" data-image-description="&lt;p&gt;business chart showing financial success at the stock market&lt;/p&gt;
" data-image-caption="" data-large-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2013/04/5961260280_f38d3cbee9_z.jpg?fit=640%2C426&amp;ssl=1" src="https://i0.wp.com/www.truiton.com/wp-content/uploads/2013/04/5961260280_f38d3cbee9_z.jpg?resize=640%2C426" alt="business chart showing success" class="wp-image-153" srcset="https://i0.wp.com/www.truiton.com/wp-content/uploads/2013/04/5961260280_f38d3cbee9_z.jpg?w=640&amp;ssl=1 640w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2013/04/5961260280_f38d3cbee9_z.jpg?resize=300%2C199&amp;ssl=1 300w" sizes="auto, (max-width: 640px) 100vw, 640px" /></figure></div>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Today&#8217;s Android based business apps are incomplete without graphical aids like graphs/charts. Therefore in this tutorial I would be introducing a free charting library called <a title="AFreeChart" href="http://code.google.com/p/afreechart/" target="_blank" rel="noopener noreferrer">AFreeChart</a>, for Android platform. This library is based on <a title="JFreeChart" href="http://www.jfree.org/jfreechart/" target="_blank" rel="noopener noreferrer">JFreeChart</a> 1.0.13. Although Android AFreeChart project is not being maintained at present, still its very easy to include this library in an Android project and create beautiful graph/charts effortlessly.</p>



<p class="wp-block-paragraph">This Android tutorial- Introduction to AFreeChart with sample is a part of my series of tutorials on creating chart/graphs on Android. In my previous tutorial I stated that there are many ways to show charts on android but I would be showing only 5 most popular ways to display graphs on Android:</p>



<ol class="wp-block-list"><li>Google Chart Tools- Latest Chart Tools – <a title="Android Tutorial- Using Google Chart Tools With SVG and Image API" href="http://www.truiton.com/2013/04/android-tutorial-using-google-chart-tools-with-svg-and-image-api/" target="_blank" rel="noopener noreferrer">Android Tutorial- Google Chart Tools</a></li><li>Google Chart Tools: Image Tools- Deprecated – <a title="Android Tutorial- Using Google Chart Tools With SVG and Image API" href="http://www.truiton.com/2013/04/android-tutorial-using-google-chart-tools-with-svg-and-image-api/" target="_blank" rel="noopener noreferrer">Android Tutorial- Google Chart Tools Image API</a></li><li>AFreeChart- <a title="Android Tutorial- Introduction to AFreeChart with Sample" href="http://www.truiton.com/2013/04/android-tutorial-introduction-to-afreechart-with-sample/" target="_blank" rel="noopener noreferrer">Android Tutorial- Introduction to AFreeChart with Sample</a></li><li>AChartEngine- <a title="Android Tutorial- Drawing AChartEngine Bar Chart with Example" href="http://www.truiton.com/2013/04/android-tutorial-drawing-achartengine-bar-chart-with-example/" target="_blank" rel="noopener noreferrer">AChartEngine Tutorial</a></li><li>MPAndroidChart &#8211; <a title="Android Chart Example: MP Android Chart library" href="http://www.truiton.com/2015/04/android-chart-example-mp-android-chart-library/" target="_blank" rel="noopener noreferrer">Android MP Chart Library</a></li></ol>



<p class="wp-block-paragraph">As stated earlier this Android tutorial focuses on introduction to AFreeChart with sample. So lets start with a basic introduction to Android AFreeChart library.</p>



<p class="wp-block-paragraph">AFreeChart library for Android is ported over time from famous JFreeChart 1.0.13 library for java, many leading projects like JBoss, Sports Tracker etc. are using this library. As we all know mobile apps are built with a mindset to provide us information which is absolutely necessary to us when we are on move, therefore Android AFreeChart library is ported with very basic and absolutely necessary charts. Although Android AFreeChart library has the functionality to draw 15 types of charts: Bar Charts, Overlaid Charts, Legends, Multiple Axis Charts, Financial Charts, Pie Charts, Miscellaneous Charts, Markers, Showcase Charts, Scatter Charts, Statistical Charts, Combine Charts, Line Charts, Annotations, and Vectors, but since this tutorial is a basic introduction to Android AFreeChart library we are only going to discuss Bar Charts.</p>



<p class="wp-block-paragraph">The lowest Andorid OS version supported by AFreeChart library is 2.1. I am building this project for 4.1.2, for this I had to make minor changes in their demo code .I would point them out later in the tutorial. To create an app with Android AFreeChart we have to include a <em>.jar</em> file in our project by configuring the build path. This jar could be downloaded from official Google project page: <a title="AFreeChart-0.0.4.jar" href="http://afreechart.googlecode.com/files/afreechart-0.0.4.jar" target="_blank" rel="noopener noreferrer">afreechart-0.0.4.jar</a>.</p>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">To draw a graph with Android AFreeChart library we have to create a view by code, in which the graph is actually drawn, and utilize that view in our class. Drawing a view is a very complicated task, way beyond the limits of a beginner Android programmer. This includes calling various methods from the AFreeChart library and android graphics libraries. Hence I took an easier path by including the <em>DemoView.java</em> from the demo code provided by good AFreeChart library people. But since we are compiling this app for later versions of android, two minor changes had to be done in their code, have a look I have highlighted them:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="java" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">/* ===========================================================
 * AFreeChart : a free chart library for Android(tm) platform.
 *              (based on JFreeChart and JCommon)
 * ===========================================================
 *
 * (C) Copyright 2010, by ICOMSYSTECH Co.,Ltd.
 * (C) Copyright 2000-2008, by Object Refinery Limited and Contributors.
 *
 * Project Info:
 *    AFreeChart: http://code.google.com/p/afreechart/
 *    JFreeChart: http://www.jfree.org/jfreechart/index.html
 *    JCommon   : http://www.jfree.org/jcommon/index.html
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see &lt;http://www.gnu.org/licenses/>.
 *
 * [Android is a trademark of Google Inc.]
 *
 * -----------------
 * ChartView.java
 * -----------------
 * (C) Copyright 2010, by ICOMSYSTECH Co.,Ltd.
 *
 * Original Author:  Niwano Masayoshi (for ICOMSYSTECH Co.,Ltd);
 * Contributor(s):   Mohit Gupt;
 *
 * Changes
 * -------
 * 19-Nov-2010 : Version 0.0.1 (NM);
 * 14-Jan-2011 : renamed method name
 * 14-Jan-2011 : Updated API docs
 * 06-Apr-2013 : Updated return types of getScaleX and getScaleY methods
 */ 

package com.truiton.myafreechart;

import org.afree.ui.RectangleInsets;
import org.afree.chart.ChartTouchEvent;
import org.afree.chart.ChartTouchListener;
import org.afree.chart.ChartRenderingInfo;
import org.afree.chart.AFreeChart;
import org.afree.chart.entity.ChartEntity;
import org.afree.chart.entity.EntityCollection;
import org.afree.chart.event.ChartChangeEvent;
import org.afree.chart.event.ChartChangeListener;
import org.afree.chart.event.ChartProgressEvent;
import org.afree.chart.event.ChartProgressListener;
import org.afree.chart.plot.Movable;
import org.afree.chart.plot.Plot;
import org.afree.chart.plot.PlotOrientation;
import org.afree.chart.plot.PlotRenderingInfo;
import org.afree.chart.plot.Zoomable;
import org.afree.graphics.geom.Dimension;
import org.afree.graphics.geom.RectShape;
import org.afree.graphics.SolidColor;

import java.util.EventListener;
import java.util.concurrent.CopyOnWriteArrayList;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PointF;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class DemoView extends View 
    implements ChartChangeListener, ChartProgressListener{

    /** The user interface thread handler. */
    private Handler mHandler;

    public DemoView(Context context) {
        super(context);
        mHandler = new Handler();
        this.initialize();
    }

    public DemoView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mHandler = new Handler();
        this.initialize();
    }

    /**
     * initialize parameters
     */
    private void initialize() {
        this.chartMotionListeners = new CopyOnWriteArrayList&lt;ChartTouchListener>();
        this.info = new ChartRenderingInfo();
        this.minimumDrawWidth = DEFAULT_MINIMUM_DRAW_WIDTH;
        this.minimumDrawHeight = DEFAULT_MINIMUM_DRAW_HEIGHT;
        this.maximumDrawWidth = DEFAULT_MAXIMUM_DRAW_WIDTH;
        this.maximumDrawHeight = DEFAULT_MAXIMUM_DRAW_HEIGHT;
        this.moveTriggerDistance = DEFAULT_MOVE_TRIGGER_DISTANCE;
        new SolidColor(Color.BLUE);
        new SolidColor(Color.argb(0, 0, 255, 63));
        new java.util.ArrayList();
    }

    /**
     * Default setting for buffer usage.  The default has been changed to
     * &lt;code>true&lt;/code> from version 1.0.13 onwards, because of a severe
     * performance problem with drawing the zoom RectShape using XOR (which
     * now happens only when the buffer is NOT used).
     */
    public static final boolean DEFAULT_BUFFER_USED = true;

    /** The default panel width. */
    public static final int DEFAULT_WIDTH = 680;

    /** The default panel height. */
    public static final int DEFAULT_HEIGHT = 420;

    /** The default limit below which chart scaling kicks in. */
    public static final int DEFAULT_MINIMUM_DRAW_WIDTH = 10;

    /** The default limit below which chart scaling kicks in. */
    public static final int DEFAULT_MINIMUM_DRAW_HEIGHT = 10;

    /** The default limit above which chart scaling kicks in. */
    public static final int DEFAULT_MAXIMUM_DRAW_WIDTH = 1280;

    /** The default limit above which chart scaling kicks in. */
    public static final int DEFAULT_MAXIMUM_DRAW_HEIGHT = 1000;

    /** The minimum size required to perform a zoom on a RectShape */
    public static final int DEFAULT_ZOOM_TRIGGER_DISTANCE = 10;

    /** The minimum size required to perform a move on a RectShape */
    public static final int DEFAULT_MOVE_TRIGGER_DISTANCE = 10;

    /** The chart that is displayed in the panel. */
    private AFreeChart chart;

    /** Storage for registered (chart) touch listeners. */
    private transient CopyOnWriteArrayList&lt;ChartTouchListener> chartMotionListeners;

    /** The drawing info collected the last time the chart was drawn. */
    private ChartRenderingInfo info;

    /** The scale factor used to draw the chart. */
    private double scaleX;

    /** The scale factor used to draw the chart. */
    private double scaleY;

    /** The plot orientation. */
    private PlotOrientation orientation = PlotOrientation.VERTICAL;

    /**
     * The zoom RectShape starting point (selected by the user with touch).
     * This is a point on the screen, not the chart (which may have
     * been scaled up or down to fit the panel).
     */
    private PointF zoomPoint = null;

    /** Controls if the zoom RectShape is drawn as an outline or filled. */
//    private boolean fillZoomRectShape = true;

    private int moveTriggerDistance;

    /** The last touch position during panning. */
//    private Point panLast;

    private RectangleInsets insets = null;

    /**
     * The minimum width for drawing a chart (uses scaling for smaller widths).
     */
    private int minimumDrawWidth;

    /**
     * The minimum height for drawing a chart (uses scaling for smaller
     * heights).
     */
    private int minimumDrawHeight;

    /**
     * The maximum width for drawing a chart (uses scaling for bigger
     * widths).
     */
    private int maximumDrawWidth;

    /**
     * The maximum height for drawing a chart (uses scaling for bigger
     * heights).
     */
    private int maximumDrawHeight;

    private Dimension size = null;

    /** The chart anchor point. */
    private PointF anchor;

    /** A flag that controls whether or not domain moving is enabled. */
    private boolean domainMovable = false;

    /** A flag that controls whether or not range moving is enabled. */
    private boolean rangeMovable = false;

    private double accelX, accelY;
    private double friction = 0.8;
    private boolean inertialMovedFlag = false;
    private PointF lastTouch;

    private float mScale = 1.0f;

    private long mPrevTimeMillis = 0;
    private long mNowTimeMillis = System.currentTimeMillis();

    /**
     * touch event
     */
    public boolean onTouchEvent(MotionEvent ev) {

        super.onTouchEvent(ev);
        int action = ev.getAction();
        int count = ev.getPointerCount();

        this.anchor = new PointF(ev.getX(), ev.getY());

        if (this.info != null) {
            EntityCollection entities = this.info.getEntityCollection();
            if (entities != null) {
            }
        }

        switch (action &amp; MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_POINTER_DOWN:
                Log.i("TouchEvent", "ACTION_DOWN");
                if(count == 2 &amp;&amp; this.multiTouchStartInfo == null) {
                    setMultiTouchStartInfo(ev);
                } else if (count == 1 &amp;&amp; this.singleTouchStartInfo == null) {
                    setSingleTouchStartInfo(ev);
                }

                touched(ev);

                break;
            case MotionEvent.ACTION_MOVE:
                Log.i("TouchEvent", "ACTION_MOVE");
                if(count == 1 &amp;&amp; this.singleTouchStartInfo != null) {
                    moveAdjustment(ev);
                } else if (count == 2 &amp;&amp; this.multiTouchStartInfo != null) {
                    //scaleAdjustment(ev);    
                    zoomAdjustment(ev);
                }

                inertialMovedFlag = false;

                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP:
                Log.i("TouchEvent", "ACTION_UP");
                if(count &lt;= 2) {
                    this.multiTouchStartInfo = null;
                    this.singleTouchStartInfo = null;
                } 
                if (count &lt;= 1) {
                    this.singleTouchStartInfo = null;
                }

                // double click check
                if (count == 1) {
                    mNowTimeMillis = System.currentTimeMillis();
                    if(mNowTimeMillis - mPrevTimeMillis &lt; 400) {
                        if(chart.getPlot() instanceof Movable) {
                            restoreAutoBounds();
                            mScale = 1.0f;
                            inertialMovedFlag = false;
                        }
                    } else {
                        inertialMovedFlag = true;
                    }
                    mPrevTimeMillis = mNowTimeMillis;
                }
                break;
            default:
                break;
        }

        return true;
    }

    /**
     * MultiTouchStartInfo setting
     * @param ev
     */
    private void setMultiTouchStartInfo(MotionEvent ev) {

        if(this.multiTouchStartInfo == null) {
            this.multiTouchStartInfo = new MultiTouchStartInfo();
        }

        // distance
        double distance = Math.sqrt(Math.pow(ev.getX(0) - ev.getX(1),2) + Math.pow(ev.getY(0) - ev.getY(1),2));
        this.multiTouchStartInfo.setDistance(distance);        
    }

    /**
     * SingleTouchStartInfo setting
     * @param ev
     */
    private void setSingleTouchStartInfo(MotionEvent ev) {

        if(this.singleTouchStartInfo == null) {
            this.singleTouchStartInfo = new SingleTouchStartInfo();
        }

        // start point
        this.singleTouchStartInfo.setX(ev.getX(0));
        this.singleTouchStartInfo.setY(ev.getY(0));
    }

    /**
     * Translate MotionEvent as TouchEvent
     * @param ev
     */
    private void moveAdjustment(MotionEvent ev) {

        boolean hMove = false;
        boolean vMove = false;
        if (this.orientation == PlotOrientation.HORIZONTAL) {
            hMove = this.rangeMovable;
            vMove = this.domainMovable;
        }
        else {
            hMove = this.domainMovable;
            vMove = this.rangeMovable;
        }

        boolean moveTrigger1 = hMove &amp;&amp; Math.abs(ev.getX(0) - this.singleTouchStartInfo.getX() ) >= this.moveTriggerDistance;
        boolean moveTrigger2 = vMove &amp;&amp; Math.abs(ev.getY(0) - this.singleTouchStartInfo.getY()) >= this.moveTriggerDistance;
        if (moveTrigger1 || moveTrigger2) {

            RectShape dataArea = this.info.getPlotInfo().getDataArea();

            double moveBoundX;
            double moveBoundY;
            double dataAreaWidth = dataArea.getWidth();
            double dataAreaHeight = dataArea.getHeight();

            // for touchReleased event, (horizontalZoom || verticalZoom)
            // will be true, so we can just test for either being false;
            // otherwise both are true

            if (!vMove) {
                moveBoundX = this.singleTouchStartInfo.getX() - ev.getX(0);
                moveBoundY = 0;
            }
            else if (!hMove) {
                moveBoundX = 0;
                moveBoundY = this.singleTouchStartInfo.getY() - ev.getY(0);
            }
            else {
                moveBoundX = this.singleTouchStartInfo.getX() - ev.getX(0);
                moveBoundY = this.singleTouchStartInfo.getY() - ev.getY(0);
            }
            accelX = moveBoundX;
            accelY = moveBoundY;

            lastTouch = new PointF(ev.getX(0), ev.getY(0));
            move(lastTouch, moveBoundX,moveBoundY,dataAreaWidth,dataAreaHeight);

        }

        setSingleTouchStartInfo(ev);
    }

    /**
     * 
     * @param moveBoundX
     * @param moveBoundY
     * @param dataAreaWidth
     * @param dataAreaHeight
     */
    private void move(PointF source, double moveBoundX, double moveBoundY,
            double dataAreaWidth, double dataAreaHeight) {

        if (source == null) {
            throw new IllegalArgumentException("Null 'source' argument");
        }

        double hMovePercent = moveBoundX / dataAreaWidth;
        double vMovePercent = - moveBoundY / dataAreaHeight;

        Plot p = this.chart.getPlot();
        if (p instanceof Movable) {
            PlotRenderingInfo info = this.info.getPlotInfo();
            // here we tweak the notify flag on the plot so that only
            // one notification happens even though we update multiple
            // axes...
            //boolean savedNotify = p.isNotify();
            //p.setNotify(false);
            Movable z = (Movable) p;
            if (z.getOrientation() == PlotOrientation.HORIZONTAL) {
                z.moveDomainAxes(vMovePercent, info, source);
                z.moveRangeAxes(hMovePercent, info, source);
            }
            else {
                z.moveDomainAxes(hMovePercent, info, source);
                z.moveRangeAxes(vMovePercent, info, source);
            }
            //p.setNotify(savedNotify);

            //repaint
            invalidate();
        }

    }

    /**
     * Restores the auto-range calculation on both axes.
     */
    public void restoreAutoBounds() {
        Plot plot = this.chart.getPlot();
        if (plot == null) {
            return;
        }
        // here we tweak the notify flag on the plot so that only
        // one notification happens even though we update multiple
        // axes...
        //boolean savedNotify = plot.isNotify();
        //plot.setNotify(false);
        restoreAutoDomainBounds();
        restoreAutoRangeBounds();
        //plot.setNotify(savedNotify);
    }

    /**
     * Restores the auto-range calculation on the domain axis.
     */
    public void restoreAutoDomainBounds() {
        Plot plot = this.chart.getPlot();
        if (plot instanceof Zoomable) {
            Zoomable z = (Zoomable) plot;
            // here we tweak the notify flag on the plot so that only
            // one notification happens even though we update multiple
            // axes...
            //boolean savedNotify = plot.isNotify();
            //plot.setNotify(false);
            // we need to guard against this.zoomPoint being null
            PointF zp = (this.zoomPoint != null
                    ? this.zoomPoint : new PointF());
            z.zoomDomainAxes(0.0, this.info.getPlotInfo(), zp);
            //plot.setNotify(savedNotify);
        }
    }

    /**
     * Restores the auto-range calculation on the range axis.
     */
    public void restoreAutoRangeBounds() {
        Plot plot = this.chart.getPlot();
        if (plot instanceof Zoomable) {
            Zoomable z = (Zoomable) plot;
            // here we tweak the notify flag on the plot so that only
            // one notification happens even though we update multiple
            // axes...
            //boolean savedNotify = plot.isNotify();
            //plot.setNotify(false);
            // we need to guard against this.zoomPoint being null
            PointF zp = (this.zoomPoint != null
                    ? this.zoomPoint : new PointF());
            z.zoomRangeAxes(0.0, this.info.getPlotInfo(), zp);
            //plot.setNotify(savedNotify);
        }
    }

    protected void onSizeChanged(int w, int h, int oldw, int oldh){
        this.insets = new RectangleInsets(0,0,0,0);
        this.size = new Dimension(w, h);
    }

    private RectangleInsets getInsets() {
        return this.insets;
    }

    /**
     * Returns the X scale factor for the chart.  This will be 1.0 if no
     * scaling has been used.
     *
     * @return The scale factor.
     */
    public float getScaleX() {
        return (float) this.scaleX;
    }

    /**
     * Returns the Y scale factory for the chart.  This will be 1.0 if no
     * scaling has been used.
     *
     * @return The scale factor.
     */
    public float getScaleY() {
        return (float) this.scaleY;
    }

    /**
     * Sets the chart that is displayed in the panel.
     *
     * @param chart  the chart (&lt;code>null&lt;/code> permitted).
     */
    public void setChart(AFreeChart chart) {

        // stop listening for changes to the existing chart
        if (this.chart != null) {
            this.chart.removeChangeListener(this);
            this.chart.removeProgressListener(this);
        }

        // add the new chart
        this.chart = chart;
        if (chart != null) {
            this.chart.addChangeListener(this);
            this.chart.addProgressListener(this);
            Plot plot = chart.getPlot();
            if (plot instanceof Zoomable) {
                Zoomable z = (Zoomable) plot;
                z.isRangeZoomable();
                this.orientation = z.getOrientation();
            }

            this.domainMovable = false;
            this.rangeMovable = false;
            if (plot instanceof Movable) {
                Movable z = (Movable) plot;
                this.domainMovable = z.isDomainMovable();
                this.rangeMovable = z.isRangeMovable();
                this.orientation = z.getOrientation();
            }
        }
        else {
            this.domainMovable = false;
            this.rangeMovable = false;
        }
//        if (this.useBuffer) {
//            this.refreshBuffer = true;
//        }
        repaint();

    }

    /**
     * Returns the minimum drawing width for charts.
     * &lt;P>
     * If the width available on the panel is less than this, then the chart is
     * drawn at the minimum width then scaled down to fit.
     *
     * @return The minimum drawing width.
     */
    public int getMinimumDrawWidth() {
        return this.minimumDrawWidth;
    }

    /**
     * Sets the minimum drawing width for the chart on this panel.
     * &lt;P>
     * At the time the chart is drawn on the panel, if the available width is
     * less than this amount, the chart will be drawn using the minimum width
     * then scaled down to fit the available space.
     *
     * @param width  The width.
     */
    public void setMinimumDrawWidth(int width) {
        this.minimumDrawWidth = width;
    }

    /**
     * Returns the maximum drawing width for charts.
     * &lt;P>
     * If the width available on the panel is greater than this, then the chart
     * is drawn at the maximum width then scaled up to fit.
     *
     * @return The maximum drawing width.
     */
    public int getMaximumDrawWidth() {
        return this.maximumDrawWidth;
    }

    /**
     * Sets the maximum drawing width for the chart on this panel.
     * &lt;P>
     * At the time the chart is drawn on the panel, if the available width is
     * greater than this amount, the chart will be drawn using the maximum
     * width then scaled up to fit the available space.
     *
     * @param width  The width.
     */
    public void setMaximumDrawWidth(int width) {
        this.maximumDrawWidth = width;
    }

    /**
     * Returns the minimum drawing height for charts.
     * &lt;P>
     * If the height available on the panel is less than this, then the chart
     * is drawn at the minimum height then scaled down to fit.
     *
     * @return The minimum drawing height.
     */
    public int getMinimumDrawHeight() {
        return this.minimumDrawHeight;
    }

    /**
     * Sets the minimum drawing height for the chart on this panel.
     * &lt;P>
     * At the time the chart is drawn on the panel, if the available height is
     * less than this amount, the chart will be drawn using the minimum height
     * then scaled down to fit the available space.
     *
     * @param height  The height.
     */
    public void setMinimumDrawHeight(int height) {
        this.minimumDrawHeight = height;
    }

    /**
     * Returns the maximum drawing height for charts.
     * &lt;P>
     * If the height available on the panel is greater than this, then the
     * chart is drawn at the maximum height then scaled up to fit.
     *
     * @return The maximum drawing height.
     */
    public int getMaximumDrawHeight() {
        return this.maximumDrawHeight;
    }

    /**
     * Sets the maximum drawing height for the chart on this panel.
     * &lt;P>
     * At the time the chart is drawn on the panel, if the available height is
     * greater than this amount, the chart will be drawn using the maximum
     * height then scaled up to fit the available space.
     *
     * @param height  The height.
     */
    public void setMaximumDrawHeight(int height) {
        this.maximumDrawHeight = height;
    }

    /**
     * Returns the chart rendering info from the most recent chart redraw.
     *
     * @return The chart rendering info.
     */
    public ChartRenderingInfo getChartRenderingInfo() {
        return this.info;
    }

    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        inertialMove();

        paintComponent(canvas);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    /**
     * Paints the component by drawing the chart to fill the entire component,
     * but allowing for the insets (which will be non-zero if a border has been
     * set for this component).  To increase performance (at the expense of
     * memory), an off-screen buffer image can be used.
     *
     * @param canvas  the graphics device for drawing on.
     */
    public void paintComponent(Canvas canvas) {

        // first determine the size of the chart rendering area...
        Dimension size = getSize();
        RectangleInsets insets = getInsets();
        RectShape available = new RectShape(insets.getLeft(), insets.getTop(),
                size.getWidth() - insets.getLeft() - insets.getRight(),
                size.getHeight() - insets.getTop() - insets.getBottom());

        double drawWidth = available.getWidth();
        double drawHeight = available.getHeight();
        this.scaleX = 1.0;
        this.scaleY = 1.0;

        if (drawWidth &lt; this.minimumDrawWidth) {
            this.scaleX = drawWidth / this.minimumDrawWidth;
            drawWidth = this.minimumDrawWidth;
        }
        else if (drawWidth > this.maximumDrawWidth) {
            this.scaleX = drawWidth / this.maximumDrawWidth;
            drawWidth = this.maximumDrawWidth;
        }

        if (drawHeight &lt; this.minimumDrawHeight) {
            this.scaleY = drawHeight / this.minimumDrawHeight;
            drawHeight = this.minimumDrawHeight;
        }
        else if (drawHeight > this.maximumDrawHeight) {
            this.scaleY = drawHeight / this.maximumDrawHeight;
            drawHeight = this.maximumDrawHeight;
        }

        RectShape chartArea = new RectShape(0.0, 0.0, drawWidth,
                drawHeight);

        // are we using the chart buffer?
//        if (this.useBuffer) {
//
//            // do we need to resize the buffer?
//            if ((this.chartBuffer == null)
//                    || (this.chartBufferWidth != available.getWidth())
//                    || (this.chartBufferHeight != available.getHeight())) {
//                this.chartBufferWidth = (int) available.getWidth();
//                this.chartBufferHeight = (int) available.getHeight();
//                GraphicsConfiguration gc = canvas.getDeviceConfiguration();
//                this.chartBuffer = gc.createCompatibleImage(
//                        this.chartBufferWidth, this.chartBufferHeight,
//                        Transparency.TRANSLUCENT);
//                this.refreshBuffer = true;
//            }
//
//            // do we need to redraw the buffer?
//            if (this.refreshBuffer) {
//
//                this.refreshBuffer = false; // clear the flag
//
//                RectShape bufferArea = new RectShape(
//                        0, 0, this.chartBufferWidth, this.chartBufferHeight);
//
//                Graphics2D bufferG2 = (Graphics2D)
//                        this.chartBuffer.getGraphics();
//                RectShape r = new RectShape(0, 0, this.chartBufferWidth,
//                        this.chartBufferHeight);
//                bufferG2.setPaint(getBackground());
//                bufferG2.fill(r);
//                if (scale) {
//                    AffineTransform saved = bufferG2.getTransform();
//                    AffineTransform st = AffineTransform.getScaleInstance(
//                            this.scaleX, this.scaleY);
//                    bufferG2.transform(st);
//                    this.chart.draw(bufferG2, chartArea, this.anchor,
//                            this.info);
//                    bufferG2.setTransform(saved);
//                }
//                else {
//                    this.chart.draw(bufferG2, bufferArea, this.anchor,
//                            this.info);
//                }
//
//            }
//
//            // zap the buffer onto the panel...
//            canvas.drawImage(this.chartBuffer, insets.left, insets.top, this);
//
//        }

        // TODO:AffineTransform
        // or redrawing the chart every time...
//        else {

//            AffineTransform saved = canvas.getTransform();
//            canvas.translate(insets.left, insets.top);
//            if (scale) {
//                AffineTransform st = AffineTransform.getScaleInstance(
//                        this.scaleX, this.scaleY);
//                canvas.transform(st);
//            }
//            this.chart.draw(canvas, chartArea, this.anchor, this.info);
//            canvas.setTransform(saved);

//        }
        this.chart.draw(canvas, chartArea, this.anchor, this.info);

//        Iterator iterator = this.overlays.iterator();
//        while (iterator.hasNext()) {
//            Overlay overlay = (Overlay) iterator.next();
//            overlay.paintOverlay(canvas, this);
//        }

        // redraw the zoom RectShape (if present) - if useBuffer is false,
        // we use XOR so we can XOR the RectShape away again without redrawing
        // the chart
        //drawZoomRectShape(canvas, !this.useBuffer);

        //canvas.dispose();

        this.anchor = null;
//        this.verticalTraceLine = null;
//        this.horizontalTraceLine = null;

    }

    public Dimension getSize() {
        return this.size;
    }

    /**
     * Returns the anchor point.
     *
     * @return The anchor point (possibly &lt;code>null&lt;/code>).
     */
    public PointF getAnchor() {
        return this.anchor;
    }

    public ChartRenderingInfo getInfo() {
        return info;
    }

    /**
     * Sets the anchor point.  This method is provided for the use of
     * subclasses, not end users.
     *
     * @param anchor  the anchor point (&lt;code>null&lt;/code> permitted).
     */
    protected void setAnchor(PointF anchor) {
        this.anchor = anchor;
    }

    /**
     * Information for multi touch start
     * @author ikeda
     *
     */
    private class MultiTouchStartInfo {
        private double distance = 0;

        public double getDistance() {
            return distance;
        }
        public void setDistance(double distance) {
            this.distance = distance;
        }
    }

    private MultiTouchStartInfo multiTouchStartInfo = null;

    /**
     * Information for Single touch start
     * @author ikeda
     *
     */
    private class SingleTouchStartInfo {
        private double x = 0;
        private double y = 0;

        public double getX() {
            return x;
        }
        public void setX(double x) {
            this.x = x;
        }
        public double getY() {
            return y;
        }
        public void setY(double y) {
            this.y = y;
        }
    }

    private SingleTouchStartInfo singleTouchStartInfo = null;

    /**
     * Zoom 
     * @param ev
     */
    private void zoomAdjustment(MotionEvent ev) {
        PointF point = new PointF((ev.getX(0) + ev.getX(1)) / 2, (ev.getY(0) + ev.getY(1)) / 2);
        //end distance
        double endDistance = Math.sqrt(Math.pow(ev.getX(0) - ev.getX(1),2) + Math.pow(ev.getY(0) - ev.getY(1),2));

        // zoom process
        zoom(point, this.multiTouchStartInfo.getDistance(),endDistance);

        // reset start point
        setMultiTouchStartInfo(ev);
    }

    /**
     * zoom
     * @param startDistance
     * @param endDistance
     */
    private void zoom(PointF source, double startDistance, double endDistance) {

        Plot plot = this.chart.getPlot();
        PlotRenderingInfo info = this.info.getPlotInfo();

        if(plot instanceof Zoomable) {
            float scaleDistance = (float)(startDistance / endDistance);

            if (this.mScale * scaleDistance &lt; 10.0f &amp;&amp;
                    this.mScale * scaleDistance > 0.1f) {
                this.mScale *= scaleDistance;
                Zoomable z = (Zoomable) plot;
                z.zoomDomainAxes(scaleDistance, info, source, false);
                z.zoomRangeAxes(scaleDistance, info, source, false);
            }
        }

        // repaint
        invalidate();
    }

    private void inertialMove() {
        if(inertialMovedFlag == true) {
            RectShape dataArea = this.info.getPlotInfo().getDataArea();

            accelX *= friction;
            accelY *= friction;

            double dataAreaWidth = dataArea.getWidth();
            double dataAreaHeight = dataArea.getHeight();

            if (lastTouch != null) {
                move(lastTouch, accelX, accelY, dataAreaWidth, dataAreaHeight);
            }

            if(accelX &lt; 0.1 &amp;&amp; accelX > -0.1) {
                accelX = 0;
            }

            if(accelY &lt; 0.1 &amp;&amp; accelY > -0.1) {
                accelY = 0;
            }

            if(accelX == 0 &amp;&amp; accelY == 0) {
                inertialMovedFlag = false;
            }
        }
    }    /**
     * Receives notification of touch on the panel. These are
     * translated and passed on to any registered {@link ChartTouchListener}s.
     *
     * @param event  Information about the touch event.
     */
    public void touched(MotionEvent event) {

        int x = (int) (event.getX() / this.scaleX);
        int y = (int) (event.getY() / this.scaleY);

        this.anchor = new PointF(x, y);
        if (this.chart == null) {
            return;
        }
        this.chart.setNotify(true);  // force a redraw

        chart.handleClick((int)event.getX(), (int)event.getY(), info);
        inertialMovedFlag = false;

        // new entity code...
        if (this.chartMotionListeners.size() == 0) {
            return;
        }

        ChartEntity entity = null;
        if (this.info != null) {
            EntityCollection entities = this.info.getEntityCollection();
            if (entities != null) {
                entity = entities.getEntity(x, y);
            }
        }
        ChartTouchEvent chartEvent = new ChartTouchEvent(getChart(), event,
                entity);
        for (int i = chartMotionListeners.size() - 1; i >= 0; i--) {
            this.chartMotionListeners.get(i).chartTouched(chartEvent);
        }

    }

    /**
     * Returns the chart contained in the panel.
     *
     * @return The chart (possibly &lt;code>null&lt;/code>).
     */
    public AFreeChart getChart() {
        return this.chart;
    }

    /**
     * Adds a listener to the list of objects listening for chart touch events.
     *
     * @param listener  the listener (&lt;code>null&lt;/code> not permitted).
     */
    public void addChartTouchListener(ChartTouchListener listener) {
        if (listener == null) {
            throw new IllegalArgumentException("Null 'listener' argument.");
        }
        this.chartMotionListeners.add(listener);
    }

    /**
     * Removes a listener from the list of objects listening for chart touch
     * events.
     *
     * @param listener  the listener.
     */
    public void removeChartTouchListener(ChartTouchListener listener) {
        this.chartMotionListeners.remove(listener);
    }

    /**
     * Returns an array of the listeners of the given type registered with the
     * panel.
     *
     * @param listenerType  the listener type.
     *
     * @return An array of listeners.
     */
    public EventListener[] getListeners() {
        return this.chartMotionListeners.toArray(new ChartTouchListener[0]);
    }

    /**
     * Schedule a user interface repaint.
     */
    public void repaint() {
        mHandler.post(new Runnable() {
            public void run() {
                invalidate();
            }
        });
    }

    /**
     * Receives notification of changes to the chart, and redraws the chart.
     *
     * @param event  details of the chart change event.
     */
    public void chartChanged(ChartChangeEvent event) {
//        this.refreshBuffer = true;
        Plot plot = this.chart.getPlot();
        if (plot instanceof Zoomable) {
            Zoomable z = (Zoomable) plot;
            this.orientation = z.getOrientation();
        }
        repaint();
    }

    /**
     * Receives notification of a chart progress event.
     *
     * @param event  the event.
     */
    public void chartProgress(ChartProgressEvent event) {
        // does nothing - override if necessary
    }
}</pre>



<p class="wp-block-paragraph">Have a look at the highlighted lines in this code, the only change that I have done is, typecasting the return type of <em>getScaleX()</em> and <em>getScaleY()</em> methods to <em>Float</em>. Credit for this class goes to good people at ICOMSYSTECH Co.,Ltd. (Niwano Masayoshi). <span style="text-decoration: underline;">Please note: To get full class, double click on the code box/dialog above</span>.</p>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Now that we have our view ready, we need a class, which can call the <em>createBarChart</em> method from the <em>ChartFactory</em> class of Android AFreeChart library.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="java" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">/* ===========================================================
 * AFreeChart : a free chart library for Android(tm) platform.
 *              (based on JFreeChart and JCommon)
 * ===========================================================
 * Original Author:  Niwano Masayoshi (for ICOMSYSTECH Co.,Ltd);
 * Contributor(s):   Mohit Gupt;
 *
 * Changes
 * -------
 * 19-Nov-2010 : Version 0.0.1 (NM);
 * 31-Mar-2013 : Restructuring
 */

package com.truiton.myafreechart;

import org.afree.chart.ChartFactory;
import org.afree.chart.AFreeChart;
import org.afree.chart.axis.CategoryAxis;
import org.afree.chart.axis.CategoryLabelPositions;
import org.afree.chart.axis.NumberAxis;
import org.afree.chart.plot.CategoryPlot;
import org.afree.chart.plot.PlotOrientation;
import org.afree.chart.renderer.category.BarRenderer;
import org.afree.data.category.CategoryDataset;
import org.afree.data.category.DefaultCategoryDataset;
import org.afree.graphics.GradientColor;
import org.afree.graphics.SolidColor;

import android.content.Context;
import android.graphics.Color;

public class TruitonBarChartView extends DemoView {

    /**
     * constructor
     * @param context
     */
    public TruitonBarChartView(Context context) {
        super(context);

        CategoryDataset dataset = createDataset();
        AFreeChart chart = createChart(dataset);

        setChart(chart);
    }

    /**
     * Returns a sample dataset.
     *
     * @return The dataset.
     */
    private static CategoryDataset createDataset() {

        // row keys...
        String series1 = "Sales";
        String series2 = "Expenses";

        // column keys...
        String category1 = "2010";
        String category2 = "2011";
        String category3 = "2012";
        String category4 = "2013";

        // create the dataset...
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();

        dataset.addValue(1.0, series1, category1);
        dataset.addValue(4.0, series1, category2);
        dataset.addValue(3.0, series1, category3);
        dataset.addValue(8.0, series1, category4);

        dataset.addValue(5.0, series2, category1);
        dataset.addValue(7.0, series2, category2);
        dataset.addValue(6.0, series2, category3);
        dataset.addValue(5.0, series2, category4);

        return dataset;

    }

    /**
     * Creates a sample chart.
     *
     * @param dataset  the dataset.
     *
     * @return The chart.
     */
    private static AFreeChart createChart(CategoryDataset dataset) {

        // create the chart...
        AFreeChart chart = ChartFactory.createBarChart(
            "Truiton's Performance by AFreeChart Bar Chart",      // chart title
            "Year",               // domain axis label
            "Sales/Expenses",         // range axis label
            dataset,                  // data
            PlotOrientation.VERTICAL, // orientation
            true,                     // include legend
            true,                     // tooltips?
            false                     // URLs?
        );

        // NOW DO SOME OPTIONAL CUSTOMISATION OF THE CHART...

        // set the background color for the chart...
        chart.setBackgroundPaintType(new SolidColor(Color.WHITE));

        // get a reference to the plot for further customisation...
        CategoryPlot plot = (CategoryPlot) chart.getPlot();

        // set the range axis to display integers only...
        NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());

        // disable bar outlines...
        BarRenderer renderer = (BarRenderer) plot.getRenderer();
        renderer.setDrawBarOutline(false);

        // set up gradient paints for series...
        GradientColor gp0 = new GradientColor(Color.BLUE, Color.rgb(51, 102, 204));
        GradientColor gp1 = new GradientColor(Color.RED, Color.rgb(255, 0, 0));
        renderer.setSeriesPaintType(0, gp0);
        renderer.setSeriesPaintType(1, gp1);

        CategoryAxis domainAxis = plot.getDomainAxis();
        domainAxis.setCategoryLabelPositions(
                CategoryLabelPositions.createUpRotationLabelPositions(
                        Math.PI / 6.0));
        // OPTIONAL CUSTOMISATION COMPLETED.

        return chart;

    }
}</pre>



<p class="wp-block-paragraph">The purpose of this <strong>TruitonBarChartView.java</strong> is to create a bar chart by proving all the required arguments. In this class we can create a data set for graph/chart, set colors and set various other properties for chart.</p>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">We can now move on to our main activity class <strong>TruitonMainActivity.java</strong> which would finally display bar chart from Android AFreeChart library.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="java" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">package com.truiton.myafreechart;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.Window;

public class TruitonMainActivity extends Activity {

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 requestWindowFeature(Window.FEATURE_NO_TITLE);
 TruitonBarChartView mView = new TruitonBarChartView(this);
 setContentView(mView);
 }

 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
 // Inflate the menu; this adds items to the action bar if it is present.
 getMenuInflater().inflate(R.menu.truiton_main, menu);
 return true;
 }

}</pre>



<p class="wp-block-paragraph">The code in this class needs no explanation, we are just creating a view from <em>TruitonBarChartView</em> class and setting it as content view. With this done our graph/chart from Android AFreeChart library would be drawn as:</p>



<ul data-carousel-extra='{&quot;blog_id&quot;:1,&quot;permalink&quot;:&quot;https://www.truiton.com/2013/04/android-tutorial-introduction-to-afreechart-with-sample/&quot;}'  class="wp-block-gallery columns-3 is-cropped wp-block-gallery-2 is-layout-flex wp-block-gallery-is-layout-flex"><li class="blocks-gallery-item"><figure><a href="https://i0.wp.com/www.truiton.com/wp-content/uploads/2013/04/1.png?ssl=1"><img data-recalc-dims="1" loading="lazy" decoding="async" width="820" height="512" data-attachment-id="157" data-permalink="https://www.truiton.com/2013/04/android-tutorial-introduction-to-afreechart-with-sample/1-5/" data-orig-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2013/04/1.png?fit=820%2C512&amp;ssl=1" data-orig-size="820,512" data-comments-opened="1" data-image-title="" data-image-description="" data-image-caption="&lt;p&gt;Android AFreeChart Tutorial&lt;/p&gt;
" data-large-file="https://i0.wp.com/www.truiton.com/wp-content/uploads/2013/04/1.png?fit=820%2C512&amp;ssl=1" src="https://i0.wp.com/www.truiton.com/wp-content/uploads/2013/04/1.png?resize=820%2C512&#038;ssl=1" alt="Android AFreeChart Tutorial" data-id="157" class="wp-image-157" srcset="https://i0.wp.com/www.truiton.com/wp-content/uploads/2013/04/1.png?w=820&amp;ssl=1 820w, https://i0.wp.com/www.truiton.com/wp-content/uploads/2013/04/1.png?resize=300%2C187&amp;ssl=1 300w" sizes="auto, (max-width: 820px) 100vw, 820px" /></a></figure></li></ul>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">The major advantages of Android AFreeChart over Google Chart Tools is that, no internet connection is required to render chart/graphs and graphs are live i.e. they are scrollable, more interactive which leads to better user experience. To get a better understanding of Android <a title="AFreeChart" href="http://code.google.com/p/afreechart/" target="_blank" rel="noopener noreferrer">AFreeChart</a> please have a look at the <a title="AFreeChart Gallery" href="http://afreechart.googlecode.com/svn/doc/screenshot/index.html" target="_blank" rel="noopener noreferrer">chart gallery</a> and AFreeChart <a title="AFreeChart JavaDocs" href="http://afreechart.googlecode.com/svn/doc/javadocs/index.html" target="_blank" rel="noopener noreferrer">javadocs</a>. Next I would be writing a tutorial about <a title="Android Tutorial- Drawing AChartEngine Bar Chart with Example" href="http://www.truiton.com/2013/04/android-tutorial-drawing-achartengine-bar-chart-with-example/" target="_blank" rel="noopener noreferrer">AChartEngine</a> which would conclude my series on charts on Android. If this tutorial helped you please like n share it on Facebook, and connect with us on by liking our Facebook page.</p>
<div class="saboxplugin-wrap" itemtype="http://schema.org/Person" itemscope itemprop="author"><div class="saboxplugin-tab"><div class="saboxplugin-gravatar"><img alt='Mohit Gupt' src='https://secure.gravatar.com/avatar/a816092ad56645d2635ccfceb9f7e9d44821c19dec126cb394c882ba574eaa04?s=100&#038;d=mm&#038;r=g' srcset='https://secure.gravatar.com/avatar/a816092ad56645d2635ccfceb9f7e9d44821c19dec126cb394c882ba574eaa04?s=200&#038;d=mm&#038;r=g 2x' class='avatar avatar-100 photo' height='100' width='100' itemprop="image"/></div><div class="saboxplugin-authorname"><a href="https://www.truiton.com/author/mohitgupt/" class="vcard author" rel="author"><span class="fn">Mohit Gupt</span></a></div><div class="saboxplugin-desc"><div itemprop="description"><p>Born in New Delhi, India. A software engineer by profession, an android enthusiast and mobile development evangelist. My motive here is to create a group of skilled engineers, who can build better software. Reason being programming is my passion, and also it feels good to make a device do something you want. Professionally I have worked with many software engineering and product development firms. As of now too, I am employed as a senior engineer in a leading tech company. In total I may have worked on more than 20 projects professionally, but whenever I get spare time I share my thoughts here at Truiton.</p>
</div></div><div class="saboxplugin-web "><a href="http://www.truiton.com" target="_self" >www.truiton.com</a></div><div class="clearfix"></div><div class="saboxplugin-socials "><a title="Wordpress" target="_blank" href="https://www.truiton.com/author/mohitgupt/" rel="nofollow noopener" class="saboxplugin-icon-grey"><svg aria-hidden="true" class="sab-wordpress" role="img" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 512 512"><path fill="currentColor" d="M61.7 169.4l101.5 278C92.2 413 43.3 340.2 43.3 256c0-30.9 6.6-60.1 18.4-86.6zm337.9 75.9c0-26.3-9.4-44.5-17.5-58.7-10.8-17.5-20.9-32.4-20.9-49.9 0-19.6 14.8-37.8 35.7-37.8.9 0 1.8.1 2.8.2-37.9-34.7-88.3-55.9-143.7-55.9-74.3 0-139.7 38.1-177.8 95.9 5 .2 9.7.3 13.7.3 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l77.5 230.4L249.8 247l-33.1-90.8c-11.5-.7-22.3-2-22.3-2-11.5-.7-10.1-18.2 1.3-17.5 0 0 35.1 2.7 56 2.7 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l76.9 228.7 21.2-70.9c9-29.4 16-50.5 16-68.7zm-139.9 29.3l-63.8 185.5c19.1 5.6 39.2 8.7 60.1 8.7 24.8 0 48.5-4.3 70.6-12.1-.6-.9-1.1-1.9-1.5-2.9l-65.4-179.2zm183-120.7c.9 6.8 1.4 14 1.4 21.9 0 21.6-4 45.8-16.2 76.2l-65 187.9C426.2 403 468.7 334.5 468.7 256c0-37-9.4-71.8-26-102.1zM504 256c0 136.8-111.3 248-248 248C119.2 504 8 392.7 8 256 8 119.2 119.2 8 256 8c136.7 0 248 111.2 248 248zm-11.4 0c0-130.5-106.2-236.6-236.6-236.6C125.5 19.4 19.4 125.5 19.4 256S125.6 492.6 256 492.6c130.5 0 236.6-106.1 236.6-236.6z"></path></svg></span></a><a title="Twitter" target="_blank" href="http://twitter.com/mohitgupt" rel="nofollow noopener" class="saboxplugin-icon-grey"><svg aria-hidden="true" class="sab-twitter" role="img" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 30 30"><path d="M26.37,26l-8.795-12.822l0.015,0.012L25.52,4h-2.65l-6.46,7.48L11.28,4H4.33l8.211,11.971L12.54,15.97L3.88,26h2.65 l7.182-8.322L19.42,26H26.37z M10.23,6l12.34,18h-2.1L8.12,6H10.23z" /></svg></span></a><a title="Facebook" target="_blank" href="https://www.facebook.com/Mr.Mohit.Gupt" rel="nofollow noopener" class="saboxplugin-icon-grey"><svg aria-hidden="true" class="sab-facebook" role="img" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 264 512"><path fill="currentColor" d="M76.7 512V283H0v-91h76.7v-71.7C76.7 42.4 124.3 0 193.8 0c33.3 0 61.9 2.5 70.2 3.6V85h-48.2c-37.8 0-45.1 18-45.1 44.3V192H256l-11.7 91h-73.6v229"></path></svg></span></a></div></div></div><p>The post <a href="https://www.truiton.com/2013/04/android-tutorial-introduction-to-afreechart-with-sample/">Android Tutorial- Introduction to AFreeChart with Sample</a> appeared first on <a href="https://www.truiton.com">Truiton</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.truiton.com/2013/04/android-tutorial-introduction-to-afreechart-with-sample/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">136</post-id>	</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Page Caching using Disk: Enhanced 
Minified using Disk

Served from: www.truiton.com @ 2026-08-06 20:58:52 by W3 Total Cache
-->