防止JFreeChart DialPlot包含大值?

我的数据值可以在0到100之间变化。 我想显示一个显示范围0-30的JFreeChart DialPlot,其中通过将针固定在30但显示在表盘上的真实值显示大于30的值。

下图显示了我的示例代码当前生成的内容:

电流输出

拨打示例

这里我显示的是值50.表盘已经四处转动指向14.我希望它设置为最大值(30),就像燃料表盘一样:

期望的输出

在此处输入图像描述

这可能与JFreeChart一起使用吗? 下面的SSCCE代码。

public class DemoChartProblem { private final DefaultValueDataset dataset = new DefaultValueDataset(50); private final JFrame frame = new JFrame(); public static void main(String[] args) throws Exception { new DemoChartProblem(); } public DemoChartProblem() { frame.setPreferredSize(new Dimension(300, 300)); frame.add(buildDialPlot(0, 30, 5)); frame.pack(); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { frame.setVisible(true); } }); } private ChartPanel buildDialPlot(int minimumValue, int maximumValue, int majorTickGap) { DialPlot plot = new DialPlot(dataset); plot.setDialFrame(new StandardDialFrame()); plot.addLayer(new DialValueIndicator(0)); plot.addLayer(new DialPointer.Pointer()); StandardDialScale scale = new StandardDialScale(minimumValue, maximumValue, -120, -300, majorTickGap, majorTickGap - 1); scale.setTickRadius(0.88); scale.setTickLabelOffset(0.20); plot.addScale(0, scale); return new ChartPanel(new JFreeChart(plot)); } } 

我很想知道是否有更好的方法。

DialValueIndicatormaximumValue之间的差异可能令人困惑。 或者,使用StandardDialRange表示不同的范围:

 int redLine = 3 * maximumValue / 5; plot.addLayer(new StandardDialRange(minimumValue, redLine, Color.blue)); plot.addLayer(new StandardDialRange(redLine, maximumValue, Color.red)); 

设置框架的首选尺寸是有问题的 。 而是覆盖ChartPanelgetPreferredSize()方法:

 return new ChartPanel(new JFreeChart(plot)) { @Override public Dimension getPreferredSize() { return new Dimension(300, 300); } }; 

测试图像

我刚刚想出了一个解决方法,但我很想知道是否有更好的方法。

在此解决方案中,我维护两个DefaultValueDataset对象。 一个包含实际值,一个包含约束值,不大于我的拨号限制。 针与受约束的组相关联,并且刻度盘值与实际值相关联。

 public class DemoChartProblem { private static final int DISPLAY_MAX = 30; private final DefaultValueDataset dataset = new DefaultValueDataset(); private final DefaultValueDataset displayDataset = new DefaultValueDataset(); private final JFrame frame = new JFrame(); public static void main(String[] args) throws Exception { new DemoChartProblem(); } public DemoChartProblem() { frame.setPreferredSize(new Dimension(300, 300)); frame.add(buildDialPlot(0, DISPLAY_MAX, 5)); frame.pack(); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); setValue(50); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { frame.setVisible(true); } }); } private void setValue(int value) { dataset.setValue(value); displayDataset.setValue(Math.min(DISPLAY_MAX, value)); } private ChartPanel buildDialPlot(int minimumValue, int maximumValue, int majorTickGap) { DialPlot plot = new DialPlot(); plot.setDataset(0, dataset); plot.setDataset(1, displayDataset); plot.setDialFrame(new StandardDialFrame()); // value indicator uses the real data set plot.addLayer(new DialValueIndicator(0)); // needle uses constrained data set plot.addLayer(new DialPointer.Pointer(1)); StandardDialScale scale = new StandardDialScale(minimumValue, maximumValue, -120, -300, majorTickGap, majorTickGap - 1); scale.setTickRadius(0.88); scale.setTickLabelOffset(0.20); plot.addScale(0, scale); return new ChartPanel(new JFreeChart(plot)); } }