JFreeChart中按索引调用setSeriesPaint设置颜色始终无效
问题分析与解决方案
你的问题出在两个核心点:
- 每个单独的SMA数据集(sma100、sma200)里仅包含一个系列(索引为0),你调用
setSeriesPaint(1, ...)和setSeriesPaint(2, ...)是给不存在的系列设置颜色,自然不会生效,渲染器只会使用默认的蓝色。 - 你把同一个
XYLineAndShapeRenderer实例绑定到了两个数据集,后续对渲染器的配置会覆盖之前的设置,最终两个数据集都会使用最后一次设置的颜色。
下面是两种可行的修复方案:
方案一:给每个SMA数据集单独分配渲染器
为每个SMA数据集创建独立的渲染器,针对各自数据集里的系列(索引0)设置颜色:
CandlestickRenderer renderer = new CandlestickRenderer(); renderer.setAutoWidthMethod(CandlestickRenderer.WIDTHMETHOD_SMALLEST); DateAxis xAxis = new DateAxis("Time"); XYPlot pricePlot = new XYPlot(ohlcDataset, xAxis, new NumberAxis("Price"), renderer); // 设置SMA数据集 pricePlot.setDataset(1, createSMADataset(this.series, 100)); pricePlot.setDataset(2, createSMADataset(this.series, 200)); pricePlot.mapDatasetToRangeAxis(1, 0); pricePlot.mapDatasetToRangeAxis(2, 0); // 给sma100创建专属渲染器 XYLineAndShapeRenderer sma100Renderer = new XYLineAndShapeRenderer(true, false); sma100Renderer.setSeriesPaint(0, Color.BLUE); pricePlot.setRenderer(1, sma100Renderer); // 给sma200创建专属渲染器 XYLineAndShapeRenderer sma200Renderer = new XYLineAndShapeRenderer(true, false); sma200Renderer.setSeriesPaint(0, Color.RED); pricePlot.setRenderer(2, sma200Renderer); // 其他配置保持不变 pricePlot.setRangeGridlinePaint(Color.WHITE); pricePlot.setDomainGridlinesVisible(false); pricePlot.setRangeGridlinesVisible(false); NumberAxis numberAxis = (NumberAxis) pricePlot.getRangeAxis(); pricePlot.setDatasetRenderingOrder(DatasetRenderingOrder.FORWARD); pricePlot.setRangeAxisLocation(AxisLocation.TOP_OR_RIGHT); numberAxis.setAutoRangeIncludesZero(false); // combinedPlot配置 CombinedDomainXYPlot combinedPlot = new CombinedDomainXYPlot(xAxis); combinedPlot.setGap(10.0); combinedPlot.setOrientation(PlotOrientation.VERTICAL); combinedPlot.add(pricePlot, 80); combinedPlot.add(getRSIPlot(), 20);
方案二:将两个SMA系列合并到同一个数据集
把sma100和sma200放到同一个数据集里,用一个渲染器针对不同系列索引设置颜色:
首先需要一个合并SMA数据集的方法(示例):
private XYDataset createCombinedSMADataset(OHLCSeries series, int... periods) { XYSeriesCollection dataset = new XYSeriesCollection(); for (int period : periods) { XYSeries smaSeries = calculateSMA(series, period); // 替换为你自己的SMA计算逻辑 smaSeries.setName("SMA" + period); dataset.addSeries(smaSeries); } return dataset; }
然后修改主代码:
CandlestickRenderer renderer = new CandlestickRenderer(); renderer.setAutoWidthMethod(CandlestickRenderer.WIDTHMETHOD_SMALLEST); DateAxis xAxis = new DateAxis("Time"); XYPlot pricePlot = new XYPlot(ohlcDataset, xAxis, new NumberAxis("Price"), renderer); // 设置合并后的SMA数据集 XYDataset smaCombinedDataset = createCombinedSMADataset(this.series, 100, 200); pricePlot.setDataset(1, smaCombinedDataset); pricePlot.mapDatasetToRangeAxis(1, 0); // 用一个渲染器设置两个系列的颜色 XYLineAndShapeRenderer smaRenderer = new XYLineAndShapeRenderer(true, false); smaRenderer.setSeriesPaint(0, Color.BLUE); // SMA100对应系列0 smaRenderer.setSeriesPaint(1, Color.RED); // SMA200对应系列1 pricePlot.setRenderer(1, smaRenderer); // 其他配置保持不变 pricePlot.setRangeGridlinePaint(Color.WHITE); pricePlot.setDomainGridlinesVisible(false); pricePlot.setRangeGridlinesVisible(false); NumberAxis numberAxis = (NumberAxis) pricePlot.getRangeAxis(); pricePlot.setDatasetRenderingOrder(DatasetRenderingOrder.FORWARD); pricePlot.setRangeAxisLocation(AxisLocation.TOP_OR_RIGHT); numberAxis.setAutoRangeIncludesZero(false); // combinedPlot配置 CombinedDomainXYPlot combinedPlot = new CombinedDomainXYPlot(xAxis); combinedPlot.setGap(10.0); combinedPlot.setOrientation(PlotOrientation.VERTICAL); combinedPlot.add(pricePlot, 80); combinedPlot.add(getRSIPlot(), 20);
内容的提问来源于stack exchange,提问作者BitQueen
相关产品推荐
相关产品推荐

