title: Update in real time GraphicalView of AChartEngine
body: <p>I want to have an app that shows me a textview and a line chart dynamically updated with the values that I receive from a range sensor.
  I used a modified TextView which manages the messages and it works well.
  I tried to do the same thing with a GraphicalView from AChartEngine, but the Chart doesn't change with the arrival of new messages.</p>
  
  <p>Here is my code, any suggestion or advice?</p>
  
  <pre><code>public class NxtActivity extends RosActivity{
  
  
  private XYSeries mCurrentSeries = new XYSeries("range data series");
  private XYSeriesRenderer mCurrentRenderer = new XYSeriesRenderer();
  private XYMultipleSeriesDataset mDataset = new XYMultipleSeriesDataset();
  private XYMultipleSeriesRenderer mRenderer = new XYMultipleSeriesRenderer();
  
  private LineChart linec;
  private Canvas canvas = new Canvas();
  private RosChartView&lt;std_msgs.String&gt; rdrawview;
  
  private RosTextView&lt;std_msgs.String&gt; rosTextView;
  private Android_Talker talker;
   private java.net.URI master_uri;
  
  //costruttore
  public NxtActivity() {
      // The RosActivity constructor configures the notification title and ticker
      // messages.
          super("Pubsub Tutorial mod", "Pubsub Tutorial mod");
  
    }
  
  
  @Override
  public void onCreate(Bundle savedInstanceState) {
  
  super.onCreate(savedInstanceState);
  
      setContentView(R.layout.activity_nxt);
  //setto i parametri del renederer relativo alla singola seria
  mCurrentRenderer.setPointStyle(PointStyle.CIRCLE);
  mCurrentRenderer.setFillPoints(true);
  mCurrentRenderer.setLineWidth(2);
  //setto i parametri del renderer globale
  mRenderer.addSeriesRenderer(mCurrentRenderer);
    mRenderer.setApplyBackgroundColor(true);
      mRenderer.setBackgroundColor(Color.argb(100, 50, 50, 50));
      mRenderer.setAxisTitleTextSize(16);
      mRenderer.setChartTitleTextSize(20);
      mRenderer.setLabelsTextSize(15);
      mRenderer.setLegendTextSize(15);
      mRenderer.setMargins(new int[] { 20, 30, 15, 0 });
      mRenderer.setZoomButtonsVisible(true);
      mRenderer.setPointSize(10);
  mRenderer.setXTitle("time");
  mRenderer.setYTitle("ranges");
  //setto la serie
  mCurrentSeries.add(1,1);
  //setto il dataset
      mDataset.addSeries(mCurrentSeries);
  //setto LineChart
      linec = new LineChart(mDataset,mRenderer);
  //inizializzo RosChartView
      rdrawview=new RosChartView&lt;std_msgs.String&gt;(this,linec,canvas);
  rdrawview.setTopicName("chatter_nxt");
     rdrawview.setMessageType(std_msgs.String._TYPE);
  rdrawview.setMessageToStringCallable(new MessageCallable&lt;String, std_msgs.String&gt;() {
             @Override
            public String call(std_msgs.String message) {          
      return message.getData();
            }
        });
      //assegno RosChartView al Layout corrispondente
  LinearLayout layout = (LinearLayout) findViewById(R.id.chart);
  layout.addView(rdrawview, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
  rdrawview.repaint();
  //rdrawview.setup(3,3);
  
   rosTextView = (RosTextView&lt;std_msgs.String&gt;) findViewById(R.id.text1);
      rosTextView.setTopicName("chatter_nxt");
      rosTextView.setMessageType(std_msgs.String._TYPE);
  
   rosTextView.setMessageToStringCallable(new MessageCallable&lt;String, std_msgs.String&gt;() {
             @Override
            public String call(std_msgs.String message) {          
      return message.getData();
            }
        });
  }
  
  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
     getMenuInflater().inflate(R.menu.activity_nxt, menu);
      return true;
  }
  
  
  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
      switch (item.getItemId()) {
          //case android.R.id.home:
           //   NavUtils.navigateUpFromSameTask(this);
            //  return true;
      }
      return super.onOptionsItemSelected(item);
  }
  
  @Override
  protected void init(NodeMainExecutor nodeMainExecutor) {
  talker = new Android_Talker();
  NodeConfiguration nodeConfiguration = NodeConfiguration.newPrivate();
  // At this point, the user has already been prompted to either enter the URI
  // of a master to use or to start a master locally.
  try {
  
      master_uri  = new java.net.URI("http://150.145.11.98:11311");
   nodeConfiguration.setMasterUri(master_uri);
  }
  catch(URISyntaxException e){
  System.out.println("URI is a malformed URL");
  }
  rdrawview.setup(3,3);
  nodeConfiguration.setMasterUri(master_uri);
  nodeMainExecutor.execute(talker, nodeConfiguration);
  // The RosTextView is also a NodeMain that must be executed in order to
  // start displaying incoming messages.
  nodeMainExecutor.execute(rosTextView, nodeConfiguration);
  nodeMainExecutor.execute(rdrawview, nodeConfiguration);
  }
  
  }
  </code></pre>
  
  <p>Modified textview:</p>
  
  <pre><code>    public class RosTextView&lt;T&gt; extends TextView implements NodeMain {
  
    private String topicName;
    private String messageType;
      private int count=0;
    private MessageCallable&lt;String, T&gt; callable;
  
    public RosTextView(Context context) {
      super(context);
    }
  
    public RosTextView(Context context, AttributeSet attrs) {
      super(context, attrs);
    }
  
    public RosTextView(Context context, AttributeSet attrs, int defStyle) {
      super(context, attrs, defStyle);
    }
  
    public void setTopicName(String topicName) {
      this.topicName = topicName;
    }
  
    public void setMessageType(String messageType) {
      this.messageType = messageType;
    }
  
    public void setMessageToStringCallable(MessageCallable&lt;String, T&gt; callable) {
      this.callable = callable;
    }
  
    @Override
    public GraphName getDefaultNodeName() {
      return GraphName.of("android_gingerbread/ros_text_view");
    }
  
    @Override
    public void onStart(ConnectedNode connectedNode) {
      Subscriber&lt;T&gt; subscriber = connectedNode.newSubscriber(topicName, messageType);
      subscriber.addMessageListener(new MessageListener&lt;T&gt;() {
        @Override
        public void onNewMessage(final T message) {
          if (callable != null) {
            post(new Runnable() {
              @Override
              public void run() {
                setText(callable.call(message));
          count++;
          if((count%2)==0){setTextColor(Color.RED);}
          else{setTextColor(Color.BLUE);}
              }
            });
          } else {
            post(new Runnable() {
              @Override
              public void run() {
                setText(message.toString());
              }
            });
          }
          postInvalidate();
        }
      });
    }
  
    @Override
    public void onShutdown(Node node) {
    }
  
    @Override
    public void onShutdownComplete(Node node) {
    }
  
    @Override
    public void onError(Node node, Throwable throwable) {
    }
  }
  </code></pre>
  
  <p>Modifed graphicalview:</p>
  
  <pre><code>   public class RosChartView&lt;T&gt; extends GraphicalView implements NodeMain {
      //---------
    private XYMultipleSeriesDataset mDataset = new XYMultipleSeriesDataset();
    private XYMultipleSeriesRenderer mRenderer = new XYMultipleSeriesRenderer();
    private XYSeries mCurrentSeries = new XYSeries("range data series");
    private int x;
    private int y;
    Context context;
    Canvas canvas; 
      //---------
    private String topicName;
    private String messageType;
    private int count=0;
    private MessageCallable&lt;String, T&gt; callable;
  
    public RosChartView(Context context, LineChart xyc, Canvas canvas_) {
      super(context,xyc);
      this.context=context;
      mDataset = xyc.getDataset();    
      mRenderer = xyc.getRenderer();
      mRenderer.setClickEnabled(true);
          mRenderer.setSelectableBuffer(100);
      x=0;
      y=0;
      canvas=canvas_;
  
  
  
    }
  
    public RosChartView(Context context, AttributeSet attrs, LineChart xyc) {
  
      super(context, xyc);
      mDataset = xyc.getDataset();    
      mRenderer = xyc.getRenderer();
      mRenderer.setClickEnabled(true);
          mRenderer.setSelectableBuffer(100);
      x=0;
      y=0;
  
  
    }
  
    public RosChartView(Context context, AttributeSet attrs, int defStyle, LineChart xyc) {
      super(context, xyc);
  
      mDataset = xyc.getDataset();    
      mRenderer = xyc.getRenderer();
      mRenderer.setClickEnabled(true);
          mRenderer.setSelectableBuffer(100);
      x=0;
      y=0;
    }
  
    public void setTopicName(String topicName) {
      this.topicName = topicName;
    }
  
    public void setMessageType(String messageType) {
      this.messageType = messageType;
    }
  
    public void setMessageToStringCallable(MessageCallable&lt;String, T&gt; callable) {
      this.callable = callable;
    }
  
    @Override
    public GraphName getDefaultNodeName() {
      return GraphName.of("android_gingerbread/ros_text_view");
    }
  
    @Override
    public void onStart(ConnectedNode connectedNode) {
      Subscriber&lt;T&gt; subscriber = connectedNode.newSubscriber(topicName, messageType);
      subscriber.addMessageListener(new MessageListener&lt;T&gt;() {
        @Override
        public void onNewMessage(final T message) {
          if (callable != null) {
            post(new Runnable() {
              @Override
              public void run() {
          count++;
          x=count;
          y=Integer.parseInt(callable.call(message));
          XYSeries series=new XYSeries("new_series");
          series=mCurrentSeries;
          series.add(2,2);
          mDataset.removeSeries(mCurrentSeries);
          mCurrentSeries=series;
          mDataset.addSeries(mCurrentSeries);
                  repaint();
              }
            });
          } else {
            post(new Runnable() {
              @Override
              public void run() {
            count++;
            x=count;
                y=Integer.parseInt(message.toString());
            mCurrentSeries.add(x,y);
  
              }
            });
          }
          postInvalidate();
        }
      });
    }
  
    @Override
    public void onShutdown(Node node) {
    }
  
    @Override
    public void onShutdownComplete(Node node) {
    }
  
    @Override
    public void onError(Node node, Throwable throwable) {
    }
  
    public void setup(double x,double y)
    {
  
          mCurrentSeries.add(x,y);          
            this.repaint();
  
     }
  }
  </code></pre>
  
  <p>layout</p>
  
  <pre><code>&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" &gt;
  
  
  
  
  
         &lt;org.ros.android.view.RosTextView
          android:id="@+id/text1"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:textSize="30dip" 
      /&gt;
  
      &lt;LinearLayout
      android:id="@+id/chart"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:layout_weight="1"
      android:layout_below="@id/text1"
      android:orientation="horizontal" /&gt;
  
  
  
      &lt;/RelativeLayout&gt;
  </code></pre>