Java JFreeChart类别图像
是否有任何方法可以在类别字符串旁边添加图像,如这些附件所示 当前: 期望的: 编辑: 根据kiwiwings的回答,我在他的演示中轻松地在XYchart的标签字符串旁边显示了我的图像:Java JFreeChart类别图像,java,jfreechart,Java,Jfreechart,是否有任何方法可以在类别字符串旁边添加图像,如这些附件所示 当前: 期望的: 编辑: 根据kiwiwings的回答,我在他的演示中轻松地在XYchart的标签字符串旁边显示了我的图像: protected AxisState drawTickMarksAndLabels(Graphics2D g2, double cursor, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge) {
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);
}
是的,有
形状位置的计算有点过于复杂,但我希望它能解决您的问题。如果你想拥有图例的形状,你需要使用
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.*;
导入java.awt.geom.*;
导入java.util.*;
导入java.util.List;
导入org.jfree.chart.*;
导入org.jfree.chart.axis.*;
导入org.jfree.chart.plot.*;
导入org.jfree.chart.renderer.xy.XYItemRenderer;
导入org.jfree.data.time.*;
导入org.jfree.ui.*;
公共类CategoryLabelWithShape扩展了ApplicationFrame{
公共类别带形状的标签(最终字符串标题){
超级(标题);
最终JFreeChart chart=constructChart();
最终图表面板=新图表面板(图表);
设置内容窗格(面板);
}
JFreeChart构造图(){
JFreeChart chart=ChartFactory.createXYBarChart(
“状态执行”、“年份”、“真”、“人数”、getDataSet()、PlotOrientation.VERTICAL、true、true、false
);
XYPlot XYPlot=(XYPlot)chart.getPlot();
final XYItemRenderer xyRend=xyPlot.getRenderer();
DateAxis daNew=新的DateAxis(){
/**
*绘制轴线、记号和记号标签。
*
*@param g2用于图形设备。
*@param cursor指向光标。
*@param plotArea打印区域。
*@param dataArea数据区域。
*@param edge轴与之对齐的边。
*
*@返回用于绘制轴的宽度或高度。
*/
受保护的AxisState图纸标记和标签(图形2D g2,
双光标、矩形2D绘图区、矩形2D数据区、,
矩形边缘){
if(belsvisible()){
Shape s=xyRend.getBaseShape();
绘制oldPaint=g2.getPaint();
g2.setPaint(xyRend.getSeriesPaint(0));
矩形2D rect=s.getBounds2D();
仿射变换oldTrans=g2.getTransform();
AxisState=新AxisState(光标);
@抑制警告(“未选中”)
列表标记=(列表)刷新标记(g2、状态、数据区、边缘);
对于(ValueTick勾号:勾号){
float[]锚点=计算锚点(勾号、光标、数据区、边缘);
g2.setTransform(oldTrans);
//TODO:将“anchorPoint[0]-X”替换为基于边界的值
g2.translate(主播点[0]-17,主播点[1]+rect.getHeight());
g2.填充;
}
g2.setPaint(旧漆);
g2.setTransform(oldTrans);
}
返回super.drawTickMarksAndLabels(g2、光标、绘图区、数据区、边缘);
}
};
setLabel(xyPlot.getDomainAxis().getLabel());
xyPlot.setDomainAxis(daNew);
收益表;
}
私有时间体验集合getDataSet(){
TimeSeriesCollection ds=新TimeSeriesCollection();
最终时间序列s1=新时间序列(“执行”);
ds.addSeries(s1);
Calendar cal=Calendar.getInstance();
cal.clear();
校准集(日历年,1970年);
Random rand=新的Random();
对于(int i=0;我只需要使用随机图像,而不是图例。我会查看您的代码。谢谢!我猜它可能是某种政治党派标志……今晚我会看一看。请指定图像和年份的对应方式,如果有关系,什么时候会因为图表宽度限制而跳过一年许可党标志?这是这只是我从JFreeChart网站上得到的一个演示屏幕截图,我的图表只是一个X轴上有国家字符串的条形图,我想在旁边添加国家国旗,所以每个值下都有不同的图像。就像在政治上一样…共和党/民主党我更新了我的版本…也许把国旗放在类别下面会更好很多!我由于类别数量和字符数量可变,我在尝试显示图像和字符串时遇到了一些麻烦。为简单起见,我放弃了字符串,只在类别空间的中心显示标志。
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);
}
}