同一数据源下TimeSeries Chart按条件为不同区间设置不同颜色的问题
JFreeChart 原生的 TimeSeries 不支持直接为单个数据点设置展示颜色,你可以根据实际需求从以下三种方案中选择:
方案1:拆分多TimeSeries实现线段颜色高亮(最简单通用)
把不同条件的数据拆分到多个独立的TimeSeries中,分别为每个Series设置专属颜色,为了避免线段断裂,两个相邻不同类型的Series需要补全公共数据点:
// 普通收支时序,默认颜色 final TimeSeries normalSeries = new TimeSeries("普通收支"); // 转账类型时序,高亮颜色 final TimeSeries transferSeries = new TimeSeries("转账记录"); for (IncomeBalanceState incomeBalanceState : incomeBalanceStates) { if (incomeBalanceState.getIncomeType() == FuturesIncomeType.COMMISSION) { continue; } Day currentDay = dateTimeToDay(incomeBalanceState.getDateTime()); BigDecimal balance = incomeBalanceState.getAvailableBalance(); // 普通类型只加普通序列 if (incomeBalanceState.getIncomeType() != FuturesIncomeType.TRANSFER) { normalSeries.addOrUpdate(currentDay, balance); } // 转账类型同时加两个序列,保证线段连续 else { normalSeries.addOrUpdate(currentDay, balance); transferSeries.addOrUpdate(currentDay, balance); } } // 组装数据集 TimeSeriesCollection dataset = new TimeSeriesCollection(); dataset.addSeries(normalSeries); dataset.addSeries(transferSeries); // 为不同序列设置颜色 XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(); renderer.setSeriesPaint(0, Color.DARK_GRAY); // 普通序列灰色 renderer.setSeriesPaint(1, Color.RED); // 转账序列红色高亮 // 统一配置是否显示线段、数据点 renderer.setSeriesLinesVisible(0, true); renderer.setSeriesShapesVisible(0, false); renderer.setSeriesLinesVisible(1, true); renderer.setSeriesShapesVisible(1, false); // 绑定渲染器到图表 XYPlot plot = chart.getXYPlot(); plot.setRenderer(renderer);
方案2:添加区间背景高亮
如果需要标记的是连续时间区间,直接在X轴维度添加背景色块更直观:
XYPlot plot = chart.getXYPlot(); // 自定义区间起止时间戳 long intervalStart = ...; long intervalEnd = ...; IntervalMarker transferMarker = new IntervalMarker(intervalStart, intervalEnd); // 半透明红色背景,红色边框 transferMarker.setPaint(new Color(255, 0, 0, 50)); transferMarker.setOutlinePaint(Color.RED); // 添加到底层背景 plot.addDomainMarker(transferMarker, Layer.BACKGROUND);
方案3:自定义渲染器动态判断颜色
如果不想拆分多Series,可以重写渲染器的取色逻辑,按当前数据点所属条件动态返回颜色:
XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer() { @Override public Paint getItemPaint(int row, int column) { TimeSeries series = ((TimeSeriesCollection) getPlot().getDataset()).getSeries(row); Day currentDay = (Day) series.getDataItem(column).getPeriod(); Date pointDate = currentDay.getStart(); // 自定义条件判断 if (isTransferRecord(pointDate)) { return Color.RED; } return Color.DARK_GRAY; } }; // 绑定渲染器到图表即可 chart.getXYPlot().setRenderer(renderer);
注意事项
- 现有代码中
incomeBalance.getIncomeType()为笔误,需要修改为incomeBalanceState.getIncomeType() - 如果标记区间为多段不连续区间,优先选择方案2
- 如果需要单条线段上不同段显示不同颜色,优先选择方案3
内容的提问来源于stack exchange,提问作者Doomed _
相关产品推荐
相关产品推荐

