Java 是否防止JFreeChart DialPlot使用大值环绕?

Java 是否防止JFreeChart DialPlot使用大值环绕?,java,jfreechart,Java,Jfreechart,我的数据值可以在0-100之间变化。我想显示一个JFreeChart拨号图,显示范围0-30,其中大于30的值通过指针固定在30来显示,但实际值显示在刻度盘上 下图显示了示例代码当前生成的内容: 电流输出 这里我显示的是值50。表盘绕到了14点。我希望将其设置为最大值(30),就像燃油刻度盘一样: 所需输出 这在JFreeChart中可能吗?SSCCE代码如下 public class DemoChartProblem { private final DefaultValueDatas

我的数据值可以在0-100之间变化。我想显示一个JFreeChart拨号图,显示范围0-30,其中大于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));
  }
}

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

在这个解决方案中,我维护了两个
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));
  }
}
我很想知道是否有更好的方法

DialValueIndicator
maximumValue
之间的差异可能令人混淆。或者,使用
StandardDialRange
表示不同的范围:

int redLine = 3 * maximumValue / 5;
plot.addLayer(new StandardDialRange(minimumValue, redLine, Color.blue));
plot.addLayer(new StandardDialRange(redLine, maximumValue, Color.red));
设置帧的首选大小是。相反,请重写
ChartPanel
getPreferredSize()
方法:

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

+1 for.@trashgood我通常是第一个排队问“你的SSCE在哪里?!”,所以我很难满足:-)谢谢你的回答。在我的实际应用中,我以类似的方式加入了范围颜色,以突出表盘的最末端。我将它们从SSCCE中删除,因为它们当时似乎无关紧要。关于首选尺寸的评论,您是完全正确的-我在SSCCE中很懒:-)关于差异,它确实可能会引起混淆。然而,我认为我的选择是有限的,因为我的实际数据范围可能比我在简化问题中提出的要大得多。然而,标准操作范围如建议的(0-30)。要直观地向用户展示这种情况并不容易。@DuncanJones:这是有道理的。您可能会看到其他一些视觉指示,表明这是一个有意的特征,而不是异常。可能是DialValueIndicator的不同颜色,或者是org.jfree.chart.annotations的不同颜色,好主意。我把针头染成红色,或者类似的颜色。因为我的工作是目前我找到的实现最初目标的唯一方法,所以我把这个标记为答案。