这里接受的答案(JFreechart(Java) - How to draw lines that is partially dashed lines and partially solid lines?)帮助我开始改变我的图表上的系列线条。单步执行我的代码并观察更改后,我发现我的seriesstroke实际上确实改为“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);
答案 0 :(得分:6)
您是否尝试过实施AbstractRenderer#getItemStroke
?
在这个例子中,我使用虚线表示x> 4系列2:
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;
}
}
答案 1 :(得分:1)
我仍然有同样的问题,这条线不是从固体变为虚线,而是一个或另一个。
setDrawSeriesLineAsPath()
方法“控制是否将每个系列绘制为单个路径。”这样就无法动态更改Stroke
,因为getItemStroke()
每个系列只会调用一次。
附录:验证这一点的简单方法是在@ GrahamA的示例中调用setDrawSeriesLineAsPath()
并在调试器中查看drawFirstPassShape()
。
答案 2 :(得分:0)
我认为你做得对,如果它不起作用,也许它不可能?我只是在这里猜测,但你可以画出2行代替1.你的第二行将从你的第一行结束开始。如果你想改变笔划很多,那么你可能会变得很乱,因为你想根据条件在每次迭代循环中改变它,你的代码可能会变得更复杂。或者只为每个画一条新线。