0

我问这个问题是因为,我不清楚为什么每次用户选择解析 1 天或 1 周或 1 个月的数据时我的图表都不会更新。类似的如何在 android 的 Shinobi 折线图中更新/删除/插入新系列/数据?

我尝试了一位名叫 Kai 的成员提供的答案,显然他为 shinobicontrols 工作。

您可能还注意到,我在 GraphFragment 中实现了 shinobichart 库,该库位于视图寻呼机中,它导入 android.android.support.v4.app.Fragment;

ViewPagerAdapter 类导入 import android.support.v4.app.FragmentPagerAdapter; 调用 GraphFragment 类的片段事务从解析 JSON 图形数据的另一个活动中捆绑一组图形数据。我试图澄清这个问题,以便当您至少阅读我的代码时,您会知道问题不在于 JSON 数据,因为它是根据 1 周、1 天或 1 个月相应地提取的。问题是 Shinobichart 确实删除了该系列及其数据,但没有绘制新的解析数据。我阅读了 shinobichart 用户指南如何处理图表生命周期,但找不到我想要的解决方案。我还为开发人员阅读了 ChartFragment 句柄 onPause 和 onResume,我想知道这是否同样适用于 SupportChartFragment。

这是我集成了 shinobichart 的 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 的主要活动。我扩展了 SupportChartFragment,并在 ViewPager 中保存了 3 个图表。我的活动中有 3 个按钮,分别将 3、6 和 12 个月的数据加载到图表中。

出于本练习的目的,我使我的数据非常简单,我只是对其进行硬编码。我成功地能够在单击按钮时动态重新加载我的数据。你可以在这里看到我在 GitHub 上的应用:

https://github.com/Kai2k/ViewPagerChartFragment

我可以对您的代码提出几点意见:

要重新加载图表,您不一定需要删除轴和系列。话虽如此,每次向 DataAdapter 添加数据点时,都会调用图表的完整绘制,这可能会影响性能。因此,您可能希望从您的系列中分离您的 DataAdapter,更新您的数据,然后重新附加它。

我注意到你已经让你的 Fragment 实现了 OnClickListener。我注意到使用这种方法时图表最初并没有更新,但实际上 ViewPager 中的另一个图表(当前不在屏幕上)被更新了。我注意到,当我在 ViewPager 中对页面进行分页时,所有包含的图表都已更新。目前,我还不是 ViewPager 类如何在内部处理片段的创建和销毁方面的专家,但这肯定是需要进一步研究的领域。

当我在 Activity 中设置点击侦听器并“推送”命令以重新加载到当前片段时,它可以工作。

您的 LoadAssetGraphTask 也可能存在问题,我认为这是一个 AsyncTask。显然我目前看不到这段代码,所以我不知道这个类会做什么。您是否首先尝试过一种更简单的方法,在 Fragment 中使用虚拟数据(就像我一样)来排除 AsyncTask 的任何问题?

SupportChartFragment 和 ChartFragment 会为您处理生命周期回调,因此您不需要覆盖 onPause 或 onResume。但是,如果您尝试将 Fragment 嵌套在另一个 Fragment 中,您可能会遇到问题,因为 ChartFragment/SupportChartFragment 在重新创建 Activity 时会保留,并且 Android 框架不允许在其他 Fragment 中保留 Fragment。如果您的用例要求这样做,您可能会发现使用 ChartView 是一种更合适的方法。在这种情况下,您需要处理生命周期回调。

如果您希望使用 ChartFragment 或 SupportChartFragment,另一种方法可能是直接扩展类,而不是扩展 Fragment。这是我在我的应用程序中采用的方法。使用这种方法,您在膨胀嵌套片段时不太可能遇到膨胀问题。

我希望这个对你有用。谢谢,凯。

免责声明 - 我为 Shinobicontrols 工作。

于 2015-10-13T20:27:24.780 回答