JFreeChart类别图像

时间:2013-04-30 08:39:19

标签: java jfreechart

有没有办法在类别字符串旁边添加图像,如这些附件中所示?

电流:

current

所需:

desired

编辑:

根据kiwiwings的回答,我很容易在他的演示中设法在XYchart的标签字符串旁边显示我的图像:

    protected AxisState drawTickMarksAndLabels(Graphics2D g2, double cursor, Rectangle2D plotArea, Rectangle2D dataArea,
            RectangleEdge edge) {

        if (isTickLabelsVisible()) {
            Shape s = xyRend.getBaseShape();
            Paint oldPaint = g2.getPaint();
            g2.setPaint(xyRend.getSeriesPaint(0));
            Rectangle2D rect = s.getBounds2D();
            AffineTransform oldTrans = g2.getTransform();

            AxisState state = new AxisState(cursor);
            @SuppressWarnings("unchecked")
            List<ValueTick> ticks = (List<ValueTick>) refreshTicks(g2, state, dataArea, edge);
            for (ValueTick tick : ticks) {
                float[] anchorPoint = calculateAnchorPoint(tick, cursor, dataArea, edge);
                g2.setTransform(oldTrans);
                // TODO: replace "anchorPoint[0]-X" with a bounds based value
                g2.translate(anchorPoint[0] - 28, anchorPoint[1] + 2);
                BufferedImage bfrImg = * load img here *;
                g2.drawImage(bfrImg, 0, 0, null);
            }

            g2.setPaint(oldPaint);
            g2.setTransform(oldTrans);
        }

        return super.drawTickMarksAndLabels(g2, cursor, plotArea, dataArea, edge);
    }

制作:

enter image description here

我现在正尝试对使用 CategoryPlot CategoryAxis 的JFreeChart执行相同操作,并使用以下方法创建:

ChartFactory.createBarChart("", "", "Items", mDataset, PlotOrientation.VERTICAL, true, true, false);

1 个答案:

答案 0 :(得分:3)

是的,有......

形状位置的计算有点衬衫,但我希望你的问题没问题。如果你想拥有你需要使用的图例的形状

Shape s = xyRend.getLegendItem(0, 0).getShape();

并调整y位置。

import java.awt.*;
import java.awt.geom.*;
import java.util.*;
import java.util.List;

import org.jfree.chart.*;
import org.jfree.chart.axis.*;
import org.jfree.chart.plot.*;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.data.time.*;
import org.jfree.ui.*;

public class CategoryLabelWithShape extends ApplicationFrame {

    public CategoryLabelWithShape(final String title) {
        super(title);
        final JFreeChart chart = constructChart();
        final ChartPanel panel = new ChartPanel(chart);
        setContentPane(panel);
    }

    JFreeChart constructChart() {
        JFreeChart chart = ChartFactory.createXYBarChart(
            "State Executions","Year",true,"Number of people",getDataSet(),PlotOrientation.VERTICAL,true,true,false
        );

        XYPlot xyPlot = (XYPlot)chart.getPlot();
        final XYItemRenderer xyRend = xyPlot.getRenderer();

        DateAxis daNew = new DateAxis(){
            /**
             * Draws the axis line, tick marks and tick mark labels.
             *
             * @param g2  the graphics device.
             * @param cursor  the cursor.
             * @param plotArea  the plot area.
             * @param dataArea  the data area.
             * @param edge  the edge that the axis is aligned with.
             *
             * @return The width or height used to draw the axis.
             */
            protected AxisState drawTickMarksAndLabels(Graphics2D g2,
                    double cursor, Rectangle2D plotArea, Rectangle2D dataArea,
                    RectangleEdge edge) {

                if (isTickLabelsVisible()) {
                    Shape s = xyRend.getBaseShape();
                    Paint oldPaint = g2.getPaint();
                    g2.setPaint(xyRend.getSeriesPaint(0));
                    Rectangle2D rect = s.getBounds2D();
                    AffineTransform oldTrans = g2.getTransform();

                    AxisState state = new AxisState(cursor);
                    @SuppressWarnings("unchecked")
                    List<ValueTick> ticks = (List<ValueTick>)refreshTicks(g2, state, dataArea, edge);
                    for (ValueTick tick : ticks) {
                        float[] anchorPoint = calculateAnchorPoint(tick, cursor, dataArea, edge);
                        g2.setTransform(oldTrans);
                        // TODO: replace "anchorPoint[0]-X" with a bounds based value
                        g2.translate(anchorPoint[0]-17, anchorPoint[1]+rect.getHeight());
                        g2.fill(s);
                    }


                    g2.setPaint(oldPaint);
                    g2.setTransform(oldTrans);
                }

                return super.drawTickMarksAndLabels(g2,cursor,plotArea,dataArea,edge);
            }
        };

        daNew.setLabel(xyPlot.getDomainAxis().getLabel());
        xyPlot.setDomainAxis(daNew);

        return chart;
    }

    private TimeSeriesCollection getDataSet() {
        TimeSeriesCollection ds = new TimeSeriesCollection();

        final TimeSeries s1 = new TimeSeries("Executions");
        ds.addSeries(s1);

        Calendar cal = Calendar.getInstance();
        cal.clear();
        cal.set(Calendar.YEAR, 1970);
        Random rand = new Random();
        for (int i=0; i<(2010-1970); i++) {
            s1.add(new Year(cal.getTime()), rand.nextInt(100));
            cal.add(Calendar.YEAR, 1);
        }

        return ds;
    }


    public static void main(String[] args) {
        CategoryLabelWithShape demo = new CategoryLabelWithShape(
                "Category-label with a shape");
        demo.pack();
        RefineryUtilities.centerFrameOnScreen(demo);
        demo.setVisible(true);
    }
}

更新:带有类别数据集的新版本... 它很少见;)

import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.net.URL;
import java.util.List;
import javax.imageio.ImageIO;
import org.jfree.chart.*;
import org.jfree.chart.axis.*;
import org.jfree.chart.plot.*;
import org.jfree.data.category.*;
import org.jfree.ui.*;

@SuppressWarnings("serial")
public class CategoryLabelWithShape extends ApplicationFrame {

    public CategoryLabelWithShape(final String title) {
        super(title);
        final JFreeChart chart = constructChart();
        final ChartPanel panel = new ChartPanel(chart);
        setContentPane(panel);
    }

    JFreeChart constructChart() {
        JFreeChart chart = ChartFactory.createBarChart(
            "MEP seats","country","# seats",getDataSet(),PlotOrientation.VERTICAL,true,true,false
        );

        CategoryPlot cp = chart.getCategoryPlot();

        CategoryAxis daNew = new CategoryAxis(){
            protected AxisState drawCategoryLabels(Graphics2D g2,
                    Rectangle2D plotArea,
                    Rectangle2D dataArea,
                    RectangleEdge edge,
                    AxisState state,
                    PlotRenderingInfo plotState) {

                if (isTickLabelsVisible()) {
                    List<CategoryTick> ticks = (List<CategoryTick>)refreshTicks(g2, state, plotArea, edge);

                    int categoryIndex = 0;
                    for (CategoryTick tick : ticks) {
                        double x0 = getCategoryStart(categoryIndex, ticks.size(), dataArea, edge);
                        double y0 = state.getCursor() + getCategoryLabelPositionOffset();


                        CountryFlag cf = (CountryFlag)((CategoryPlot)getPlot()).getDataset().getColumnKey(categoryIndex);
                        try {
                            BufferedImage img = ImageIO.read(new URL(cf.flagUrl));

                            g2.drawImage(img, (int)(x0-img.getWidth()), (int)(y0), img.getWidth(), img.getHeight(), Color.black, null);
                        } catch (IOException e) {
                            // skip flag
                        }

                        categoryIndex++;
                    }
                }               
                return super.drawCategoryLabels(g2, plotArea, dataArea, edge, state, plotState);
            }
        };

        daNew.setLabel(cp.getDomainAxis().getLabel());
        cp.setDomainAxis(daNew);

        return chart;
    }

    static class CountryFlag implements Comparable<CountryFlag> {
        String name, flagUrl;
        CountryFlag(String name, String flagUrl) {
            this.name = name;
            this.flagUrl = flagUrl;
        }
        public int compareTo(CountryFlag o) {
            return name.compareTo(o.name);
        }
        public String toString() {
            return name;
        }
    }

    private CategoryDataset getDataSet() {
        DefaultCategoryDataset ds = new DefaultCategoryDataset();
        ds.addValue(99, "MEP seats", new CountryFlag("Germany","http://upload.wikimedia.org/wikipedia/en/thumb/b/ba/Flag_of_Germany.svg/22px-Flag_of_Germany.svg.png"));
        ds.addValue(72, "MEP seats", new CountryFlag("France","http://upload.wikimedia.org/wikipedia/en/thumb/c/c3/Flag_of_France.svg/22px-Flag_of_France.svg.png"));
        ds.addValue(72, "MEP seats", new CountryFlag("Italy","http://upload.wikimedia.org/wikipedia/en/thumb/0/03/Flag_of_Italy.svg/22px-Flag_of_Italy.svg.png"));
        ds.addValue(72, "MEP seats", new CountryFlag("United Kingdom","http://upload.wikimedia.org/wikipedia/en/thumb/a/ae/Flag_of_the_United_Kingdom.svg/22px-Flag_of_the_United_Kingdom.svg.png"));
        ds.addValue(50, "MEP seats", new CountryFlag("Spain","http://upload.wikimedia.org/wikipedia/en/thumb/9/9a/Flag_of_Spain.svg/22px-Flag_of_Spain.svg.png"));
        ds.addValue(50, "MEP seats", new CountryFlag("Poland","http://upload.wikimedia.org/wikipedia/en/thumb/1/12/Flag_of_Poland.svg/22px-Flag_of_Poland.svg.png"));
        ds.addValue(33, "MEP seats", new CountryFlag("Romania","http://upload.wikimedia.org/wikipedia/commons/thumb/7/73/Flag_of_Romania.svg/22px-Flag_of_Romania.svg.png"));
        ds.addValue(25, "MEP seats", new CountryFlag("Netherlands","http://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Flag_of_the_Netherlands.svg/22px-Flag_of_the_Netherlands.svg.png"));
        ds.addValue(22, "MEP seats", new CountryFlag("Belgium","http://upload.wikimedia.org/wikipedia/commons/thumb/9/92/Flag_of_Belgium_%28civil%29.svg/22px-Flag_of_Belgium_%28civil%29.svg.png"));
        ds.addValue(22, "MEP seats", new CountryFlag("Czech Republic","http://upload.wikimedia.org/wikipedia/commons/thumb/c/cb/Flag_of_the_Czech_Republic.svg/22px-Flag_of_the_Czech_Republic.svg.png"));
        return ds;
    }


    public static void main(String[] args) {
        CategoryLabelWithShape demo = new CategoryLabelWithShape(
                "Category-label with a shape");
        demo.pack();
        RefineryUtilities.centerFrameOnScreen(demo);
        demo.setVisible(true);
    }
}