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.
我的数据值可以在0到100之间变化。我想显示一个显示范围0-30的JFreeChart DialPlot,其中通过将针固定在30但显示在表盘上的真实值显示大于30的值。
The image below shows what my example code currently produces:
下图显示了我的示例代码当前生成的内容:
Current Output
电流输出
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:
这里我显示的是值50.表盘已经四处转动指向14.我希望它设置为最大值(30),就像燃料表盘一样:
Desired Output
期望的输出
Is this possible with JFreeChart? SSCCE code below.
这可能与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));
}
}
2 个解决方案
#1
4
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
:
DialValueIndicator和maximumValue之间的差异可能令人困惑。或者,使用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
:
设置框架的首选尺寸是有问题的。而是覆盖ChartPanel的getPreferredSize()方法:
return new ChartPanel(new JFreeChart(plot)) {
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
};
#2
1
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.
在此解决方案中,我维护两个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));
}
}
#1
4
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
:
DialValueIndicator和maximumValue之间的差异可能令人困惑。或者,使用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
:
设置框架的首选尺寸是有问题的。而是覆盖ChartPanel的getPreferredSize()方法:
return new ChartPanel(new JFreeChart(plot)) {
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
};
#2
1
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.
在此解决方案中,我维护两个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));
}
}