Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent JFreeChart DialPlot wrapping around with large values?

My data value can vary between 0-100. I would like to display a JFreeChart DialPlot showing the range 0-30, where values larger than 30 are displayed by having the needle fixed at 30 but the true value displayed on the dial.

The image below shows what my example code currently produces:

Current Output

dial example

Here I am displaying the value 50. The dial has wrapped around to point at 14. I would prefer it to be set to the maximum (30), much like with a fuel dial:

Desired Output

enter image description here

Is this possible with JFreeChart? SSCCE code below.

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));
  }
}
like image 836
Duncan Jones Avatar asked Dec 18 '25 04:12

Duncan Jones


1 Answers

I would be interested to hear if there are better methods.

The disparity between the DialValueIndicator and the maximumValue may be confusing. As an alternative, signify distinct ranges using StandardDialRange:

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

Setting the frame's preferred size is problematic. Instead, override the getPreferredSize() method of ChartPanel:

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

test image

like image 125
trashgod Avatar answered Dec 19 '25 21:12

trashgod



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!