0

この質問をしているのは、ユーザーが 1 日、1 週間、または 1 か月単位でデータを解析することを選択するたびにグラフが更新されない理由がはっきりしないためです。Androidの忍折れ線グラフで新しいシリーズ/データを更新/削除/挿入する同様の方法は?

シノビコントロールズで働いているらしいカイというメンバーの回答を試してみました。

また、android.android.support.v4.app.Fragment をインポートするビュー ページャーに配置されている GraphFragment 内に、シノビチャート ライブラリを実装したことにも気付くかもしれません。

ViewPagerAdapter クラスのインポート import android.support.v4.app.FragmentPagerAdapter; そして、GraphFragment クラスを呼び出すフラグメント トランザクションは、JSON グラフデータを解析する別のアクティビティからグラフ データの配列をバンドルします。この質問を明確にしようとしているので、少なくとも私のコードを読んだときに、1week、1day、または 1month に基づいて適切にプルされるため、問題は JSON データではないという考えが得られます。問題は、Shinobichart がシリーズとそのデータを削除するが、新しい解析データをプロットしないことです。shinobichart のユーザー ガイド チャートのライフ サイクルの処理方法を読みましたが、必要な解決策が見つかりませんでした。開発者向けの ChartFragment ハンドル onPause および onResume も読みましたが、SupportChartFragment にも同じことが当てはまるのではないかと思います。

これがシノビチャートを統合した私のGraphFragmentです。誰かが助けてくれることを願っています。前もって感謝します。

public class GraphFragment extends Fragment implements OnClickListener, 
        ShinobiChart.OnCrosshairActivationStateChangedListener{

private static final int CROSSHAIR_INACTIVE_COLOR = Color.argb(255, 240, 240, 240);
private static final int CROSSHAIR_ACTIVE_COLOR = Color.argb(150, 0, 0, 0);
Context context;
String label_x[];
ArrayList<DataAssetGraph> alAssetGraph = new ArrayList<DataAssetGraph>();
Button btnOneDayG, btnOneWeekG, btnOneMonthG;
String endDate;
String assetId;
ProgressDialog dialog;
ShinobiChart shinobiChart;
LineSeries series;
SupportChartFragment chartFragment;
String startDate;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    super.onCreateView(inflater, container, savedInstanceState);
    View view = null;
    view = inflater.inflate(R.layout.fragment_chart, null);
    initView(view);
    if (getArguments() != null) {
        alAssetGraph = (ArrayList<DataAssetGraph>) getArguments()
                .getSerializable(WebElement.RECORDS);
        if (alAssetGraph != null && alAssetGraph.size() > 0) {
            // DrawGraph(alAssetGraph);
             // Only setup the chart the first time the activity is created
            if (savedInstanceState == null) {
                // Log.d("Init Graph", "Retrieve"+ alAssetGraph);
                chartFragment =
                      (SupportChartFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.chart);
                    shinobiChart = chartFragment.getShinobiChart();
                    // TODO: replace <license_key_here> with you trial license key
                    shinobiChart.setLicenseKey("sCVfKPnWajLtffqMjAxNTA0MThzdGVybmx5QHJpZ2h0Y2xpY2t" +
                            "tZWRpYS5jby56YQ==rveipQf9y4819/K4wLwWKR86Q1RIViUBTLEhBXAwh6q5zW53TgYi" +
                            "JcIUvc3S7DhTfH4KzUNeol9Rc5rXrzLOBnzP0TStc8n+eytCBhUFEgR21Cv7gq1dLEvOu" +
                            "tLENUwUtZ6Crk+Z8syIKEuyfZ8/1gtPvHIc=BQxSUisl3BaWf/7myRmmlIjRnMU2cA7q+" +
                            "/03ZX9wdj30RzapYANf51ee3Pi8m2rVW6aD7t6Hi4Qy5vv9xpaQYXF5T7XzsafhzS3hbBo" +
                            "kp36BoJZg8IrceBj742nQajYyV7trx5GIw9jy/V6r0bvctKYwTim7Kzq+YPWGMtqtQoU=" +
                            "PFJTQUtleVZhbHVlPjxNb2R1bHVzPnh6YlRrc2dYWWJvQUh5VGR6dkNzQXUrUVAxQnM5b2" +
                            "VrZUxxZVdacnRFbUx3OHZlWStBK3pteXg4NGpJbFkzT2hGdlNYbHZDSjlKVGZQTTF4S2Zwe" +
                            "WZBVXBGeXgxRnVBMThOcDNETUxXR1JJbTJ6WXA3a1YyMEdYZGU3RnJyTHZjdGhIbW1BZ21PTT" +
                            "dwMFBsNWlSKzNVMDg5M1N4b2hCZlJ5RHdEeE9vdDNlMD08L01vZHVsdXM+PEV4cG9uZW50Pk" +
                            "FRQUI8L0V4cG9uZW50PjwvUlNBS2V5VmFsdWU+");
                    // Create the series
                    createLineSeries(alAssetGraph);

                   // Add this Activity as a listener for any crosshair changes
                   shinobiChart.setOnCrosshairActivationStateChangedListener(this);

            }

        } else {

        }
    }

    return view;
}
private void initView(View view)
{
    btnOneDayG=(Button)view.findViewById(R.id.btnOneDayG);
    btnOneWeekG=(Button)view.findViewById(R.id.btnOneWeekG);
    btnOneMonthG=(Button)view.findViewById(R.id.btnOneMonthG);
    btnOneDayG.setSelected(true);
    btnOneDayG.setOnClickListener(this);
    btnOneMonthG.setOnClickListener(this);
    btnOneWeekG.setOnClickListener(this);
}
@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.btnOneDayG:
        btnOneWeekG.setSelected(false);
        btnOneMonthG.setSelected(false);
        if(!btnOneDayG.isSelected())
        {
            btnOneDayG.setSelected(true);
            startDate=GlobalData.getDateBeforeOneDay();
            getGraphHistory(startDate);
            System.out.println("Btn Date 1 day: %tc"+startDate);
        }
        break;

    case R.id.btnOneWeekG:
        btnOneDayG.setSelected(false);
        btnOneMonthG.setSelected(false);
        if(!btnOneWeekG.isSelected())
        {
            btnOneWeekG.setSelected(true);
            startDate=GlobalData.getDateBeforeOneWeek();
            getGraphHistory(startDate);
            System.out.println("Btn Date 1 week: %tc"+startDate);

        }
        break;
    case R.id.btnOneMonthG:
        btnOneWeekG.setSelected(false);
        btnOneDayG.setSelected(false);
        if(!btnOneMonthG.isSelected())
        {
            btnOneMonthG.setSelected(true);
            startDate=GlobalData.getDateBeforeOneMonth();
            getGraphHistory(startDate);
            System.out.println("Btn Date 1 Month: %tc"+startDate);
        }
        break;

    default:
        break;
    }       
}

private void createLineSeries(ArrayList<DataAssetGraph> alGraph) {
    // TODO Auto-generated method stub
    shinobiChart.getSeries();

    // remove Series
    while (shinobiChart.getSeries().size() > 0) {
        shinobiChart.removeSeries(shinobiChart.getSeries().get(0));
    }

    // remove Axis
    while (shinobiChart.getAllXAxes().size() > 0) {
        shinobiChart.removeXAxis(shinobiChart.getAllXAxes().get(0));
    }
    while (shinobiChart.getAllYAxes().size() > 0) {
        shinobiChart.removeYAxis(shinobiChart.getAllYAxes().get(0));
    }
    // Create the X-axis, showing ticks daily with a custom format and
    // clipping the tick at the far right
    DateTimeAxis xAxis = new DateTimeAxis();
    // xAxis.setTitle("Date/Time");
    xAxis.enableGesturePanning(true);
    xAxis.enableGestureZooming(true);
    xAxis.getDoubleTapBehavior();
     // Create the Y-axis, clipping the tick at the top
    NumberAxis yAxis = new NumberAxis();
    // yAxis.setTitle("Temperature");
    yAxis.enableGesturePanning(true);
    yAxis.enableGestureZooming(true);

    // Declare length of graph array
    int length=alGraph.size();

    LineSeries series = new LineSeries();

    series.getStyle().getPointStyle().setPointsShown(false);

    DataAdapter<Date, Double> data = new SimpleDataAdapter<Date, Double>();

    for(int i=0;i<length;i++)
    {
        String dateString=alGraph.get(i).x_cord;
        double y_cord=  alGraph.get(i).y_cord;
        Date x_cord=convertToDate(dateString);
        data.add(new DataPoint<Date, Double>(x_cord, y_cord));
    }
    // reload and redraw the graph
     series.setDataAdapter(data);
     series.setCrosshairEnabled(true);
     shinobiChart.addSeries(series, xAxis, yAxis);
     series.getStyle().setLineColor(Color.WHITE);
     System.out.println("Add Series");
     // Style the chart and the crosshair
     shinobiChart.getStyle().setPlotAreaBackgroundColor(
              GraphFragment.CROSSHAIR_ACTIVE_COLOR);
     shinobiChart.getCrosshair().getStyle().setLineColor(Color.BLUE);
     shinobiChart.getStyle().setBackgroundColor(Color.WHITE);
     // shinobiChart.getStyle().setPlotAreaBackgroundColor(Color.BLACK);
     shinobiChart.getStyle().getBackgroundColor();
     shinobiChart.getXAxis().getStyle().getGridlineStyle().setGridlinesShown(true);
     shinobiChart.getYAxis().getStyle().getGridlineStyle().setGridlinesShown(true);
     // Remember to redraw the chart to make the changes visible
     shinobiChart.redrawChart();
}

private Date convertToDate(String dateString)
{
    Date convertedDate= new Date();

    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
    try 
    {
        convertedDate = dateFormat.parse(dateString);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        return null;
    }

    return convertedDate;
}

private void getGraphHistory(String start_date)
{
        System.out.println("Get graph History: %tc"+ start_date);
        dialog= new ProgressDialog(getActivity());
        dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        dialog.setMessage("Retrieving graph...");
        dialog.setCanceledOnTouchOutside(false);
        dialog.show();
        endDate=GlobalData.getCurrentDate();
        assetId=ComponentActivity.assetId;
        new LoadAssetGraphTask(getActivity(),assetId, start_date,endDate)
        {
            @Override
            protected void onPostExecute(ArrayList<DataAssetGraph> result) 
            {
                super.onPostExecute(result);
                if(dialog.isShowing())
                    dialog.dismiss();
                if(result!=null && result.size()>0)
                {   
                    createLineSeries(result);
                    System.out.println("onPostExecute Called");
                }

            };
        }.execute();


    //}
}

@Override
public void onCrosshairActivationStateChanged(ShinobiChart chart) {
    // Set the plot area background color depending on the crosshair's
    // activation state
    if (chart.getCrosshair().isActive()) {
        chart.getStyle().setPlotAreaBackgroundColor(GraphFragment.CROSSHAIR_ACTIVE_COLOR);
        chart.getLegend().getStyle().setTextColor(Color.WHITE);
    }
    else {
        chart.getStyle().setPlotAreaBackgroundColor(GraphFragment.CROSSHAIR_INACTIVE_COLOR);
        chart.getLegend().getStyle().setTextColor(Color.BLACK);
    }

    // Remember to redraw the chart to make the color change visible
    chart.redrawChart();
}
4

1 に答える 1

0

お問い合わせいただいてからしばらく経ちますが、よろしくお願いいたします。未回答ですので、他の方から同様の質問があった場合に備えて、お答えしたいと思います。

あなたのコードが何をしているかの全体像を把握するのは難しいので、残りのコードを投稿していただけますか? たとえば、レイアウト ファイル、アクティビティ ファイル、LoadAssetGraphTask ファイルなどです。

それまでの間、ViewPager を含む 1 つのメイン アクティビティを持つ単純なアプリケーションを作成しました。SupportChartFragment を拡張し、ViewPager に 3 つのグラフを保持しています。アクティビティに 3 つのボタンがあり、3 か月、6 か月、12 か月のデータをグラフに読み込みます。

この演習の目的のために、データを非常にシンプルに保ち、単純にハードコーディングしました。ボタンをクリックすると、データを動的に再ロードできるようになりました。ここで GitHub で私のアプリを見ることができます:

https://github.com/Kai2k/ViewPagerChartFragment

私はあなたのコードについていくつかの観察を行うことができます:

チャートをリロードするために、必ずしも軸とシリーズを削除する必要はありません。そうは言っても、DataAdapter にデータ ポイントを追加するたびに、チャートの完全な描画が呼び出され、パフォーマンスが低下する可能性があります。そのため、シリーズから DataAdapter を切り離し、データを更新してから再接続することをお勧めします。

Fragment に OnClickListener を実装していることに気付きました。このアプローチを使用すると、チャートが最初は更新されていないことに気付きましたが、実際には ViewPager 内の別のチャート (現在は画面外にありました) が代わりに更新されました。ViewPager 内のページをページングすると、含まれているすべてのグラフが更新されたことに気付きました。現時点では、ViewPager クラスがフラグメントの作成と破棄を内部でどのように処理するかについて、私は専門家ではありませんが、これについてはさらに調査する必要があるかもしれません。

アクティビティにクリックリスナーを設定し、コマンドを「プッシュ」して現在のフラグメントにリロードすると、機能します。

また、AsyncTask であると思われる LoadAssetGraphTask に問題がある可能性もあります。明らかに、現在このコードを見ることができないので、このクラスが何をするのかわかりません。AsyncTask の問題を除外するために、(私が持っているように) Fragment 内にダミー データを使用して、より単純なアプローチを最初に試しましたか?

SupportChartFragment と ChartFragment はライフサイクル コールバックを処理するため、onPause または onResume をオーバーライドする必要はありません。ただし、フラグメントを別のフラグメント内にネストしようとすると、問題が発生する可能性があります。これは、ChartFragment/SupportChartFragment がアクティビティの再作成後も保持され、Android フレームワークが他のフラグメント内に保持されたフラグメントを許可しないためです。ユースケースでこれが指示されている場合は、ChartView を使用する方がより適切なアプローチであることがわかる場合があります。この場合、ライフサイクルのコールバックを処理する必要があります。

ChartFragment または SupportChartFragment を使用する場合、Fragment を拡張するのではなく、クラスを直接拡張する別の方法があります。これは、私がアプリで採用したアプローチです。このアプローチを使用すると、ネストされたフラグメントを膨張させるときに膨張の問題が発生する可能性が低くなります。

これが役立つことを願っています。ありがとう、カイ。

免責事項 - 私はシノビコントロールズで働いています。

于 2015-10-13T20:27:24.780 に答える