精华内容
下载资源
问答
  • 钻孔柱状图是了解地层结构、岩性特征、编写...系统可根据实际需要设置柱状图的字体、线宽,实现钻孔柱状图的分段自动绘制,提高了成图效率,克服了手工绘图方法成图慢、工作量大的缺点。并进行了实例应用,取得良好效果。
  • 我的实现方式是使用再堆叠一个柱状图的形式来显示标签,具体为 颜色为透明色,标签位于内部下方(insideBottom),然后是重写tooltip的formatter,最后就是在触发legend切换时,更换option.缺点是切换legend时需要写好...

    本文主要记录一下使用echart的柱状图堆叠时,需要在柱状图顶部显示总计数值的问题。参考一篇文章的实现,它的实现方式是替换最后一列的formater属性来达到实现总计的方式。我的实现方式是使用再堆叠一个柱状图的形式来显示标签,具体为 颜色为透明色,标签位于内部下方(insideBottom),然后是重写tooltip的formatter(使其不显示总计的数值),最后就是在触发legend切换时,更换option.缺点是切换legend触发事件时需要重新设置option并更改总计数值的逻辑。
    一.结果
    在这里插入图片描述

    二.代码实现

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>ECharts1</title>
        <!-- 引入 echarts.js -->
         <script src="https://cdn.bootcdn.net/ajax/libs/echarts/4.0.0/echarts.min.js"></script>
    	  <script src="https://cdn.bootcss.com/jquery/3.3.0/jquery.min.js"></script>
    	
    </head>
    <body>
        <!-- 为ECharts准备一个具备大小(宽高)的Dom -->
        <div id="main" style="width: 1600px;height:800px;"></div>
         <script type="text/javascript">    
    	 
    	  function formatNum(strNum) {
                if (strNum.length <= 3) {
                    return strNum;
                }
                if (!/^(\+|-)?(\d+)(\.\d+)?$/.test(strNum)) {
                    return strNum;
                }
                var a = RegExp.$1,
                    b = RegExp.$2,
                    c = RegExp.$3;
                var re = new RegExp();
                re.compile("(\\d)(\\d{3})(,|$)");
                while (re.test(b)) {
                    b = b.replace(re, "$1,$2$3");
                }
                return a + "" + b + "" + c;
            }
    
    	 
    		var heavyIn = [100,200,300,400,500];
    		var heavyOut = [600,400,200,100,460];
    		var emptyIn = [300,100,200,200,300];
    		var emptyOut = [420,230,280,320,480];
    		var sumIn =[];
    		var sumOut =[];
    		for(var i in heavyIn)
    			sumIn.push(heavyIn[i]+emptyIn[i]);
    		for(var i in heavyOut)
    			sumOut.push(heavyOut[i]+emptyOut[i]);
            var myChart7 = echarts.init(document.getElementById("main"));
                    var colorList = ['#5ad9a6', '#cef2e4', '#ceddfe', '#7babff']
                  
    
                    var left = '7.85%';
                    var right = '3%';
                  
    
    
                    option = {
                        tooltip: {
                            trigger: 'axis',
                            axisPointer: {            // 坐标轴指示器,坐标轴触发有效
                                type: 'shadow'        // 默认为直线,可选为:'line' | 'shadow'
                            },
                            formatter: function (params) {
                                var res = '<div><p>' + params[0].name + '</p ></div>';
                                for (var i = 0; i < params.length; i++) {
    
                                    if (i == 4 || i == 5)
                                        ;
                                    else {
                                        res += "<p><font color=" + params[i].color + ">● " + "</font>" + params[i].seriesName + ':' + params[i].data + '</p >';
                                    }
                                }
                                return res;
                            }
                        },
                        legend: {
                            data: ['进口重箱', '进口空箱', '出口重箱', '出口空箱'],
                            right: '2%',
                        },
                        grid: {
                            left: left,
                            right: right,
                            top: '15%',
                            bottom: '10%',
                        },
                        xAxis: [
                            {
                                type: 'category',
                                data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
                            }
                        ],
                        yAxis: [
                            {
                                type: 'value',
                                axisLine: {
                                    show: false
                                },
                                axisLabel: {
                                    color: '#666666'
                                },
                                axisTick: {
                                    show: false
                                }
                            }
                        ],
                        series: [
                            {
                                name: '进口重箱',
                                type: 'bar',
                                data: heavyIn,
                                stack: '进口',
                                color: colorList[3],
    
                                barGap: '80%'
                            },
                            {
                                name: '进口空箱',
                                type: 'bar',
                                stack: '进口',
                                data: emptyIn,
                                color: colorList[2],
    
                                barGap: '80%'
                            },
                            {
                                name: '出口重箱',
                                type: 'bar',
                                stack: '出口',
                                data: heavyOut,
                                color: colorList[0],
    
                                barGap: '80%'
                            },
                            {
                                name: '出口空箱',
                                type: 'bar',
                                stack: '出口',
                                data: emptyOut,
                                color: colorList[1],
    
                                barGap: '80%'
                            },
                            {
                                name: '进口总量',
                                type: 'bar',
                                stack: '进口',
                                data: sumIn,
                                color: 'transparent',
                                label: {
                                    position: 'insideBottom',
                                    show: true,
    
                                    color: '#666666',
                                    formatter: function (param) {
    
                                        return formatNum(param.value);
    
                                    }
                                },
    
    
                            },
                            {
                                name: '出口总量',
                                type: 'bar',
                                stack: '出口',
                                data: sumOut,
                                color: 'transparent',
                                label: {
                                    show: true,
                                    position: 'insideBottom',
                                    color: '#666666',
                                    formatter: function (param) {
    
                                        return formatNum(param.value);
    
                                    }
                                },
    
    
    
    
                            },
    
                        ]
                    };
    
    
                    myChart7.on("legendselectchanged", function (obj) {
                        var selected = obj.selected;
    
    
    
                        sumIn = [];
                        sumOut = [];
    
                        if (selected.进口重箱 == false && selected.进口空箱 == false) {
                            for (var i in emptyIn) {
                                sumIn.push(0);
                            }
                        }
    
                        if (selected.进口重箱 == true && selected.进口空箱 == false) {
                            for (var i in emptyIn) {
                                sumIn.push(heavyIn[i]);
                            }
                        }
    
                        if (selected.进口重箱 == false && selected.进口空箱 == true) {
                            for (var i in emptyIn) {
                                sumIn.push(emptyIn[i]);
                            }
                        }
    
                        if (selected.进口重箱 == true && selected.进口空箱 == true) {
                            for (var i in emptyIn) {
                                sumIn.push(emptyIn[i] + heavyIn[i]);
                            }
                        }
    
    
                        if (selected.出口重箱 == false && selected.出口空箱 == false) {
                            for (var i in emptyOut) {
                                sumOut.push(0);
                            }
                        }
    
                        if (selected.出口重箱 == true && selected.出口空箱 == false) {
                            for (var i in emptyOut) {
                                sumOut.push(heavyOut[i]);
                            }
                        }
    
                        if (selected.出口重箱 == false && selected.出口空箱 == true) {
                            for (var i in emptyOut) {
                                sumOut.push(emptyOut[i]);
                            }
                        }
    
                        if (selected.出口重箱 == true && selected.出口空箱 == true) {
                            for (var i in emptyOut) {
                                sumOut.push(emptyOut[i] + heavyOut[i]);
                            }
                        }
    
    
    
    
    
                        option = {
                            tooltip: {
                                trigger: 'axis',
                                axisPointer: {            // 坐标轴指示器,坐标轴触发有效
                                    type: 'shadow'        // 默认为直线,可选为:'line' | 'shadow'
                                },
                                formatter: function (params) {
                                    var res = '<div><p>' + params[0].name + '</p ></div>';
                                    for (var i = 0; i < params.length; i++) {
    
                                        if (i == 4 || i == 5)
                                            ;
                                        else {
                                            res += "<p><font color=" + params[i].color + ">● " + "</font>" + params[i].seriesName + ':' + params[i].data + '</p >';
                                        }
                                    }
                                    return res;
                                }
                            },
                            legend: {
                                data: ['进口重箱', '进口空箱', '出口重箱', '出口空箱'],
                                right: '2%',
                            },
                            grid: {
                                left: left,
                                right: right,
                                top: '15%',
                                bottom: '10%',
                            },
                            xAxis: [
                                {
                                    type: 'category',
                                    data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
                                }
                            ],
                            yAxis: [
                                {
                                    type: 'value',
                                    axisLine: {
                                        show: false
                                    },
                                    axisLabel: {
                                        color: '#666666'
                                    },
                                    axisTick: {
                                        show: false
                                    }
                                }
                            ],
                            series: [
                                {
                                    name: '进口重箱',
                                    type: 'bar',
                                    data: heavyIn,
                                    stack: '进口',
                                    color: colorList[3],
    
                                    barGap: '80%'
                                },
                                {
                                    name: '进口空箱',
                                    type: 'bar',
                                    stack: '进口',
                                    data: emptyIn,
                                    color: colorList[2],
    
                                    barGap: '80%'
                                },
                                {
                                    name: '出口重箱',
                                    type: 'bar',
                                    stack: '出口',
                                    data: heavyOut,
                                    color: colorList[0],
    
                                    barGap: '80%'
                                },
                                {
                                    name: '出口空箱',
                                    type: 'bar',
                                    stack: '出口',
                                    data: emptyOut,
                                    color: colorList[1],
    
                                    barGap: '80%'
                                },
                                {
                                    name: '进口总量',
                                    type: 'bar',
                                    stack: '进口',
                                    data: sumIn,
                                    color: 'transparent',
                                    label: {
                                        position: 'insideBottom',
                                        show: true,
    
                                        color: '#666666',
                                        formatter: function (param) {
    
                                            return formatNum(param.value);
    
                                        }
                                    },
    
    
                                },
                                {
                                    name: '出口总量',
                                    type: 'bar',
                                    stack: '出口',
                                    data: sumOut,
                                    color: 'transparent',
                                    label: {
                                        show: true,
                                        position: 'insideBottom',
                                        color: '#666666',
                                        formatter: function (param) {
    
                                            return formatNum(param.value);
    
                                        }
                                    },
    
    
    
    
                                },
    
                            ]
                        };
                        myChart7.setOption(option);
    
                    })
                    myChart7.setOption(option);
                    window.addEventListener("resize", function () {
                   
    
                        var left = '7.85%';
                        var right = '3%';
       
    				option = {
    
                         
                            tooltip: {
                                trigger: 'axis',
                                axisPointer: {            // 坐标轴指示器,坐标轴触发有效
                                    type: 'shadow'        // 默认为直线,可选为:'line' | 'shadow'
                                },
                                formatter: function (params) {
                                    var res = '<div><p>' + params[0].name + '</p ></div>';
                                    for (var i = 0; i < params.length; i++) {
    
                                        if (i == 4 || i == 5)
                                            ;
                                        else {
                                            res += "<p><font color=" + params[i].color + ">● " + "</font>" + params[i].seriesName + ':' + params[i].data + '</p >';
                                        }
                                    }
                                    return res;
                                }
                            },
                            legend: {
                                data: ['进口重箱', '进口空箱', '出口重箱', '出口空箱'],
                                right: '2%',
                            },
                            grid: {
                                left: left,
                                right: right,
                                top: '15%',
                                bottom: '10%',
                            },
                            xAxis: [
                                {
                                    type: 'category',
                                    data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
                                }
                            ],
                            yAxis: [
                                {
                                    type: 'value',
                                    axisLine: {
                                        show: false
                                    },
                                    axisLabel: {
                                        color: '#666666'
                                    },
                                    axisTick: {
                                        show: false
                                    }
                                }
                            ],
                            series: [
                                {
                                    name: '进口重箱',
                                    type: 'bar',
                                    data: heavyIn,
                                    stack: '进口',
                                    color: colorList[3],
    
                                    barGap: '80%'
                                },
                                {
                                    name: '进口空箱',
                                    type: 'bar',
                                    stack: '进口',
                                    data: emptyIn,
                                    color: colorList[2],
    
                                    barGap: '80%'
                                },
                                {
                                    name: '出口重箱',
                                    type: 'bar',
                                    stack: '出口',
                                    data: heavyOut,
                                    color: colorList[0],
    
                                    barGap: '80%'
                                },
                                {
                                    name: '出口空箱',
                                    type: 'bar',
                                    stack: '出口',
                                    data: emptyOut,
                                    color: colorList[1],
    
                                    barGap: '80%'
                                },
                                {
                                    name: '进口总量',
                                    type: 'bar',
                                    stack: '进口',
                                    data: sumIn,
                                    color: 'transparent',
                                    label: {
                                        posion: 'insideBottom',
                                        show: true,
    
                                        color: '#666666',
                                        formatter: function (param) {
    
                                            return formatNum(heavyIn[param.dataIndex] + emptyIn[param.dataIndex]);
    
                                        }
                                    },
    
    
                                },
                                {
                                    name: '出口总量',
                                    type: 'bar',
                                    stack: '出口',
                                    data: sumOut,
                                    color: 'transparent',
                                    label: {
                                        show: true,
                                        posion: 'insideBottom',
                                        color: '#666666',
                                        formatter: function (param) {
                                            return formatNum(heavyOut[param.dataIndex] + emptyOut[param.dataIndex]);
    
                                        }
                                    },
    
    
    
    
                                },
    
                            ]
                        };
    
                        myChart7.setOption(option);
                        myChart7.resize();
                    });
        </script>
    </body>
    </html>
    

    三.参考文章
    1.https://blog.csdn.net/qq_36612779/article/details/78810107

    展开全文
  • 自定义View_一个非常简洁的柱状图

    千次阅读 2017-01-14 16:30:56
    快过年了,提前祝大家新年快乐哦。马上就可以闲下来休息几天了,好幸福啊。...但是唯一的缺点就是它们有些功能我们产品用不上,就为了显示一个小柱状图就compile一个别人的项目,有点得不偿失啊。所以我就自己撸了一个

    快过年了,提前祝大家新年快乐哦。马上就可以闲下来休息几天了,好幸福啊。。。不多说了,最近项目中有个地方要用柱状图显示客户的消费情况,本着一名程序员的优秀品质,上gitbub上连续搜罗了有关画图的,不得不说,真心蛮多的,不仅仅功能多,而且很多都已经高度封装,很好用了。但是唯一的缺点就是它们有些功能我们产品用不上,就为了显示一个小柱状图就compile一个别人的项目,有点得不偿失啊。所以我就自己撸了一个,呵呵,撸的蛮简单的。。
    如图:
    这里写图片描述

    这里写图片描述

    这里写图片描述

    本着一个菜鸟的气质,也非常羡慕那些会自定义View的人,先不说封装的非常优秀,让人用起来非常顺手;看自定义代码时,各种自定义的属性让人忧郁,我就是这种人,每次下载别人看上去很好的代码,唉,自定义的属性真实太多了,本想顺着他们的思路学习下去,但是很多时候就是看这自定义的高度,宽度,长度,颜色,type值,字体大小值,padding值,margin值…….我就害怕得崩溃了。所以我就想,能不能有些简单的方法让自己能理清思路呢。作为一只有想法的菜鸟,我想就这个柱状图说说自己的看法。

    我想做一个怎么样的控件

    在android中写个自定义控件并不是为了好玩[我是这么理解的],大多数自定义控件的诞生,都是与我们的业务逻辑相关的,然后通过代码抽象,提取了一个符合多种场合的东西。所以,我们的控件,不管是找的,还是自己写的,到底能不能实现自己业务中的功能。说到这里,简单列举我自己项目中柱状图要的功能:
    1.显示每个季度/一年中 用户的消费情况
    2.科技点击每个季度/一年中任意一个月,可以看到备份比/数值
    3.可以自定义颜色

    由于不是电商,这个柱状图的很多功能是弱化的,所以我去下载guahub上千star的项目的确有些浪费啊。明确的需求,那就开始写吧。

    开始

    这就是说自己的想法了,我先特么不管onMeasure(),onSizeChanged(),我先画个草图再说,这对我onDraw觉得是有帮助的:
    这里写图片描述

    恩,那么我就先把width,height钉死吧,恩,我就定死你,我先把最重要的写完再写你。
    那好啊,我就先画坐标吧。是的,画坐标,画之前,先写死一下:
    这里写图片描述

    画坐标的代码我也就不说了,也就一个Paint.drawLine(),你传入一个起始坐标与结束坐标就行,应该来说是简单的了啊。

    坐标画完了,那么我就来画我们的柱状图了,这个我想应该也是简单的,就是一个Paint.drawRoundRect(),我想难的还是那个传入的坐标了,
    这里写图片描述

    这里我们假设所有的柱状图的宽度是一致的,为mItemWidth , 另外还有一个就是两个柱状图之间的距离值,我们也假设他们之间的距离也是一样的,那么也可以设置mItemBetWidth;可以看出结论如下:
    n * mItemWidth + (n+1) * mItemBetWidth = View的宽度 - View.paddingLeft - View.paddingRight ;这里的n就是我们设置的要显示的柱状图的个数,唉,先不管了,设置n=12吧。这个mItemWidth与mItemBetWdith怎么办,还能咋办,先让他们相等嘛,如果测试妹妹说不行,我们改还不行吗?
    那么我们得到的结论就是 mItemWidth = (View.宽度 - View.paddingLeft - View.paddingRight ) / (2 * n + 1) ;
    好了,宽度确定了,高度呢?? 先设置假的啊,用random,呵呵,恩。

    说到这里,相信大家也已经画个大致的样子了吧:

    这里写图片描述

    细节

    写到这里,自定义View已经完成了很多一部分,为了能让我们的View拿得出手,需要定义一些细节,哪些细节呢?举个例子啊:

    1.坐标系的Paint,怎么定义?颜色/字体大小/strokeWidth
    2.具状图的Paint, 怎么定义? 颜色[普通颜色/渐变颜色]/字体大小/strokeWidth/显示方式[百分比还是数值]
    3.坐标系X轴该显示什么?有没有Paint,显示文字,设置前缀/后缀? 颜色/大小/strokeWidth/位置摆放?

    别急,你一个一个来,就像这样:

    mTextPaint = new Paint();
            mTextPaint.setStyle(Paint.Style.FILL);
            mTextPaint.setAntiAlias(true);
            mTextPaint.setColor(mTextColor);
            mTextPaint.setTextSize(mTextSize);
            Paint.FontMetrics metrics = mTextPaint.getFontMetrics();
            mTextBottomHeight = metrics.ascent + metrics.descent;
    
            mChartPaint = new Paint();
            mChartPaint.setStyle(Paint.Style.FILL);
            mChartPaint.setAntiAlias(true);
            mChartPaint.setColor(mStartChartViewColor);
    
            mTextTopPaint = new Paint();
            mTextTopPaint.setStyle(Paint.Style.FILL);
            mTextTopPaint.setAntiAlias(true);
            mTextTopPaint.setTextSize(mTopTextSize);
            mTextTopPaint.setColor(mTopTextColor);
    
            mCoordinatePaint = new Paint();
            mCoordinatePaint.setColor(Color.RED);
            mCoordinatePaint.setAntiAlias(true);
            mCoordinatePaint.setStrokeWidth(4);

    先标上自己喜欢的颜色,然后再去细致的改吧。当然这是刚刚开始,view的onDraw方法我感觉就像是画家在画画,慢慢去调节。当然啊前提是我们得学习一个常用的技巧,想Paint.draw到底可以draw什么,这个我们得自己知道啊。

    微调了坐标系,柱状图,现在还剩下点击颜色发生变化了吧,好吧,那就是OnTouch事件了:
    这里写图片描述

    那主要是判断我们的MotionEvent是否落在了这个柱状图里面了,如果是那么就修改这个柱状图的Paint中的颜色了,就是这样:

    private boolean contains(float x, float y) {
            for (int i = 1; i <= mChartItemCount; i++) {
                int tempValue = mValues.get(i - 1);
    
                RectF rectF = new RectF();
                rectF.top = mTextLocationHeight + mChartPaddingTop - tempValue * mHeight * 1.0f / (mMaxValue - mMinValue);
                rectF.left = (i - 1) * mBetweenWidth + (i - 1) * mChartWidth;
                rectF.right = i * (mBetweenWidth + mChartWidth) + mChartWidth;
                rectF.bottom = mTextLocationHeight + mChartPaddingTop;
    
                if (rectF.contains(x, y)) {
                    mCurrentIndex = i - 1;
                    return true;
                }
            }
            return false;
        }

    该变画笔的颜色:

     mTextPaint.setColor(mCurrentIndex == i - 1 ? mChooseColor : mTopTextColor);
     canvas.drawText(result, rectF.left + mChartWidth / 2 - width / 2, rectF.top - 10, mTextTopPaint);

    好了,基本上就是这样了,还是蛮简单的啊,下面是我定义的属性,也是一点一点加上去的:

     <declare-styleable name="CustomChartView">
    
            <!--底部文字颜色 -->
            <attr name="text_color" format="color"/>
            <!--底部文字大小 -->
            <attr name="text_size" format="dimension"/>
            <!--底部文字后缀 当然你可以定义前缀-->
            <attr name="text_suffix" format="string"/>
    
            <!--chartView开始显示的颜色-->
            <attr name="chart_start_color" format="color"/>
            <!--chartView结束显示的颜色-->
            <attr name="chart_end_color" format="color"/>
            <!--chartView选中的颜色-->
            <attr name="chart_choose_color" format="color"/>
            <!--chartView的圆角大小-->
            <attr name="chart_view_circle_radius" format="integer"/>
    
            <!--顶部文字的颜色-->
            <attr name="text_top_color" format="color"/>
            <!--顶部文字大小-->
            <attr name="text_top_size" format="dimension"/>
            <!--顶部文字显示方式 百分比还是数值-->
            <attr name="text_top_type" format="enum">
                <enum name="percent" value="1"/>
                <enum name="value" value="2"/>
            </attr>
    
            <!--显示chartView的个数-->
            <attr name="chart_item_count" format="integer"/>
            <!--最大值-->
            <attr name="chart_max_value" format="integer"/>
            <!--最小值-->
            <attr name="chart_min_value" format="integer"/>
    
            <!--chartView显示图与View顶部的距离-->
            <attr name="chart_padding_top" format="dimension"/>
            <!--chartView显示图与View底部的距离-->
            <attr name="chart_padding_bottom" format="dimension"/>
    
        </declare-styleable>

    基本上都有注释,我想也还算简单的,希望大家喜欢。
    代码

    好了,上海的下午,太阳落山了还是很冷的,我要去买菜做饭了。。。

    展开全文
  • JFreeChart展示柱状图和折线图的组合

    千次阅读 2012-09-27 11:02:59
    笔者最近工作需要在Web前端展示统计图表(基于SSH架构),使用了JFreeChart和amchart两个控件,谈谈使用...Amchart则可以更好展示动态性,但是缺点也很明显,前端代码复杂,不能保存server端图片。另外,chrome和f
            笔者最近工作需要在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;
    	}

    
    
    
    
    展开全文
  • 使用SVG最头痛一点就是其宽度和高度是从左上到右下方向增加,这意味如果我们需要一个水平排列的柱状图柱状图底部处于同一y轴操作起来会很麻烦。网上也有不少方法但是多数也是看一头雾水,然而突然灵光一闪...

    使用SVG最头痛的一点就是其宽度和高度是从左上到右下的方向增加的,这意味如果我们需要一个水平排列的柱状图即柱状图底部处于同一y轴操作起来会很麻烦。网上也有不少方法但是多数也是看的一头雾水,然而突然灵光一闪,如果我将整个承载svg的框架逆时针旋转90度那问题不久都迎刃而解了?试了一下效果挺理想,唯一的缺点就是在设计css的时候需要把头也拧90度。
    下面上html代码

    <div id="barchart">
    <p id="title">Peak And Average Timecost</p>
    <div id="bars">
    <div id="ave">
    <div class="avemarks">
    
    </div>
    
    </div>
    <div id="peak">
    <div class="peakmarks">
    
    </div>
    
    </div>
    <div id="ticks">
    <p class="date">Mon</p>
    <p class="date">Tue</p>
    <p class="date">Wed</p>
    <p class="date">Thu</p>
    <p class="date">Fri</p>
    <p class="date">Sat</p>
    <p class="date">Sun</p>
    </div>
    </div>
    
    </div>
    

    这是一个统计一周内北京某路段交通路程的平均时间的项目,用到了百度地图api以及python的数据处理,这里就不上代码了。总之数据都储存在了一个json文件里面,在JavaScript中使用ajax获取json的数据并进行使用,这个在后面的js代码里面会有
    接下来是css代码#barchart{position:absolute;margin:auto;top:50%;left:3%;height:50%;width:50%} #title{font-size:25px;text-align:center;margin-bottom:0} #bars{position:absolute;bottom:0;height:88%;width:100%} #ticks{position:absolute;left:13%;bottom:0} .date{float:left;margin:0px 25px;bottom:0;font-size:30px} svg{display:block;margin-top:36.1%} #ave>svg{background:blue} #peak>svg{background:red} .avemarks{position:absolute;left:20.1%;margin:0 0;height:100%;top:-20%;} #avemarks{-webkit-transform:rotate(90deg);margin:480% 0;position:relative;} #ave{-webkit-transform:rotate(-90deg);height:100px;width:100px;position:absolute;bottom:30px;left:12%;z-index:101;} .peakmarks{position:absolute;left:24.1%;margin:0 0;height:100%;top:-20%} #peakmarks{-webkit-transform:rotate(90deg);margin:480% 0;position:relative} #peak{-webkit-transform:rotate(-90deg);height:100px;width:100px;position:absolute;bottom:30px;left:12%;z-index:100}
    这里最重要的就是在#ave及#peak里面添加的-webkit-transform:rotate(-90deg)这一属性,它的效果就是把整个容器给逆时针旋转90度,这样svg的width和height就会从左下到右上增加,只不过此时width代表了高度,height代表了宽度。 再通过css设计position margin之类的东西对上下面的日期标注就成为一个像样的柱状图了。
    另外我们先要在柱图上方添加具体的数字,那就需要将承载数字的容器.avemarks .peakmark再顺时针调转90度 不然字体就是歪的。
    接下来javascript就是简单的读取数据,再往空的容器里添加svg矢量图。代码如下

    function record(output){
    var recorded=document.getElementById('record');
    recorded.innerHTML=output
    }
    var json=(function(){var json=null;
    $.ajax({'async':false,'global':false,'url':'./baidumap.json','dataType':"json",'success':function(data){json=data;}});
    return json;
    }
    )();
    console.log(json)
    function addAvechart(){
    $("#ave").append('<svg width='+json['Monday'][0]*3+' height=60></svg>')
    $("#ave").append('<svg width='+json['Tuesday'][0]*3+' height=60></svg>')
    $("#ave").append('<svg width='+json['Wednesday'][0]*3+' height=60></svg>')
    $("#ave").append('<svg width='+json['Thursday'][0]*3+' height=60></svg>')
    $("#ave").append('<svg width='+json['Friday'][0]*3+' height=60></svg>')
    $("#ave").append('<svg width='+json['Saturday'][0]*3+' height=60></svg>')
    $("#ave").append('<svg width='+json['Sunday'][0]*3+' height=60></svg>')
    }
    function addAvemark(){
    $(".avemarks").append('<p id="avemarks" style="left:'+json['Monday'][0]*2.5+'px"><b>'+json['Monday'][0]+'</b></p>')
    $(".avemarks").append('<p id="avemarks" style="left:'+json['Tuesday'][0]*2.5+'px"><b>'+json['Tuesday'][0]+'</b></p>')
    $(".avemarks").append('<p id="avemarks" style="left:'+json['Wednesday'][0]*2.5+'px"><b>'+json['Wednesday'][0]+'</b></p>')
    $(".avemarks").append('<p id="avemarks" style="left:'+json['Thursday'][0]*2.5+'px"><b>'+json['Thursday'][0]+'</b></p>')
    $(".avemarks").append('<p id="avemarks" style="left:'+json['Friday'][0]*2.5+'px"><b>'+json['Friday'][0]+'</b></p>')
    $(".avemarks").append('<p id="avemarks" style="left:'+json['Saturday'][0]*2.5+'px"><b>'+json['Saturday'][0]+'</b></p>')
    $(".avemarks").append('<p id="avemarks" style="left:'+json['Sunday'][0]*2.5+'px"><b>'+json['Sunday'][0]+'</b></p>')
    }
    function addPeakchart(){
    $("#peak").append('<svg width='+json['Monday'][1]*3+' height=60></svg>')
    $("#peak").append('<svg width='+json['Tuesday'][1]*3+' height=60></svg>')
    $("#peak").append('<svg width='+json['Wednesday'][1]*3+' height=60></svg>')
    $("#peak").append('<svg width='+json['Thursday'][1]*3+' height=60></svg>')
    $("#peak").append('<svg width='+json['Friday'][1]*3+' height=60></svg>')
    $("#peak").append('<svg width='+json['Saturday'][1]*3+' height=60></svg>')
    $("#peak").append('<svg width='+json['Sunday'][1]*3+' height=60></svg>')
    }
    function addPeakmark(){
    $(".peakmarks").append('<p id="peakmarks" style="left:'+json['Monday'][1]*2.5+'px"><b>'+json['Monday'][1]+'</b></p>')
    $(".peakmarks").append('<p id="peakmarks" style="left:'+json['Tuesday'][1]*2.5+'px"><b>'+json['Tuesday'][1]+'</b></p>')
    $(".peakmarks").append('<p id="peakmarks" style="left:'+json['Wednesday'][1]*2.5+'px"><b>'+json['Wednesday'][1]+'</b></p>')
    $(".peakmarks").append('<p id="peakmarks" style="left:'+json['Thursday'][1]*2.5+'px"><b>'+json['Thursday'][1]+'</b></p>')
    $(".peakmarks").append('<p id="peakmarks" style="left:'+json['Friday'][1]*2.5+'px"><b>'+json['Friday'][1]+'</b></p>')
    $(".peakmarks").append('<p id="peakmarks" style="left:'+json['Saturday'][1]*2.5+'px"><b>'+json['Saturday'][1]+'</b></p>')
    $(".peakmarks").append('<p id="peakmarks" style="left:'+json['Sunday'][1]*2.5+'px"><b>'+json['Sunday'][1]+'</b></p>')
    }
    $(document).ready(function(){addAvechart();addAvemark();addPeakchart();addPeakmark();})
    

    json长这样

    {"Tuesday": [44, 47], "Monday": [32, 58], "Wednesday": [42, 51], "Thursday": [38, 58], "Friday": [37, 57], "Sunday": [34, 47], "Saturday": [34, 48]}
    

    另外我们的这个.ajax方法只适用于服务器环境,因为它请求的protocol只有http https ftp等等而没有file:// ,which 是我们加载本地文件的protocol

    展开全文
  • 这种题通解是用单调栈维护l,r数组,缺点是需要更多空间 class Solution { public: int largestRectangleArea(vector<int>& heights) { int n=heights.size();if(n==0)return 0; int *l=new int[n...
  • 由于是要生成图片所以图表绘制方面在技术选型时就选用了JfreeChart,尽管JfreeChart有很多的缺点譬如说:生成的图片、文字不清晰,JfreeChart的文档要收费等等,但是这些都不是事,图片文字(尤其是对于中文乱码的...
  • 一、AntVg2plot分组柱状图 优点:用处更广泛,用法更简单 缺点:tiptop以一组形式展示(不影响使用) 效果图: 数据: 数据源格式为一个数组对象 const data = [ { name: 'London', 月份: 'Jan.', 月均...
  • 前一篇文章写了思路一:给series集合末尾多加一栏用于展示合计,但缺点较多,所以又想了另一个方法。 思路二:通过tooltip中函数formatter自定义鼠标触发时展示格式,先看展示效果 当我们去掉“安卓”选项时...
  • 地图上显示报表我认为目前一般有几种方法(这个见仁见智),下面介绍三种(最后一种是绝对原创)。...不过他那个缺点很明显,饼图随着地图放大缩小,饼图大小越来越大。 第二种方法是用arcgis server for flex
  • 缺点:必须根据xAxisdata生成一组为空数据,且tooltip不能加trigger: ‘axis’,这个条件,不然会展示合计:0。 数据为模拟数据,已经实现ajax后台动态传数据,但这里不做细讲,主要研究echartsjs求和方法。 ...
  • 常见图表应用场景及其优缺点

    万次阅读 2019-05-04 11:13:56
    柱图,又称柱状图。是一种以长方形长度来表达数据统计报告图,由一系列高度不等纵向条纹表示数据分布情况。
  • JFreeChart使用缺点

    2012-09-04 11:28:00
    饼图(二维和三维),柱状图(水平,垂直),线图,点图,时间变化图,甘特图,股票行情图,混和图,温度计图,刻度图等常用商用图表),图形可以导出成PNG和JPEG格式,同时还可以与PDF和EXCEL关联。JFreeChar...
  • 在数据可视化领域我们经常使用各种图表来形象直观展现数据,业务人员或者...1. 柱图(柱状图) **柱图,**又称柱状图。是一种以长方形长度来表达数据统计报告图,由一系列高度不等纵向条纹表示数据分布...
  • 什么是MVC框架以及缺点

    千次阅读 2014-06-07 10:06:38
    MVC (Modal View Controler)本来是存在于...比如一批统计数据你可以分别用柱状图、饼图来表示。C存在目的则是确保M和V同步,一旦M改变,V应该同步更新。 模型-视图-控制器(MVC)是Xerox PARC在八十年代为编程语
  • JFreeCHart是一个开源半免费工具,可以用来生成饼状图,柱状图,线型图等图片。 优点是代码简单,可以生成jpg或png图片 缺点是不能与用户交互。
  • android折线图的应用

    千次阅读 2015-09-01 18:23:34
    2.使用android系统自制框架AChartEngine,这个框架可以实现各种图,有折线图,柱状图,面积图,散点图...功能还是很强大缺点是样子不美观(老板又是个外贸协会)这个还是我调试过。如图: 如果有需要详细...
  • MVC优缺点

    2020-12-30 11:09:26
    比如一批统计数据你可以分别用柱状图、饼图来表示。C存在目的则是确保M和V同步,一旦M改变,V应该同步更新。 模型-视图-控制器(MVC)是Xerox PARC在八十年代为编程语言Smalltalk-80发明
  • 从技术上来看,裸眼式3D可分为光屏障式(Barrier)、柱状透镜(Lenticular Lens)技术和指向光源(Directional Backlight)三种。裸眼式3D技术最大优势便是摆脱了眼镜束缚,但是分辨率、可视角度和可视距离等方面还...
  • 一般简单点,我们就搞个帧动画,UI 切切切就完事,这是最简单,也是成效最快缺点就是一直循环几张。 另一种情况就是手写VIEW,这样更高大上点,效果看起来也比较好,而且颜色以及柱数量高度可以随意...
  • 图形化报表

    2019-10-08 04:30:41
    一、报表简介  作用:开发winform或web时,用来分析、统计各各种业务数据表。  缺点:外观单一,无法清晰... 可制作:直线图、曲线图、区域图、区域直线图、柱状图、饼状图、散装图等。(纯javaScript编...
  • MVC框架和xml优缺 ...比如:一批统计数据可以用柱状图和饼图表示。XML缺点: 优点: 具有良好格式。标记一定要有结束标记如:具有验证机制。XML标记是程序员自己定义,标记定义和使用是否符合语
  • C# 使用NPlot绘图技巧

    2017-11-10 19:24:00
    NPlot是一款非常难得的.Net平台下的图表控件,能做各种曲线图,柱状图,饼图,散点图,股票图等,而且它免费又开源,使用起来也非常符合程序员的习惯。唯一的缺点就是文档特别难找,难读。通过对其文档的阅读和对...
  • 文章目录前言一、JSBin实现直方图二、JSBin实现二叉树&...缺点:未标明各个柱状图的省份名称,没有在图中写入主题。 进行补充后的完整代码: <!DOCTYPE html> <html> <head> <m
  • NPlot是一款非常难得的.Net平台下的图表控件,能做各种曲线图,柱状图,饼图,散点图,股票图等,而且它免费又开源,使用起来也非常符合程序员的习惯。唯一的缺点就是文档特别难找,难读。通过对其文档的阅读和对...
  • 一、什么是MVC Model:模型层 View:视图层 Controller:控制层 MVC (Modal View Controler)本来是存在于Desktop程序中...比如一批统计数据你可以分别用柱状图、饼图来表示。C存在目的则是确保M和V同步,一...

空空如也

空空如也

1 2 3 4 5
收藏数 85
精华内容 34
关键字:

柱状图的缺点