You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AnyChart折线图无法实时更新API数据,首次加载正常后续显旧数据

问题原因分析

从你的代码来看,导致折线图无法更新、始终显示旧数据的核心问题有两个:

  1. CustomDataEntry构造函数的逻辑错误
    你在CustomDataEntry的构造方法里,把整个List<String> x直接转成字符串传给父类的ValueDataEntry,这会导致所有数据点的x轴标识都是同一个列表的字符串(比如[2023-01,2023-02]),而不是每个数据项对应的单个x轴标签。当你第二次请求新数据时,即使数据内容变化,x轴的标识没有差异,AnyChart无法识别这是新的数据集,因此依然显示旧数据。

  2. 每次更新都重新创建完整图表,未正确处理旧状态
    你每次调用anyChartGraphViewData时都重新创建Cartesian实例并设置给anyChartView,虽然理论上可行,但AnyChart的视图可能没有完全释放旧的图表绑定,再加上数据标识的错误,最终导致更新失效。


修复方案

第一步:修复CustomDataEntry构造函数

每个CustomDataEntry对应单个数据点,应该传入当前循环的单个x轴标签,而不是整个列表:

private class CustomDataEntry extends ValueDataEntry {
    CustomDataEntry(String x, Number value1, Number value2) {
        // 父类第一个参数是单个x轴值
        super(x, value1);
        setValue("value1", value1);
        setValue("value2", value2);
    }
}

同时修改循环创建数据项的代码,传入单个x标签:

for (OpdIpdModel opdIpdModel : response.body().getOpdIpdComparison()) {
    String xLabel = opdIpdModel.getYear().shortValue() + "-" + opdIpdModel.getMonthString();
    entries1.add(new CustomDataEntry(xLabel, opdIpdModel.getoPD(), opdIpdModel.getiPD()));
}

第二步:优化图表更新逻辑(推荐)

不需要每次请求都重新创建完整的Cartesian图表,复用已有实例并仅更新数据集合,既高效又能避免视图绑定问题:

  1. 将图表核心对象改为类成员变量:
public class OpdIpdAnalysis extends AppCompatActivity implements NetworkReceiver.ConnectionChangeCallback {
    AnyChartView anyChartView;
    Set set1;
    Cartesian cartesian;
    Line series1;
    Line series2; // 新增类成员变量
    // ... 其他原有代码
}
  1. 在onCreate中初始化一次图表基础配置:
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_opd_ipd_analysis);
    anyChartView = findViewById(R.id.anyChartLineChart);
    anyChartView.setProgressBar(myProgressBar);
    
    // 仅初始化一次图表基础配置
    initChart();
}

private void initChart() {
    cartesian = AnyChart.line();
    cartesian.animation(true);
    cartesian.padding(5d, 10d, 1d, 5d);
    cartesian.crosshair().enabled(true);
    cartesian.crosshair()
        .yLabel(true)
        .yStroke((Stroke) null, null, null, (String) null, (String) null);
    cartesian.tooltip().positionMode(TooltipPositionMode.POINT);
    cartesian.title("MIS Report of comparing OPD and IPD data.");
    cartesian.xAxis(0).labels().padding(1d, 1d, 1d, 1d);
    cartesian.xAxis(0).labels().fontSize(8);
    cartesian.legend().enabled(true);
    cartesian.legend().fontSize(10d);
    cartesian.legend().padding(0d, 0d, 10d, 0d);
    cartesian.interactivity().hoverMode(HoverMode.BY_X);
    cartesian.xScroller(true);
    anyChartView.setZoomEnabled(true);
    
    // 初始化数据集和折线系列
    set1 = Set.instantiate();
    Mapping series1Mapping = set1.mapAs("{ x: 'x', value: 'value1' }");
    Mapping series2Mapping = set1.mapAs("{ x: 'x', value: 'value2' }");
    
    series1 = cartesian.line(series1Mapping);
    series1.name("OPD");
    series1.hovered().markers().enabled(true);
    series1.hovered().markers()
        .type(MarkerType.CIRCLE)
        .size(5d);
    series1.tooltip()
        .position("right")
        .anchor(Anchor.LEFT_CENTER)
        .offsetX(0d)
        .offsetY(0d);
    
    series2 = cartesian.line(series2Mapping);
    series2.name("IPD");
    series2.hovered().markers().enabled(true);
    series2.hovered().markers()
        .type(MarkerType.CIRCLE)
        .size(5d);
    series2.tooltip()
        .position("right")
        .anchor(Anchor.LEFT_CENTER)
        .offsetX(0d)
        .offsetY(0d);
    
    anyChartView.setChart(cartesian);
}
  1. 修改anyChartGraphViewData方法,仅更新数据集合:
private void anyChartGraphViewData(Response<OpdIpdModel.ModelResponse> response) {
    List<DataEntry> entries1 = new ArrayList<>();
    if (response.body() != null) {
        for (OpdIpdModel opdIpdModel : response.body().getOpdIpdComparison()) {
            String xLabel = opdIpdModel.getYear().shortValue() + "-" + opdIpdModel.getMonthString();
            entries1.add(new CustomDataEntry(xLabel, opdIpdModel.getoPD(), opdIpdModel.getiPD()));
        }
    }
    
    // 清空旧数据并设置新数据,强制图表重绘
    set1.clear();
    set1.data(entries1);
    cartesian.draw();
    anyChartView.invalidate();
}

第三步:确保UI更新在主线程

Retrofit的onResponse回调默认在主线程执行,所以你的现有代码没问题,但如果后续有其他异步操作,要确保更新图表的代码在主线程:

runOnUiThread(() -> {
    anyChartGraphViewData(response);
});

验证说明

完成以上修改后,第二次请求新数据时,数据集的x轴标签会是正确的单个值,图表会识别到新数据并更新显示。如果仍有问题,可以尝试在设置新数据前调用anyChartView.clear()清空旧图表视图。

内容的提问来源于stack exchange,提问作者Aleef Faminn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 14:57:51