JFreeChart展示柱状图和折线图的组合

本文介绍了如何使用JFreeChart在SSH架构的Web前端展示统计图表,强调了JFreeChart在Server端保存图片并简化前端代码的优点,同时也对比了其与Amchart在动态展示上的不足。提供了JFreeChart的前端、中后端关键代码示例,展示如何组织数据、创建图表以及设置样式。
        笔者最近工作需要在Web前端展示统计图表(基于SSH架构),使用了JFreeChart和amchart两个控件,谈谈使用心得。
        JFreeChart的最大好处是可以在Server端保存jpg图片,并且前端代码简单,各浏览器兼容性好,但是相对来说动态展示效果较差。Amchart则可以更好的展示动态性,但是缺点也很明显,前端代码复杂,不能保存server端图片。另外,chrome和ff中对其支持较好,所需显示时间很短(2s左右),但是在ie8中需要30s以上时间(9张图表)。
       JFreeChart前端代码简洁明了,中端API详尽,代码如下:
    //1.jquery调用ajax请求
    $(document).ready(function() {
        $.ajax({
            type: "POST",
            url: "需要调用的url链接",
            beforeSend :function() {//调用成功前前端显示内容
                $("#testImgError").text("正在获取...");//可使用动态gif图片展示等待过程
            },
            success: function(data) {//调用成功后前端处理
                $("#testImgError").text("");                    
                $("#testImg").attr("src", "../test/"+data);
            },
            error: function() {//前端调用错误处理
                $("#testImgError").text("调用失败");
                $("#testImg").hide();
            }
        });            
    });
    
    //2.前端form中的显示,只需两行代码,可嵌入到相应的table或者div中:
    <label id="testImgError"></label>
    <img id="testImg" width=500 height=270 border=0>

    //3.中后端的代码也不复杂,需要处理一下数据获取和图片的保存和发送过程,代码如下:
    //3.1.数据获取
    public void createTestImg() throws IOException {
        //获取参数, id不能为空
        Integer id = Integer.parseInt(this.getRequest().getParameter("id"));
        //根据id获取数据        
        List distributed = testService.getData(id);

        ChartConstruction mtd = new ChartConstruction("");
        JFreeChart demo = mtd.getTestChart(distributed);
        //保存为图片,创建所需保存图片的文件夹
        String prefix = "InvestTypeDistributed-";
        String path1 = "D://Chart//paperIrrByYear";
        File newPath = new File(path1);
        if (!newPath.exists())
            newPath.mkdir();
        File tempFile1 = File.createTempFile(prefix, ".jpeg", newPath);
        ChartUtilities.saveChartAsJPEG(tempFile1, demo, 500, 270);//实际JFreeChart保存图片方法

        //向前台传递Json
        sendJSON(distributed);
    }
    //3.2.向前台发送Json,方法多种多样,大家可以根据需要自行编写
    private void sendJSON(List distributed){
        Map<String, Object> map = new HashMap<String, Object>();
        if ((distributed == null) || (distributed.size() == 0))
            map.put("rows", new ArrayList<Object>());
        else
            map.put("rows", distributed);
        senderJson(this.getResponse(), map);
    }
    //3.3组织数据,两个dataset,形成柱状图和折线图的组合
    public JFreeChart getTestChart(List distributed, Integer companyId, String begin, String end){
        //List distributed = peCompanyInvestAnalysisService.getCompanyMoneyTypeDistributed(companyId, begin, end);
    	DefaultCategoryDataset datasetSum = new DefaultCategoryDataset();
        DefaultCategoryDataset datasetNum = new DefaultCategoryDataset();
        Double maxSum = 0.0d;
        Double minSum = 0.0d;
        Double tempSum = 0.0d;
        Integer maxNum = 0;
        Integer minNum = 0;
        Integer tempNum = 0;
        if(distributed!=null)
            for(int i=0;i<distributed.size();i++){
                Map mm=(Map)distributed.get(i);
                if(mm.get("amount")==null)
                    tempSum = 0.0d;
                else
                    tempSum = Double.parseDouble(mm.get("amount").toString());
                if(mm.get("num")==null)
                    tempNum = 0;
                else
                    tempNum = Integer.parseInt(mm.get("num").toString());
                if(tempNum==null)
                    tempNum = 0;
                
                datasetSum.addValue(tempSum, "投资币种", mm.get("moneyType").toString());
                datasetNum.addValue(tempNum,"投资项目数",mm.get("moneyType").toString());
            }

        JFreeChart chart = creatChart("投资币种分布图",datasetSum,datasetNum);

        return chart;
    }
    //3.4调用JFreeChart的api,创建图片样式
    private JFreeChart creatChart(String title, DefaultCategoryDataset datasetSum, DefaultCategoryDataset datasetNum){
        //创建主题样式
        StandardChartTheme standardChartTheme=new StandardChartTheme("CN");
        standardChartTheme.setExtraLargeFont(new Font("黑体",Font.BOLD,15)); //设置标题字体
        standardChartTheme.setRegularFont(new Font("宋书",Font.PLAIN,12));//设置图例的字体
        standardChartTheme.setLargeFont(new Font("宋书",Font.PLAIN,12));//设置轴向的字体
        ChartFactory.setChartTheme(standardChartTheme);//应用主题样式

		    JFreeChart chart = ChartFactory.createBarChart(
                title, // chart title
                "", // x轴标题,domain axis label
                "", // y轴标题,range axis label
                datasetSum, // data
                PlotOrientation.VERTICAL, // orientation
                false, // include legend
                true, // tooltips?
                false // URLs?
        );
        chart.setBackgroundPaint(Color.white);

        CategoryPlot plot = (CategoryPlot) chart.getPlot();
        CategoryDataset categorydataset = datasetNum;       //设置第二个数据集
        plot.setDataset(1, categorydataset);
        plot.mapDatasetToRangeAxis(1, 1);
        plot.setBackgroundPaint(Color.white);
        plot.setRangeGridlinePaint(Color.white);
        plot.setOutlinePaint(Color.white);  //设置图片边框颜色,去掉边框

        //柱体的样式设计
        BarRenderer renderer = (BarRenderer) plot.getRenderer();
        renderer.setSeriesPaint(0, Color.orange);
        renderer.setDrawBarOutline(false);
        //设置柱顶数据,API中居然没有StandardCategoryItemLabelGenerator这个类
        renderer.setItemLabelGenerator(new StandardCategoryItemLabelGenerator());
        renderer.setSeriesItemLabelsVisible(0, true);
        //防止由于柱体太少而动态增加柱体宽度(JFreeChart默认是根据柱体多少而显示柱体宽度的)
        int k = datasetSum.getColumnCount();
        if (k == 1) {
            plot.getDomainAxis().setLowerMargin(0.26);
            plot.getDomainAxis().setUpperMargin(0.66);
        } else if (k < 6) {
            double margin = (1.0 - k * 0.08) / 3;
            plot.getDomainAxis().setLowerMargin(margin);
            plot.getDomainAxis().setUpperMargin(margin);
            ((BarRenderer) plot.getRenderer()).setItemMargin(margin);
        } else {
            ((BarRenderer) plot.getRenderer()).setItemMargin(0.1);
        }

        /*------设置Y轴----*/
        double unit=1d;//刻度的长度
        //右边Y轴,相关属性设置
        NumberAxis numberaxis1 = new NumberAxis("");
        unit=Math.floor(10);//刻度的长度
        NumberTickUnit ntu= new NumberTickUnit(unit);
        numberaxis1.setTickUnit(ntu);
        numberaxis1.setRange(0,100);//刻度范围
        plot.setRangeAxis(1, numberaxis1);
        //左边Y轴
        NumberAxis numberaxis = (NumberAxis) plot.getRangeAxis();
        numberaxis .setAutoTickUnitSelection(false);        
        numberaxis.setRange(0.0, 100.0);//刻度的范围
        ntu= new NumberTickUnit(unit);
        numberaxis .setTickUnit(ntu);
        /*------设置柱状体与图片边框的上下间距---*/
        numberaxis.setUpperMargin(0.05);
        numberaxis.setLowerMargin(0.05);

        /*------设置X轴----*/
        CategoryAxis domainAxis = plot.getDomainAxis();
        domainAxis.setCategoryLabelPositions(CategoryLabelPositions.STANDARD);
        /*------设置X轴标题的倾斜程度----*/
        domainAxis.setCategoryLabelPositions(CategoryLabelPositions.createUpRotationLabelPositions(Math.PI / 6.0));
        /*------设置柱状体与图片边框的左右间距--*/
        //domainAxis.setLowerMargin(0.01);
        //domainAxis.setUpperMargin(0.01);

        //设置折线图的样式
        LineAndShapeRenderer lineandshaperenderer = new LineAndShapeRenderer();
        lineandshaperenderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
        lineandshaperenderer.setBaseItemLabelsVisible(true);
        lineandshaperenderer.setBaseItemLabelFont(new Font("隶书", Font.BOLD, 10));

        plot.setRenderer(1, lineandshaperenderer);
        plot.setDatasetRenderingOrder(DatasetRenderingOrder.FORWARD);
        //图例1声明及相关样式设置
        LegendTitle legendtitle = new LegendTitle(plot.getRenderer(0));
        //图例2声明及相关样式设置
        LegendTitle legendtitle1 = new LegendTitle(plot.getRenderer(1));
        BlockContainer blockcontainer = new BlockContainer(new BorderArrangement());
        blockcontainer.add(legendtitle, RectangleEdge.LEFT);
        blockcontainer.add(legendtitle1, RectangleEdge.RIGHT);
        blockcontainer.add(new EmptyBlock(20D, 0.0D));
        CompositeTitle compositetitle = new CompositeTitle(blockcontainer);
        compositetitle.setPosition(RectangleEdge.BOTTOM);
        chart.addSubtitle(compositetitle);

        chart.setAntiAlias(false);
        chart.getRenderingHints().put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);

        return chart;
	}




                
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值