achartengine toScreenPoint(双)总是返回NullPointerException异常 [英] achartengine toScreenPoint(double) always returns nullPointerException

查看:502
本文介绍了achartengine toScreenPoint(双)总是返回NullPointerException异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我每次调用这个方法就返回NullPointerException异常:

Every time I call this method it return nullpointerexception:

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

java.lang.NullPointerException at org.achartengine.chart.XYChart.toScreenPoint(XYChart.java:867)

我看图表mScreenR为null

I see mScreenR of chart is null

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

Without using this method toScreenPoint(double) the charts works well this is the code:

    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;
    }
}

这是布局文件:

And this is the layout file:

<?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>

第二个编辑:

我想做的事情是这样的:

I want to do something like this:

使用我的code我这样做:

With my code I do this:

这是我的code:

 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));
    }
}

任何人都知道我怎能:

Anyone know how can I:

1,退出的底部边框

2,退出粉色图表的行

2-Quit the line of the pink chart

3的图不动

4-当我问屏幕点为什么很多次的y值返回无限

4- When I ask for the screen point why to many times the y value returns infinite

推荐答案

过去有这个bug在AChartEngine的旧版本。我建议您更新到1.1.0。

There used to be this bug in an older version of AChartEngine. I suggest you update to 1.1.0.

另外请注意,必须已经显示在图表调用方法时。如果图表未显示在屏幕上,然后就没有办法来计算

Also, please note that the chart must have been already displayed when calling the method. If the chart didn't display on screen then there is no way to calculate that.

这篇关于achartengine toScreenPoint(双)总是返回NullPointerException异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆