Prevent JFreeChart DialPlot wrapping around with large values?

前端 未结 2 848
忘掉有多难
忘掉有多难 2020-11-30 15:37

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 fi

相关标签:
2条回答
  • 2020-11-30 15:54

    I've just figured out a work-around answer, but I would be interested to hear if there are better methods.

    In this solution, I maintain two DefaultValueDataset objects. One contains the real value and one contains a constrained value, no larger than my dial limit. The needle is associated with the constrained set and the dial value is linked to the real value.

    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));
      }
    }
    
    0 讨论(0)
  • 2020-11-30 16:00

    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

    0 讨论(0)
提交回复
热议问题