我正在使用jFreeChart在X轴上绘制堆积条形图。但是我有这个要求来控制X轴上两个堆栈条之间的空间,类似于Micorsoft excel的间隙宽度。 我刚刚附上了一个示例代码来演示这个问题。在滑动条形图上调整间隙宽度。以下是示例代码。
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.LegendItemCollection;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.SubCategoryAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.GroupedStackedBarRenderer;
import org.jfree.data.KeyToGroupMap;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;
public class DomainTranslateDemo extends ApplicationFrame {
private static class DemoPanel extends JPanel implements ChangeListener {
private static int SLIDER_INITIAL_VALUE = 50;
private JSlider slider;
private DateAxis domainAxis;
private int lastValue = SLIDER_INITIAL_VALUE;
private GroupedStackedBarRenderer renderer;
// one month (milliseconds, seconds, minutes, hours, days)
private int delta = 1000 * 60 * 60 * 24 * 30;
public DemoPanel() {
super(new BorderLayout());
final CategoryDataset dataset = createDataset();
final JFreeChart chart = createChart(dataset);
final ChartPanel chartPanel = new ChartPanel(chart);
Dimension Dim = new Dimension(590, 350);
chartPanel.setPreferredSize(Dim);
add(chartPanel);
JPanel dashboard = new JPanel(new BorderLayout());
dashboard.setBorder(BorderFactory.createEmptyBorder(0, 4, 4, 4));
this.slider = new JSlider(0, 100, SLIDER_INITIAL_VALUE);
this.slider.addChangeListener(this);
dashboard.add(this.slider);
add(dashboard, BorderLayout.SOUTH);
}
private CategoryDataset createDataset() {
DefaultCategoryDataset result = new DefaultCategoryDataset();
result.addValue(20.3, "Product 1 (US)", "Jan 04");
result.addValue(23.3, "Product 2 (US)", "Jan 04");
result.addValue(12.7, "Product 2 (Europe)", "Jan 04");
result.addValue(11.9, "Product 3 (US)", "Jan 04");
return result;
}
private JFreeChart createChart(final CategoryDataset dataset) {
final JFreeChart chart = ChartFactory.createStackedBarChart(
"Max Bar Width", // chart title
"Category", // domain axis label
"Value", // range axis label
dataset, // data
PlotOrientation.VERTICAL, // the plot orientation
true, // legend
true, // tooltips
false // urls
);
renderer = new GroupedStackedBarRenderer();
KeyToGroupMap map = new KeyToGroupMap("G1");
map.mapKeyToGroup("Product 1 (US)", "G1");
map.mapKeyToGroup("Product 2 (US)", "G2");
map.mapKeyToGroup("Product 2 (Europe)", "G2");
map.mapKeyToGroup("Product 3 (US)", "G3");
renderer.setSeriesToGroupMap(map);
double maxBarWidth = renderer.getMaximumBarWidth();
//renderer.setMaximumBarWidth(1);
//renderer.setItemMargin(0.85);
SubCategoryAxis domainAxis = new SubCategoryAxis("Product / Month");
domainAxis.setCategoryMargin(0.05);
domainAxis.addSubCategory("Product 1");
domainAxis.addSubCategory("Product 2");
domainAxis.addSubCategory("Product 3");
CategoryPlot plot = (CategoryPlot) chart.getPlot();
plot.setDomainAxis(domainAxis);
plot.setRenderer(renderer);
plot.setFixedLegendItems(createLegendItems());
return chart;
}
/**
* @return The legend items.
*/
private LegendItemCollection createLegendItems() {
LegendItemCollection result = new LegendItemCollection();
return result;
}
@Override
public void stateChanged(ChangeEvent event) {
int value = this.slider.getValue();
/* long minimum = domainAxis.getMinimumDate().getTime();
long maximum = domainAxis.getMaximumDate().getTime();
if (value<lastValue) { // left
minimum = minimum - delta;
maximum = maximum - delta;
} else { // right
minimum = minimum + delta;
maximum = maximum + delta;
}
DateRange range = new DateRange(minimum,maximum);
domainAxis.setRange(range);*/
System.out.println("value:"+value);
renderer.setItemMargin(value/100);
}
}
public DomainTranslateDemo(String title) {
super(title);
setContentPane(new DemoPanel());
}
public static JPanel createDemoPanel() {
return new DemoPanel();
}
public static void main(String[] args) {
DomainTranslateDemo demo = new DomainTranslateDemo("Translate Demo");
demo.pack();
RefineryUtilities.centerFrameOnScreen(demo);
demo.setVisible(true);
}
}
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.LegendItemCollection;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.SubCategoryAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.GroupedStackedBarRenderer;
import org.jfree.data.KeyToGroupMap;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;
public class DomainTranslateDemo extends ApplicationFrame {
private static class DemoPanel extends JPanel implements ChangeListener {
private static int SLIDER_INITIAL_VALUE = 50;
private JSlider slider;
private DateAxis domainAxis;
private int lastValue = SLIDER_INITIAL_VALUE;
private GroupedStackedBarRenderer renderer;
// one month (milliseconds, seconds, minutes, hours, days)
private int delta = 1000 * 60 * 60 * 24 * 30;
public DemoPanel() {
super(new BorderLayout());
final CategoryDataset dataset = createDataset();
final JFreeChart chart = createChart(dataset);
final ChartPanel chartPanel = new ChartPanel(chart);
Dimension Dim = new Dimension(590, 350);
chartPanel.setPreferredSize(Dim);
add(chartPanel);
JPanel dashboard = new JPanel(new BorderLayout());
dashboard.setBorder(BorderFactory.createEmptyBorder(0, 4, 4, 4));
this.slider = new JSlider(0, 100, SLIDER_INITIAL_VALUE);
this.slider.addChangeListener(this);
dashboard.add(this.slider);
add(dashboard, BorderLayout.SOUTH);
}
private CategoryDataset createDataset() {
DefaultCategoryDataset result = new DefaultCategoryDataset();
result.addValue(20.3, "Product 1 (US)", "Jan 04");
result.addValue(23.3, "Product 2 (US)", "Jan 04");
result.addValue(12.7, "Product 2 (Europe)", "Jan 04");
result.addValue(11.9, "Product 3 (US)", "Jan 04");
return result;
}
private JFreeChart createChart(final CategoryDataset dataset) {
final JFreeChart chart = ChartFactory.createStackedBarChart(
"Max Bar Width", // chart title
"Category", // domain axis label
"Value", // range axis label
dataset, // data
PlotOrientation.VERTICAL, // the plot orientation
true, // legend
true, // tooltips
false // urls
);
renderer = new GroupedStackedBarRenderer();
KeyToGroupMap map = new KeyToGroupMap("G1");
map.mapKeyToGroup("Product 1 (US)", "G1");
map.mapKeyToGroup("Product 2 (US)", "G2");
map.mapKeyToGroup("Product 2 (Europe)", "G2");
map.mapKeyToGroup("Product 3 (US)", "G3");
renderer.setSeriesToGroupMap(map);
double maxBarWidth = renderer.getMaximumBarWidth();
//renderer.setMaximumBarWidth(1);
//renderer.setItemMargin(0.85);
SubCategoryAxis domainAxis = new SubCategoryAxis("Product / Month");
domainAxis.setCategoryMargin(0.05);
domainAxis.addSubCategory("Product 1");
domainAxis.addSubCategory("Product 2");
domainAxis.addSubCategory("Product 3");
CategoryPlot plot = (CategoryPlot) chart.getPlot();
plot.setDomainAxis(domainAxis);
plot.setRenderer(renderer);
plot.setFixedLegendItems(createLegendItems());
return chart;
}
/**
* @return The legend items.
*/
private LegendItemCollection createLegendItems() {
LegendItemCollection result = new LegendItemCollection();
return result;
}
@Override
public void stateChanged(ChangeEvent event) {
int value = this.slider.getValue();
/* long minimum = domainAxis.getMinimumDate().getTime();
long maximum = domainAxis.getMaximumDate().getTime();
if (value<lastValue) { // left
minimum = minimum - delta;
maximum = maximum - delta;
} else { // right
minimum = minimum + delta;
maximum = maximum + delta;
}
DateRange range = new DateRange(minimum,maximum);
domainAxis.setRange(range);*/
System.out.println("value:"+value);
renderer.setItemMargin(value/100);
}
}
public DomainTranslateDemo(String title) {
super(title);
setContentPane(new DemoPanel());
}
public static JPanel createDemoPanel() {
return new DemoPanel();
}
public static void main(String[] args) {
DomainTranslateDemo demo = new DomainTranslateDemo("Translate Demo");
demo.pack();
RefineryUtilities.centerFrameOnScreen(demo);
demo.setVisible(true);
}
}
此外,我无法根据滑块更改更新图表面板。
任何建议都会非常有用。
由于
答案 0 :(得分:1)
我没有看到MS Excel如何执行其间距但你在这里遇到了整数除法的问题:
renderer.setItemMargin(value / 100);
确保至少有一个操作数是浮点值。替换为
renderer.setItemMargin(value / 100.0);
否则堆叠条之间的间距将始终为0