2013-07-18 37 views
4

我每次调用此方法将其返回NullPointerException异常:achartengine toScreenPoint(双)总是返回NullPointerException异常

显示java.lang.NullPointerException在org.achartengine.chart.XYChart.toScreenPoint(XYChart.java:867)

我见图表的mScreenR是空

如果不使用这种方法toScreenPoint(双)图表效果很好,这是代码:

package com.insights.insights.gui; 

import java.util.ArrayList; 

import org.achartengine.ChartFactory; 
import org.achartengine.GraphicalView; 
import org.achartengine.chart.LineChart; 
import org.achartengine.chart.PointStyle; 
import org.achartengine.chart.XYChart; 
import org.achartengine.model.XYMultipleSeriesDataset; 
import org.achartengine.model.XYSeries; 
import org.achartengine.renderer.XYMultipleSeriesRenderer; 
import org.achartengine.renderer.XYSeriesRenderer; 

import com.insights.insights.R; 
import com.insights.insights.local.ApplicationsController; 
import com.insights.insights.model.AppMetrics; 
import com.insights.insights.model.Application; 
import com.insights.insights.model.Applications; 
import com.insights.insights.model.Day; 

import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.AbsoluteLayout; 
import android.widget.LinearLayout; 
import android.widget.Toast; 

public class ChartFragment extends Fragment { 

    private XYMultipleSeriesRenderer renderer; 
    private XYMultipleSeriesDataset dataset; 
    private GraphicalView graphicalView; 
    private XYSeries firstSeries; 
    private XYChart chart=null; 

    private String apiKey; 
    private ArrayList<Day> days; 

    private View view; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     apiKey = getArguments().getString(getString(R.string.tabs_activity_api_key)); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View v = inflater.inflate(R.layout.chart_fragment, container, false); 

     v.findViewById(R.idChartFragment.container).requestFocus(); 

     this.view = v; 

     return v; 
    } 

    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 

     //  Obtaining data to plot 
     Applications applications = ApplicationsController.getInstance(getActivity()).getApplications(); 
     ArrayList<Application> applicationArray = applications.getApplication(); 

     if (applicationArray != null && !applicationArray.isEmpty()) { 
      for (int i = 0; i < applicationArray.size(); i++) { 
       if (applicationArray.get(i).getApiKey().equals(apiKey)) { 
        ArrayList<AppMetrics> appMetrics = applicationArray.get(i).getAppMetrics(); 
        for (int j = 0; j < appMetrics.size(); j++) { 
         if (appMetrics.get(j).getMetric().equals("Sessions")) { 
          days = appMetrics.get(j).getDay(); 
          break; 
         } 
        } 
       } 
      } 
     } 

     // If there isn't any item to plot and show a toast 
     if (days == null) { 
      Toast toast = Toast.makeText(getActivity(), R.string.chart_fragment_no_items, Toast.LENGTH_LONG); 
      toast.show(); 
      return; 
     } 

     // Ploting the items 
     dataset = getDataset(days); 
     renderer = getRenderer(); 
     setRendererStyling(renderer); 

     // add plot to the layout 
     if (graphicalView == null) { 
      LinearLayout layout = (LinearLayout) view.findViewById(R.idChartFragment.Chart); 
      chart= new LineChart(dataset, renderer); 
      graphicalView = new GraphicalView(getActivity(), chart); 
      renderer.setSelectableBuffer(11); 

      layout.addView(graphicalView); 
     } else{ 
      graphicalView.repaint(); 
     } 


     if(chart!=null&&firstSeries!=null){ 
      for(int i=0;i<firstSeries.getItemCount();i++){ 
       double x = firstSeries.getX(i); 
       double y = firstSeries.getY(i); 

       double[] screenPoint = chart.toScreenPoint(new double[] { x, y },0); 

       Log.i("puntos", x + "," + y + " = "+" ("+screenPoint[0]+", "+screenPoint[1]+")"); 
      } 
     } 
    } 

    /** 
    * Method for set the style of the plotter window and the string at the x 
    * axis 
    * 
    * @param mRenderer 
    *   render to put style in 
    * 
    * @param dataSetX 
    *   string to set at x axis 
    */ 
    private void setRendererStyling(XYMultipleSeriesRenderer mRenderer) { 
     mRenderer.setApplyBackgroundColor(false); 
     mRenderer.setMarginsColor(R.drawable.transperent_color); 
     mRenderer.setMargins(new int[] { 0, 0, 0, 0 }); 
     mRenderer.setShowAxes(false); 
     mRenderer.setZoomButtonsVisible(false); 
     mRenderer.setExternalZoomEnabled(false); 
     mRenderer.setPointSize(20); 
     mRenderer.setClickEnabled(false); 
     mRenderer.setDisplayValues(false); 
     mRenderer.setXLabels(0); 
     mRenderer.setYLabels(0); 
     mRenderer.setPanEnabled(false); 
     mRenderer.setZoomEnabled(false); 
     mRenderer.setShowLegend(false); 

    } 

    /** 
    * Method to introduce the values of the y axis 
    * 
    * @param dataSetY 
    *   data to set at axis y 
    * @return the data to set 
    */ 
    private XYMultipleSeriesDataset getDataset(ArrayList<Day> days) { 

     XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset(); 
     firstSeries = new XYSeries(""); 

     for (int i = 0; i < 12; i++) { 

      int value = Integer.parseInt(days.get(days.size() - (13 - i)).getValue()); 
      firstSeries.add(i, value); 

     } 
     dataset.addSeries(firstSeries); 
     return dataset; 
    } 

    /** 
    * Method for set the style of the line you want to plot and create a new 
    * renderer 
    * 
    * @return the renderer 
    */ 
    private XYMultipleSeriesRenderer getRenderer() { 
     XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer(); 
     XYSeriesRenderer r = new XYSeriesRenderer(); 
     r.setColor(getResources().getColor(R.color.grey_number_label_background)); 
     r.setLineWidth(getResources().getInteger(R.integer.chart_fragment_line_width)); 
     // r.setDisplayChartValues(true); 
     r.setPointStyle(PointStyle.POINT); 
     r.setFillPoints(true); 
     renderer.addSeriesRenderer(r); 
     return renderer; 
    } 
} 

这是布局文件:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+idChartFragment/container" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_gravity="center_horizontal"> 

    <LinearLayout 
     android:id="@+idChartFragment/Chart" 
     android:layout_width="300dp" 
     android:layout_height="300dp" 
     android:orientation="horizontal"/> 


    <AbsoluteLayout 
     android:id="@+idChartFragment/absolute" 
     android:layout_width="300dp" 
     android:layout_height="300dp"/> 

</RelativeLayout> 

第二个编辑:

我想要做这样的事情:

enter image description here

我的代码我这样做:

enter image description here

这是我的代码:

package com.insights.insights.gui; 

import java.util.ArrayList; 
import java.util.List; 

import org.achartengine.GraphicalView; 
import org.achartengine.chart.ClickableArea; 
import org.achartengine.chart.LineChart; 
import org.achartengine.chart.PointStyle; 
import org.achartengine.chart.XYChart; 
import org.achartengine.model.SeriesSelection; 
import org.achartengine.model.XYMultipleSeriesDataset; 
import org.achartengine.model.XYSeries; 
import org.achartengine.renderer.SimpleSeriesRenderer; 
import org.achartengine.renderer.XYMultipleSeriesRenderer; 
import org.achartengine.renderer.XYSeriesRenderer; 

import android.graphics.Canvas; 
import android.graphics.Paint; 
import android.graphics.Typeface; 
import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.text.Layout; 
import android.util.AttributeSet; 
import android.util.Log; 
import android.view.Gravity; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.view.ViewGroup; 
import android.view.ViewTreeObserver.OnGlobalLayoutListener; 
import android.widget.AbsoluteLayout; 
import android.widget.AbsoluteLayout.LayoutParams; 
import android.widget.Button; 
import android.widget.ImageView; 
import android.widget.LinearLayout; 
import android.widget.TextView; 
import android.widget.Toast; 

import com.google.android.maps.ItemizedOverlay.OnFocusChangeListener; 
import com.insights.insights.R; 
import com.insights.insights.local.ApplicationsController; 
import com.insights.insights.model.AppMetrics; 
import com.insights.insights.model.Application; 
import com.insights.insights.model.Applications; 
import com.insights.insights.model.Day; 

/** 
* 
* @author Manuel Plazas Palacio 
* 
*/ 
public class ChartFragment extends Fragment { 

    private XYMultipleSeriesRenderer renderer; 
    private XYMultipleSeriesDataset dataset; 
    private GraphicalView graphicalView; 
    private XYSeries firstSeries; 
    private XYChart chart = null; 

    private AbsoluteLayout absoluteLayout; 
    private ImageView point; 
    private LinearLayout pointInfoConatiner; 
    private TextView pointNumberText; 
    private TextView pointNameText; 
    private TextView pointDateText; 

    private Typeface avenirHeavy; 
    private Typeface avenirLight; 

    private String apiKey; 
    private String metricName; 
    private ArrayList<Day> days; 

    // The max and the min values displayed 
    private double max = 0; 
    private double min = 0; 

    private View view; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     apiKey = getArguments().getString(getString(R.string.tabs_activity_api_key)); 
     metricName = "Sessions"; 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View v = inflater.inflate(R.layout.chart_fragment, container, false); 

     v.findViewById(R.idChartFragment.container).requestFocus(); 

     this.view = v; 

     absoluteLayout = (AbsoluteLayout) v.findViewById(R.idChartFragment.absolute); 
     //  pointInfoConatiner = (LinearLayout) v.findViewById(R.idChartFragment.pointInfoContainer); 
     //  pointNumberText = (TextView) v.findViewById(R.idChartFragment.pointNumberText); 
     //  pointNameText = (TextView) v.findViewById(R.idChartFragment.pointNameText); 
     //  pointDateText = (TextView) v.findViewById(R.idChartFragment.pointDateText); 
     // 
     //  pointNameText.setText(metricName); 

     //  Obtaining data to plot 
     Applications applications = ApplicationsController.getInstance(getActivity()).getApplications(); 
     ArrayList<Application> applicationArray = applications.getApplication(); 

     if (applicationArray != null && !applicationArray.isEmpty()) { 
      for (int i = 0; i < applicationArray.size(); i++) { 
       if (applicationArray.get(i).getApiKey().equals(apiKey)) { 
        ArrayList<AppMetrics> appMetrics = applicationArray.get(i).getAppMetrics(); 
        for (int j = 0; j < appMetrics.size(); j++) { 
         if (appMetrics.get(j).getMetric().equals(metricName)) { 
          days = appMetrics.get(j).getDay(); 
          break; 
         } 
        } 
       } 
      } 
     } 

     // If there isn't any item to plot and show a toast 
     if (days == null) { 
      Toast toast = Toast.makeText(getActivity(), R.string.chart_fragment_no_items, Toast.LENGTH_LONG); 
      toast.show(); 
     } 

     // Ploting the items 
     dataset = getDataset(days); 
     renderer = getRenderer(); 
     setRendererStyling(renderer); 

     // add plot to the layout 
     if (graphicalView == null) { 
      LinearLayout layout = (LinearLayout) view.findViewById(R.idChartFragment.Chart); 
      chart = new LineChart(dataset, renderer); 

      graphicalView = new GraphicalView(getActivity(), chart); 
      renderer.setSelectableBuffer(11); 

      layout.addView(graphicalView); 
     } else { 
      graphicalView.repaint(); 
     } 

     return v; 
    } 

    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 

     avenirHeavy = Typeface.createFromAsset(getActivity().getAssets(), "fonts/Avenir Heavy.ttf"); 
     avenirLight = Typeface.createFromAsset(getActivity().getAssets(), "fonts/Avenir Light.ttf"); 

     graphicalView.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 

       SeriesSelection seriesSelection = graphicalView.getCurrentSeriesAndPoint(); 
       double[] xy = graphicalView.toRealPoint(0); 
       //creating the views 
       createOnClickPointsView(); 

       if (seriesSelection != null) { 

        //     debug 
        Log.d("Punto", seriesSelection.getXValue() + ", " + seriesSelection.getValue()); 

        double x = firstSeries.getX(seriesSelection.getPointIndex() + 1); 
        double y = firstSeries.getY(seriesSelection.getPointIndex() + 1); 
        double[] screenPoint = chart.toScreenPoint(new double[] { x, y }); 

        //     debug 
        Log.d("Chart point", "Chart element in series index " + seriesSelection.getSeriesIndex() + " data point index " 
          + seriesSelection.getPointIndex() + " was clicked" + " closest point value X=" + seriesSelection.getXValue() 
          + ", Y=" + seriesSelection.getValue() + " clicked point value X=" + (float) xy[0] + ", Y=" + (float) xy[1]); 
        Log.d("Punto pantalla", " (" + screenPoint[0] + ", " + screenPoint[1] + ")"); 

        int value = Integer.parseInt(days.get((int) (days.size() - (13 - x))).getValue()); 
        String date = days.get((int) (days.size() - (13 - x))).getDate(); 
        pointNumberText.setText(value + ""); 
        pointDateText.setText(date); 

        //     drawing point info 
        absoluteLayout.addView(pointInfoConatiner, new LayoutParams(getResources().getDrawable(R.drawable.graficapin) 
          .getIntrinsicWidth(), getResources().getDrawable(R.drawable.graficapin).getIntrinsicHeight(), 
          (int) (screenPoint[0] - (getResources().getDrawable(R.drawable.graficapin).getIntrinsicWidth()/2)), 
          (int) (screenPoint[1] - (getResources().getDrawable(R.drawable.graficapin).getIntrinsicHeight())))); 

        //     drawing point clicked 
        absoluteLayout.addView(point, new LayoutParams(getResources().getDrawable(R.drawable.puntoon).getIntrinsicWidth(), 
          getResources().getDrawable(R.drawable.puntoon).getIntrinsicHeight(), (int) (screenPoint[0] - (getResources() 
            .getDrawable(R.drawable.puntoon).getIntrinsicWidth()/2)), (int) (screenPoint[1] - ((getResources() 
            .getDrawable(R.drawable.puntoon).getIntrinsicHeight())/4)))); 
       } 
      } 
     }); 

    } 

    /** 
    * Method for set the style of the plotter window and the string at the x 
    * axis 
    * 
    * @param mRenderer 
    *   render to put style in 
    * 
    * @param dataSetX 
    *   string to set at x axis 
    */ 
    private void setRendererStyling(XYMultipleSeriesRenderer mRenderer) { 
     mRenderer.setApplyBackgroundColor(false); 
     mRenderer.setMarginsColor(R.drawable.transperent_color); 
     mRenderer.setMargins(new int[] { 0, 0, 0, 0 }); 
     mRenderer.setShowAxes(false); 
     mRenderer.setZoomButtonsVisible(false); 
     mRenderer.setExternalZoomEnabled(false); 
     mRenderer.setPointSize(getResources().getInteger(R.integer.chart_fragment_point_size)); 
     mRenderer.setClickEnabled(true); 
     mRenderer.setDisplayValues(false); 
     mRenderer.setXLabels(0); 
     mRenderer.setYLabels(0); 
     mRenderer.setPanEnabled(true); 
     mRenderer.setZoomEnabled(false); 
     mRenderer.setShowLegend(false); 
     mRenderer.setYAxisMax(max + 10); 
     mRenderer.setYAxisMin(min - 10); 
    } 

    /** 
    * Method to introduce the values of the y axis 
    * 
    * @param dataSetY 
    *   data to set at axis y 
    * @return the data to set 
    */ 
    private XYMultipleSeriesDataset getDataset(ArrayList<Day> days) { 

     XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset(); 
     firstSeries = new XYSeries(""); 

     for (int i = 0; i < 12; i++) { 

      int value = Integer.parseInt(days.get(days.size() - (13 - i)).getValue()); 
      firstSeries.add(i, value); 

     } 
     dataset.addSeries(firstSeries); 

     XYSeries secondSeries = new XYSeries(""); 
     for (int i = 1; i < 11; i++) { 

      int value = Integer.parseInt(days.get(days.size() - (13 - i)).getValue()); 

      if (i == 1) { 
       max = value; 
       min = value; 
      } 

      if (value > max) 
       max = value; 
      if (value < min) 
       min = value; 

      secondSeries.add(i, value); 

     } 

     dataset.addSeries(secondSeries); 
     return dataset; 
    } 

    /** 
    * Method for set the style of the line you want to plot and create a new 
    * renderer 
    * 
    * @return the renderer 
    */ 
    private XYMultipleSeriesRenderer getRenderer() { 
     XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer(); 

     //First chart with the line 
     XYSeriesRenderer r = new XYSeriesRenderer(); 
     r.setColor(getResources().getColor(R.color.grey_number_label_background)); 
     r.setLineWidth(getResources().getInteger(R.integer.chart_fragment_line_width)); 
     // r.setDisplayChartValues(true); 
     r.setPointStyle(PointStyle.POINT); 
     r.setFillPoints(true); 
     renderer.addSeriesRenderer(r); 

     //  Second chart with the points 
     XYSeriesRenderer r1 = new XYSeriesRenderer(); 
     r1.setColor(getResources().getColor(R.color.purple_chart_points)); 
     r1.setLineWidth(0); 
     r1.setFillPoints(true); 
     r1.setPointStyle(PointStyle.CIRCLE); 
     renderer.addSeriesRenderer(r1); 

     return renderer; 
    } 

    public XYSeries getFirstSeries() { 
     return firstSeries; 
    } 

    public void setFirstSeries(XYSeries firstSeries) { 
     this.firstSeries = firstSeries; 
    } 

    public XYChart getChart() { 
     return chart; 
    } 

    public void setChart(XYChart chart) { 
     this.chart = chart; 
    } 

    /** 
    * Method for create the views when clicking on a point of the chart 
    */ 
    private void createOnClickPointsView() { 
     //If the info is already visible 
     if (pointInfoConatiner != null) 
      absoluteLayout.removeView(pointInfoConatiner); 
     //    If the point is drawn 
     if (point != null) 
      absoluteLayout.removeView(point); 

     pointInfoConatiner = new LinearLayout(getActivity()); 
     pointInfoConatiner.setBackgroundDrawable(getResources().getDrawable(R.drawable.graficapin)); 
     pointInfoConatiner.setOrientation(LinearLayout.VERTICAL); 
     pointInfoConatiner.setGravity(Gravity.CENTER_HORIZONTAL); 

     LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, 
       LinearLayout.LayoutParams.WRAP_CONTENT); 
     layoutParams.setMargins(0, 8, 0, 0); 

     pointNumberText = new TextView(getActivity()); 
     pointNumberText.setTextSize(18); 
     pointNumberText.setTextColor(getResources().getColor(R.color.purple_chart_points)); 
     pointNumberText.setTypeface(avenirHeavy); 
     pointNumberText.setGravity(Gravity.CENTER); 

     pointNameText = new TextView(getActivity()); 
     pointNameText.setTextSize(18); 
     pointNameText.setTextColor(getResources().getColor(R.color.grey_users_label)); 
     pointNameText.setTypeface(avenirLight); 
     pointNameText.setText(metricName); 
     pointNameText.setGravity(Gravity.CENTER); 

     pointDateText = new TextView(getActivity()); 
     pointDateText.setTextSize(11); 
     pointDateText.setTextColor(getResources().getColor(R.color.grey_users_label)); 
     pointDateText.setTypeface(avenirHeavy); 
     pointDateText.setGravity(Gravity.CENTER); 

     pointInfoConatiner.addView(pointNumberText, 0, layoutParams); 
     layoutParams.setMargins(0, 2, 0, 0); 
     pointInfoConatiner.addView(pointNameText, 1, layoutParams); 
     pointInfoConatiner.addView(pointDateText, 2, layoutParams); 

     point = new ImageView(getActivity()); 
     point.setImageDrawable(getResources().getDrawable(R.drawable.puntoon)); 
    } 
} 

任何人都知道我怎么能:

1 - 退出底边框

2退出粉色图表的行

3的图表不动的时候我碰点

4-当我询问屏幕点为什么多次y值返回无穷

+0

感谢您的支持!这是我能够实现的一个很好的例子和答案。只有抱怨是我想要你的drawable graficapin – jcaruso

+0

我需要准确地实现这个,你能帮我吗? – user2056563

回答

1

在旧版本的AChartEngine中曾经存在这个错误。我建议你更新到1.1.0。

此外,请注意,调用该方法时必须已经显示图表。如果图表没有显示在屏幕上,那么没有办法计算出来。

+1

我在GraphicalView中添加了一个isChartDrawn()方法。你可以在这里下载这个方法的版本:https://repository-achartengine.forge.cloudbees.com/snapshot/org/achartengine/achartengine/1.2.0/ –

+0

谢谢,但我想把按钮放在图表显示时,但直到onResume结束执行我不显示图表。你知道我该怎么做? –

+0

我不明白这个问题。 –

相关问题