Java JFreeChart-将图表线的序列行程从实线更改为虚线

Java JFreeChart-将图表线的序列行程从实线更改为虚线,java,charts,jfreechart,time-series,timeserieschart,Java,Charts,Jfreechart,Time Series,Timeserieschart,这里接受的答案()帮助我开始改变图表上的系列行程线。在逐步浏览代码并查看更改后,我发现seriesstroke实际上在应该更改为“dashedStroke”(在特定日期“dashedAfter”之后)时更改为“dashedStroke”,但当图表呈现时,整个系列线都是虚线。我怎样才能让一条系列线在开始时画成实线,在设定日期后画成虚线 /* series line modifications */ final Number dashedAfter = timeNowDate.getTime();

这里接受的答案()帮助我开始改变图表上的系列行程线。在逐步浏览代码并查看更改后,我发现seriesstroke实际上在应该更改为“dashedStroke”(在特定日期“dashedAfter”之后)时更改为“dashedStroke”,但当图表呈现时,整个系列线都是虚线。我怎样才能让一条系列线在开始时画成实线,在设定日期后画成虚线

/* series line modifications */
final Number dashedAfter = timeNowDate.getTime();

XYLineAndShapeRenderer render = new XYLineAndShapeRenderer() {
  Stroke regularStroke = new BasicStroke();
  Stroke dashedStroke = new BasicStroke(
                            1.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
                            1.0f, new float[] {10.0f, 6.0f}, 0.0f );
  @Override
  public Stroke getItemStroke(int row, int column) {
    Number xVal = cd.getXValue(row, column);
    if (xVal.doubleValue() > dashedAfter.doubleValue()) { 
      return dashedStroke; 
    } else { 
      return regularStroke; 
    }
  }
};
render.setBaseShapesVisible(false);
render.setBaseShapesFilled(true);
render.setDrawSeriesLineAsPath(true);
plot.setRenderer(render);

我认为你做得对,如果它不起作用,也许就不可能了?我只是在猜,但是你可以画两条线而不是一条。第二行从第一行结束的地方开始。如果您想大量更改笔划,并且希望根据条件在循环的每次迭代中更改笔划,那么这可能会变得很混乱,您的代码可能会变得更复杂。或者只为每一行画一条新线。

您是否尝试过实现
AbstractRenderer\getItemStroke

在本例中,我使用一条虚线表示系列2的x>4:

xylineandshaperender渲染器=新的xylineandshaperender(){
行程固体=新的基本行程(2.0f);
笔划虚线=新基本行程(1.0f,基本行程.CAP_BUTT,基本行程.JOIN_MITER,10.0f,新浮动[]{10.0f},0.0f);
@凌驾
公共笔划getItemStroke(int行,int列){
如果(行==2){
double x=dataset.getXValue(行、列);
如果(x>4){
返回虚线;
}否则{
返土;
} 
}否则
返回super.getItemStroke(行、列);
}
};
renderer.setBaseShapesVisible(true);
renderer.setBaseShapesFilled(true);
setBaseStroke(新基本行程(3));
plot.setRenderer(渲染器);
虽然此示例使用and
XYSeries
而不是日期,但您应该能够根据需要修改它

下面是完整的例子

import java.awt.BasicStroke;
import java.awt.Stroke;

import javax.swing.JPanel;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;

public class LineChartDemo2 extends ApplicationFrame {

    public LineChartDemo2(String title) {
        super(title);
        JPanel chartPanel = createDemoPanel();
        chartPanel.setPreferredSize(new java.awt.Dimension(500, 270));
        setContentPane(chartPanel);
    }

    private static JFreeChart createChart(final XYDataset dataset) {

        JFreeChart chart = ChartFactory.createXYLineChart(
            "Line Chart Demo: XYLineAndShapeRenderer",     
            "X",                     
            "Y",                     
            dataset,              
            PlotOrientation.VERTICAL,
            false,                     
            false,                 
            false             
        );

        XYPlot plot = (XYPlot) chart.getPlot();
        plot.setDomainPannable(true);
        plot.setRangePannable(true);

        XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(){
            Stroke soild = new BasicStroke(2.0f);
            Stroke dashed =  new BasicStroke(1.0f,BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, new float[] {10.0f}, 0.0f);
            @Override
            public Stroke getItemStroke(int row, int column) {
                if (row == 2){
                    double x = dataset.getXValue(row, column);
                    if ( x > 4){
                        return dashed;
                    } else {
                        return soild;
                    } 
                } else
                    return super.getItemStroke(row, column);
            }
        };

        renderer.setBaseShapesVisible(true);
        renderer.setBaseShapesFilled(true);
        renderer.setBaseStroke(new BasicStroke(3));
        plot.setRenderer(renderer);
        return chart;
    }

    public static JPanel createDemoPanel() {
        JFreeChart chart = createChart(createDataset());
        ChartPanel panel = new ChartPanel(chart);
        panel.setMouseWheelEnabled(true);
        return panel;
    }

    public static void main(String[] args) {
        LineChartDemo2 demo = new LineChartDemo2(
                "JFreeChart");
        demo.pack();
        RefineryUtilities.centerFrameOnScreen(demo);
        demo.setVisible(true);
    }

    private static XYDataset createDataset() {

        XYSeries series1 = new XYSeries("First");
        series1.add(1.0, 1.0);
        series1.add(2.0, 4.0);
        series1.add(3.0, 3.0);
        series1.add(4.0, 5.0);
        series1.add(5.0, 5.0);
        series1.add(6.0, 7.0);
        series1.add(7.0, 7.0);
        series1.add(8.0, 8.0);

        XYSeries series2 = new XYSeries("Second");
        series2.add(1.0, 5.0);
        series2.add(2.0, 7.0);
        series2.add(3.0, 6.0);
        series2.add(4.0, 8.0);
        series2.add(5.0, 4.0);
        series2.add(6.0, 4.0);
        series2.add(7.0, 2.0);
        series2.add(8.0, 1.0);

        XYSeries series3 = new XYSeries("Third");
        series3.add(3.0, 4.0);
        series3.add(4.0, 3.0);
        series3.add(5.0, 2.0);
        series3.add(6.0, 3.0);
        series3.add(7.0, 6.0);
        series3.add(8.0, 3.0);
        series3.add(9.0, 4.0);
        series3.add(10.0, 3.0);

        XYSeriesCollection dataset = new XYSeriesCollection();
        dataset.addSeries(series1);
        dataset.addSeries(series2);
        dataset.addSeries(series3);

        return dataset;

    }


}
我仍然有同样的问题,线不是从实线变为虚线,而是一个或另一个

setDrawSeriesLineAsPath()
方法“控制是否将每个序列绘制为单个路径”。这阻止动态更改
笔划,因为每个序列只调用一次
getItemStroke()


附录:验证这一点的一个简单方法是在@GrahamA的示例中调用
setDrawSeriesLineAsPath()
,并在调试器中插入
drawFirstPassShape()

+1对于以下内容,这与我链接到的示例更接近,更接近我开始尝试这整件事情的地方。我希望这些建议中的一些会有所帮助,但我仍然有同样的问题,那就是线不是从实线变为虚线,而是一个或另一个。我已重新发布代码以反映更改。任何进一步的帮助都将不胜感激@MisterMichaelK如果你能一起给出一个自包含的示例(SSCCE),我将为你尝试代码。如果没有数据,很难看到发生了什么事实上,看起来我遇到了一些变量问题,这就是为什么它不能正常工作的原因。@GrahamA我尝试了这个解决方案,但我的数据集总是空的。此外,eclipse还通知我数据集将始终为空。我可能做错了什么?仅供参考-我正在使用
图表工厂.createTimeSeriesChart
。这就是问题所在吗?这也是我努力实现的一个关键组成部分。到目前为止,将setDrawSeriesLineAsPath()设置为false可以使我的图表正确运行,因为当我需要时,线条会从实线变为虚线。不幸的是,虚线大部分是实心的,除非我的图表大幅上升。我知道这与sDSLAP()方法有关,我有很多数据点,每个点之间没有足够的空间来有效地划线,除非点之间有很大的上升。有没有一种方法可以像getItemStroke()was那样有条件地设置它?NAFAIK,尽管我喜欢
ChartPanel\setMouseWheelEnabled(true)
以便于缩放。例如,我想您可以让用户根据需要切换视图。@MisterMichaelK如果点靠近,为什么不改变颜色而不是线型呢。