9

ここで受け入れられた答え(JFreechart(Java)-部分的に破線と部分的に実線の線を描く方法は?)は、チャート上のシリーズストロークラインを変更する道を歩み始めるのに役立ちました。コードをステップ実行して変更を確認した後、シリーズストロークが実際には「dashedStroke」に変更されることがわかります(特定の日付「dashedAfter」の後)が、グラフがレンダリングされると、シリーズライン全体が破線になります。一連の線を最初に実線で描画し、設定した日付の後に破線にする方法を教えてください。

/* 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);
4

3 に答える 3

7

実装してみましたAbstractRenderer#getItemStrokeか?

ここに画像の説明を入力してください

この例では、シリーズ2のx>4に破線を使用しています。

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);

この例では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;

    }


}
于 2012-11-06T09:02:55.023 に答える
1

私はまだ線が実線から破線に変わらず、どちらかであるという同じ問題を抱えています。

このsetDrawSeriesLineAsPath()メソッドは、「各シリーズを単一のパスとして描画するかどうかを制御します」。これにより、シリーズごとに 1 回だけ呼び出されるため、Strokeを動的に変更することができなくなります。getItemStroke()

補遺: これを確認する簡単な方法はsetDrawSeriesLineAsPath()、@GrahamA の例で呼び出しdrawFirstPassShape()、デバッガーに割り込むことです。

于 2012-11-06T18:29:45.027 に答える
0

あなたはそれを正しくやっていると思いますが、うまくいかない場合はおそらく不可能ですか?ここで推測するだけですが、1 本ではなく 2 本の線を引くこともできます。2 本目の線は最初の線が終わったところから始まります。ストロークを大幅に変更したい場合は面倒になる可能性があり、条件に応じてループの反復ごとにストロークを変更したい場合、コードはおそらくさらに複雑になります。または、それぞれに新しい線を引くだけです。

于 2012-11-05T21:18:54.727 に答える