jfreechart 饼状图和柱状图 自定义填充图片

最近项目生成报表中,用户要求生成的饼图和柱图都不用颜色区分,用纹理填充来区分。饼图要求随机一块 隔离 出来,特别显示,柱图要求用柱图和折线图联合比较。


后台生成图表选择的工具是jfreechart,个人感觉功能相当齐全,网上相关资料也很多。但填充图片网上是真的找不到类似案例。没办法,研究了一下jfreechart  API ,终于还是给发现了解决方法。


正文  柱图填充

先了解一下主要类及作用。JFreeChart类是通过ChartFactory(理解为生成chart的工厂)创建的类,代表图表。抽象类plot代表图表本身,包括背景,柱图,坐标轴,标题等等属性。基本上各个图有对应的PLOT类,饼图(pieplot)柱图(CategoryPlot)等。Render类,图表的渲染工具,类似画笔,用什么线条画,什么图片填充,同样的每个类有对应的render。(饼图没有)。柱图的render是BarRenderer,她有一个属性,BarPainter,即设置画笔画的内容


重写BarPainter。

import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Stroke;
import java.awt.geom.RectangularShape;

import org.jfree.chart.renderer.category.BarPainter;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.ui.RectangleEdge;

public class CustomeBarPainter implements BarPainter{

	@Override
	public void paintBar(Graphics2D paramGraphics2D, BarRenderer paramBarRenderer, int paramInt1, int paramInt2,
			RectangularShape paramRectangularShape, RectangleEdge paramRectangleEdge) {
		// TODO Auto-generated method stub
		 Paint itemPaint = paramBarRenderer.getItemPaint(paramInt1, paramInt2);
		 paramGraphics2D.setPaint(itemPaint);
		 paramGraphics2D.fill(paramRectangularShape);
		 if (!(paramBarRenderer.isDrawBarOutline()))//柱状图加边框   从StandardBarPainter实现类copy
			 return;
		 Stroke stroke = paramBarRenderer.getItemOutlineStroke(paramInt1, paramInt2);
		 Paint paint = paramBarRenderer.getItemOutlinePaint(paramInt1, paramInt2);
		 if ((stroke != null) && (paint != null)) {
			 paramGraphics2D.setStroke(stroke);
			 paramGraphics2D.setPaint(paint);
			 paramGraphics2D.draw(paramRectangularShape);
		  }
	}

	@Override
	public void paintBarShadow(Graphics2D paramGraphics2D, BarRenderer paramBarRenderer, int paramInt1, int paramInt2,
			RectangularShape paramRectangularShape, RectangleEdge paramRectangleEdge, boolean paramBoolean) {
		// TODO Auto-generated method stub
		Paint itemPaint = paramBarRenderer.getItemPaint(paramInt1, paramInt2);
		paramGraphics2D.setPaint(itemPaint);
		paramGraphics2D.fill(paramRectangularShape);
	}

}
设置柱图的barrender对象

	if (dataset != null) {
        	plot.setDataset(1, dataset);//设置折线数据源
        	LineAndShapeRenderer lineandshaperenderer = new LineAndShapeRenderer(); //shape理解为数据点和线的渲染器
        	lineandshaperenderer.setSeriesPaint(0, new java.awt.Color(0, 0, 0));//设置线为黑色
        	plot.setRenderer(1, lineandshaperenderer);//渲染折线
        	plot.setDatasetRenderingOrder(DatasetRenderingOrder.FORWARD);//折线在柱状图前面显示
	}


	BarRenderer renderer = (BarRenderer) plot.getRenderer();
	renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());//柱子上顯示相關信息
        renderer.setMaximumBarWidth(0.075);// 设置柱子最大宽度
        renderer.setBaseOutlinePaint(Color.BLACK);//设置柱子边框
        renderer.setDrawBarOutline(true);
        renderer.setBarPainter(new CustomeBarPainter());//自定义barPainter实现方法
        renderer.setItemMargin(0);//設置不同種類柱子之間的距離
       
        ValueAxis valueAxis = plot.getRangeAxis();
        Axis axis = plot.getDomainAxis();
        valueAxis.setLowerMargin(0);
        valueAxis.setAxisLinePaint(Color.BLACK);//纵轴设置为黑
        axis.setAxisLinePaint(Color.BLACK);//横轴设置为黑
        
        String[] imageArray = new String[]{"16.png","17.png","4.png","15.png","3.png"};//填充纹理图片库
        for (int i = 0,count = plot.getDataset().getRowCount(); i < count; i++) {
        	renderer.setSeriesPaint(i, getTexturePaint(imageArray[i%(imageArray.length)]));
		}//多柱子不同图片渲染
获取纹理填充图片


 /**
	 * 获取填充图片
	 * */
	private static TexturePaint getTexturePaint(String fileName){
        BufferedImage bi=null;
        Rectangle r = null;
        TexturePaint tp = null;
        try {
            InputStream in = ChartUtils.class.getClassLoader().getResourceAsStream("config/texture/"+fileName);
            bi = ImageIO.read(in);
        } catch (IOException e) {
            e.printStackTrace();
        }
        r = new Rectangle(0,0,bi.getWidth(),bi.getHeight());
        tp = new TexturePaint(bi,r);
        return tp;
    }

运行即可生成纹理填充的柱状图。


饼图的填充和柱图不一样,因为饼图没有对应的render方法。但是查看了pieplot的方法之后,发现setSectionPaint()方法。同样,把纹理图片获取成Paint对象即可。


 	String[] imageArray = new String[]{"16.png","17.png","4.png","15.png","3.png"};
        for (int i = 0,pieCount = piePlot.getDataset().getItemCount(); i < pieCount; i++) {
        	int j = i%imageArray.length;
        	piePlot.setSectionPaint(i,getTexturePaint(imageArray[j]));
	}

结果如下:






  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值