【问题标题】:How to determine min and max value for ItemMargin property in StackedBarChart using jFreeChart如何使用 jFreeChart 确定 StackedBarChart 中 ItemMargin 属性的最小值和最大值
【发布时间】:2013-06-27 11:11:46
【问题描述】:

我正在使用 jFreeChart api 制作一个应用程序,以便在移动滑块时,两个条之间的间隙宽度会根据滑块的值增加或减少。但我发现不同的图表和不同的数据项边距属性会有所不同。 为了演示这个问题,我附上了以下代码:-

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(1.5, "5YEUR", "5Y");
            result.addValue(-1.5, "5YUSD", "5Y");

            result.addValue(0.5, "5Yx5YEUR", "5Yx5Y");
            result.addValue(-0.5, "5Yx5YUSD", "5Yx5Y");

            result.addValue(1.5, "10Yx5YEUR", "10Yx5Y");
            result.addValue(-1.5, "10Yx5YUSD", "10Yx5Y");

            result.addValue(1.5, "15Yx5YEUR", "15Yx5Y");
            result.addValue(-1.5, "15Yx5YUSD", "15Yx5Y");

            result.addValue(1.5, "20Yx5YEUR", "20Yx5Y");
            result.addValue(-1.5, "20Yx5YUSD", "20Yx5Y");

            result.addValue(1.5, "20Yx5YEUR", "25Yx5Y");
            result.addValue(-1.5, "20Yx5YUSD", "25Yx5Y");

            //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("5YEUR", "G1");
            map.mapKeyToGroup("5YUSD", "G1");

            map.mapKeyToGroup("5Yx5YEUR", "G2");
            map.mapKeyToGroup("5Yx5YUSD", "G2");

            map.mapKeyToGroup("10Yx5YEUR", "G3");
            map.mapKeyToGroup("10Yx5YUSD", "G3");

            map.mapKeyToGroup("15Yx5YEUR", "G4");
            map.mapKeyToGroup("15Yx5YUSD", "G4");

            map.mapKeyToGroup("20Yx5YEUR", "G5");
            map.mapKeyToGroup("20Yx5YUSD", "G5");

            map.mapKeyToGroup("25Yx5YEUR", "G6");
            map.mapKeyToGroup("25Yx5YUSD", "G6");


            renderer.setSeriesToGroupMap(map);
            double maxBarWidth = renderer.getMaximumBarWidth();

            //renderer.setMaximumBarWidth(1);
            renderer.setItemMargin(-20);

           /* 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.0);

        }

    }

    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。同样,在 100% 之前,我的条形图消失了。 我需要一个应用程序,其中

滑块的最小值 = 所有的条都需要相互接触

关于滑块的最大值 = 它将显示条之间的最大距离。

这将完全取决于项目边距属性的最小值和最大值。 我搜索了几个与此相关的文档,没有找到任何令人信服的计算。

这方面的任何建议都会非常有帮助。

谢谢

【问题讨论】:

标签: java swing jfreechart


【解决方案1】:

我认为您只需要使用更多的负范围,例如-50, 10.

SSCCE:

import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.BorderFactory;
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.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;

/** @see http://stackoverflow.com/a/17342522/230513 */
public class DomainTranslateDemo extends ApplicationFrame {

    private static class DemoPanel extends JPanel implements ChangeListener {

        private static int SLIDER_INITIAL_VALUE = -42;
        private static final double INCREMENT = 1 / 10.0;
        private JSlider slider;
        private GroupedStackedBarRenderer renderer;

        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(-50, 10, SLIDER_INITIAL_VALUE);
            this.slider.addChangeListener(this);
            dashboard.add(this.slider);
            add(dashboard, BorderLayout.SOUTH);
        }

        private CategoryDataset createDataset() {
            DefaultCategoryDataset result = new DefaultCategoryDataset();
            result.addValue(1.5, "5YEUR", "5Y");
            result.addValue(-1.5, "5YUSD", "5Y");
            result.addValue(0.5, "5Yx5YEUR", "5Yx5Y");
            result.addValue(-0.5, "5Yx5YUSD", "5Yx5Y");
            result.addValue(1.5, "10Yx5YEUR", "10Yx5Y");
            result.addValue(-1.5, "10Yx5YUSD", "10Yx5Y");
            result.addValue(1.5, "15Yx5YEUR", "15Yx5Y");
            result.addValue(-1.5, "15Yx5YUSD", "15Yx5Y");
            result.addValue(1.5, "20Yx5YEUR", "20Yx5Y");
            result.addValue(-1.5, "20Yx5YUSD", "20Yx5Y");
            result.addValue(1.5, "20Yx5YEUR", "25Yx5Y");
            result.addValue(-1.5, "20Yx5YUSD", "25Yx5Y");
            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("5YEUR", "G1");
            map.mapKeyToGroup("5YUSD", "G1");
            map.mapKeyToGroup("5Yx5YEUR", "G2");
            map.mapKeyToGroup("5Yx5YUSD", "G2");
            map.mapKeyToGroup("10Yx5YEUR", "G3");
            map.mapKeyToGroup("10Yx5YUSD", "G3");
            map.mapKeyToGroup("15Yx5YEUR", "G4");
            map.mapKeyToGroup("15Yx5YUSD", "G4");
            map.mapKeyToGroup("20Yx5YEUR", "G5");
            map.mapKeyToGroup("20Yx5YUSD", "G5");
            map.mapKeyToGroup("25Yx5YEUR", "G6");
            map.mapKeyToGroup("25Yx5YUSD", "G6");
            renderer.setSeriesToGroupMap(map);
            double maxBarWidth = renderer.getMaximumBarWidth();
            renderer.setItemMargin(SLIDER_INITIAL_VALUE * INCREMENT);

            CategoryPlot plot = (CategoryPlot) chart.getPlot();
            plot.setRenderer(renderer);
            plot.setFixedLegendItems(createLegendItems());
            return chart;
        }

        private LegendItemCollection createLegendItems() {
            LegendItemCollection result = new LegendItemCollection();
            return result;
        }

        @Override
        public void stateChanged(ChangeEvent event) {
            int value = slider.getValue();
            System.out.println("value:" + value);
            renderer.setItemMargin(value * INCREMENT);
        }
    }

    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);
    }
}

【讨论】:

  • 旨在使42 看起来很重要的值。
  • 看起来不错。经过一些调整,我希望它能解决我的问题。但是,如果要知道确切的最小和最大项目边距,请使滑块的最小值和最大值不同。那也不错。非常感谢。
  • 对不起,我的结果纯粹是经验性的;您可能想尝试chartPanel.setMouseWheelEnabled(true)。效果是分配“未使用”的空间,因此大部分时间它(至少)一个像素。
猜你喜欢
  • 2016-10-13
  • 1970-01-01
  • 1970-01-01
  • 2010-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-13
  • 1970-01-01
相关资源
最近更新 更多