用XCL-Charts定制多柱形堆积图

    有网友发了张图,问我实现的方法。 与一般的柱形图不一样,这张图很特别,相信他要找到现成的,对得上号的图表将不是件易事。

通常图表库实现的不是通常意义上的柱形图,就是单纯的堆积图,很少有这种混在一起展现的情况出现。没得法,要定制才能实现的了。

      网友的原图(应当没侵权吧)            

                

     利用XCL-Charts实现的效果图:

             

                   网友的这张表面看起来,是同一个标签,两个堆积柱形并排放在一起,但依我的经验,要原汁原味让图表库提供这种图是很难的,

参数及数据位置计算很难处理。只能利用现有图表,采用混合方式实现。仔细观察了下,发现实际上只要将两个柱形图并在一起,在柱形高

度上做点手脚就能达到这个效果了。

        即,先画高一点那一些柱形图,再绘数据低一层的柱形图。 当然如果数据是变化的,现在高的到时有可能变低,就不能采用这种方法了,

但这张图暂不用考虑这个问题。

       定制程序的部份代码如下:         

	private String TAG = "MultiBarchart201View";
	private BarChart chart = new BarChart();
	private BarChart chart2 = new BarChart();
	
	//标签轴
	private List<String> chartLabels = new LinkedList<String>();
	private List<BarData> chartData = new LinkedList<BarData>();
	private List<BarData> chartData2 = new LinkedList<BarData>();
	
	private int axisColor = Color.rgb(125, 223, 252);
	
	public MultiBarChart01View(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		initView();				
	}
	
	public MultiBarChart01View(Context context, AttributeSet attrs){   
        super(context, attrs);   
        initView();
	 }
	 
	 public MultiBarChart01View(Context context, AttributeSet attrs, int defStyle) {
			super(context, attrs, defStyle);
			initView();
	 }
	 
	 private void initView()
	 {
		 	chartLabels();
			chartDataSet();
			chartDataSet2();
			chartRender();
			chartRender2();
			
	 }
	
	@Override  
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {  
        super.onSizeChanged(w, h, oldw, oldh);  
       //图所占范围大小
        chart.setChartRange(w,h);
        chart2.setChartRange(w,h);
    }  
	
	
	private void chartRender()
	{
		try {								
			//设置绘图区默认缩进px值,留置空间显示Axis,Axistitle....		
			int [] ltrb = getBarLnDefaultSpadding();
			chart.setPadding(ltrb[0], ltrb[1], DensityUtil.dip2px(getContext(), 45), ltrb[3]);			
		
			//数据源
			chart.setDataSource(chartData);
			chart.setCategories(chartLabels);				
			
			//数据轴
			chart.getDataAxis().setAxisMax(2500);
			chart.getDataAxis().setAxisMin(0);
			chart.getDataAxis().setAxisSteps(500);
								
			 //让柱子间没空白
			 chart.getBar().setBarInnerMargin(0d);
			 
			 //隐藏轴
			 chart.getDataAxis().setVisible(false);
			 chart.getCategoryAxis().setVisible(false);
						 
			 //将Bar风格设为Fill
			 chart.getBar().setBarStyle(XEnum.BarStyle.FILL);
			 
			 chart.setApplyBackgroundColor(true);
			 chart.setBackgroundColor(Color.rgb(19, 163, 224));			 			 			 
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			Log.e(TAG, e.toString());
		}
	}
	
	
	private void chartRender2()
	{
		try {									 
			//设置绘图区默认缩进px值,留置空间显示Axis,Axistitle....		
			int [] ltrb = getBarLnDefaultSpadding();
			chart2.setPadding(ltrb[0], ltrb[1], DensityUtil.dip2px(getContext(), 45), ltrb[3]);			
			
			//显示边框
			//chart2.showRoundBorder();		
			
			chart2.getBar().setBarStyle(XEnum.BarStyle.FILL);			
			
			//标题
			chart2.setTitle("负债率标准备: 40%~60%");
			chart2.addSubtitle("(XCL-Charts Demo)");	
			chart2.getPlotTitle().getTitlePaint().setColor(axisColor);
			chart2.getPlotTitle().getSubtitlePaint().setColor(axisColor);
			//数据源
			chart2.setDataSource(chartData2);
			chart2.setCategories(chartLabels);	
			
			//轴标题
			chart2.getAxisTitle().setLeftAxisTitle("金额");
			chart2.getAxisTitle().setLowerAxisTitle("资产负债率");
			
			//数据轴
			chart2.getDataAxis().setAxisMax(2500);
			chart2.getDataAxis().setAxisMin(0);
			chart2.getDataAxis().setAxisSteps(500);
			
		
			//定义数据轴标签显示格式
			chart2.getDataAxis().setLabelFormatter(new IFormatterTextCallBack(){
	
				@Override
				public String textFormatter(String value) {
					// TODO Auto-generated method stub		
					Double tmp = Double.parseDouble(value);
					DecimalFormat df=new DecimalFormat("#0");
					String label = df.format(tmp).toString();				
					return (label);
				}
				
			});					
			
			 //让柱子间没空白
			 chart2.getBar().setBarInnerMargin(0d);
					
			//轴颜色					
			chart2.getDataAxis().getAxisPaint().setColor(axisColor);
			chart2.getCategoryAxis().getAxisPaint().setColor(axisColor);			
			chart2.getDataAxis().getTickMarksPaint().setColor(axisColor);
			chart2.getCategoryAxis().getTickMarksPaint().setColor(axisColor);
			
			chart2.getDataAxis().getTickLabelPaint().setColor(axisColor);
			chart2.getCategoryAxis().getTickLabelPaint().setColor(axisColor);
			
			chart2.getAxisTitle().getLeftAxisTitlePaint().setColor(axisColor);
			chart2.getAxisTitle().getLowerAxisTitlePaint().setColor(axisColor);
			
			//隐藏图例
			chart2.getPlotLegend().hideLegend();
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			Log.e(TAG, e.toString());
		}
	}
	
	
	private void chartDataSet()
	{
		//标签对应的柱形数据集
		List<Double> dataSeriesA= new LinkedList<Double>();	
		dataSeriesA.add(2400d); 
		dataSeriesA.add(2400d); 
		dataSeriesA.add(2400d);
		dataSeriesA.add(2400d); 
		dataSeriesA.add(2400d);
		BarData BarDataA = new BarData("流动资产",dataSeriesA,(int)Color.rgb(58, 191, 247));
				
		List<Double> dataSeriesB= new LinkedList<Double>();	
		dataSeriesB.add(2000d);
		dataSeriesB.add(2000d);
		dataSeriesB.add(2000d);
		dataSeriesB.add(2000d);
		dataSeriesB.add(2000d);
		BarData BarDataB = new BarData("非流动资产",dataSeriesB,(int)Color.rgb(20, 181, 251));
		
	
		chartData.add(BarDataA);
		chartData.add(BarDataB);
		
		
		List<Double> dataSeriesAA= new LinkedList<Double>();	
		dataSeriesAA.add(0d); 
		BarData BarDataAA = new BarData("负债",dataSeriesAA,(int)Color.rgb(38, 137, 176));
		
		List<Double> dataSeriesBB= new LinkedList<Double>();	
		dataSeriesBB.add(0d);
		BarData BarDataBB = new BarData("所有者权益",dataSeriesBB,(int)Color.rgb(13, 116, 161));
		
		chartData.add(BarDataAA);
		chartData.add(BarDataBB);
		
	}
	
	private void chartDataSet2()
	{					
		//标签对应的柱形数据集
		List<Double> dataSeriesA= new LinkedList<Double>();	
		dataSeriesA.add(1600d); 
		dataSeriesA.add(1700d); 
		dataSeriesA.add(1800d);
		dataSeriesA.add(1800d); 
		dataSeriesA.add(1500d);
		BarData BarDataA = new BarData("负债",dataSeriesA,(int)Color.rgb(38, 137, 176));
				
		List<Double> dataSeriesB= new LinkedList<Double>();	
		dataSeriesB.add(1500d);
		dataSeriesB.add(1300d);
		dataSeriesB.add(1400d);
		dataSeriesB.add(1200d);
		dataSeriesB.add(1600d);
		BarData BarDataB = new BarData("所有者权益",dataSeriesB,(int)Color.rgb(13, 116, 161));
			
		chartData2.add(BarDataA);
		chartData2.add(BarDataB);	
	}
	
	
	private void chartLabels()
	{
		chartLabels.add("20%"); 
		chartLabels.add("40%"); 
		chartLabels.add("60%"); 
		chartLabels.add("80%"); 
		chartLabels.add("100%"); 
	}	
		
	@Override
    public void render(Canvas canvas) {
        try{        	           
            chart.render(canvas);  
            chart2.render(canvas);  
            
            //绘制轴点
            float radius = 10f;
            Paint paint = new Paint();
            paint.setAntiAlias(true);
            paint.setColor(this.axisColor);            
            canvas.drawCircle(chart2.getPlotArea().getLeft(), chart2.getPlotArea().getBottom(), radius, paint);            
            canvas.drawCircle(chart2.getPlotArea().getRight(), chart2.getPlotArea().getBottom(), radius, paint);            
            canvas.drawCircle(chart2.getPlotArea().getLeft(), chart2.getPlotArea().getTop(), radius, paint);            
            
        } catch (Exception e){
        	Log.e(TAG, e.toString());
        }
    }			


     至此,图就绘制出来了。 代码不长,相信基本能看懂。

     特别要说一下代码中的绘制轴点。 在原图中,轴的两端和交叉处都有一个白点。XCL-Charts默认是没有这个功能,但这三个点的位置,

在XCL-Charts中都能取得出来,所以直接在render()中,直接加上三个绘制制circle的代码就行了。图例和轴标题风格有点不同,但这已不是什么大问题了。如果

还要求一样,可从XCL-Charts中依相关函数得到位置后,自定义一个图例和轴标题也不是难事。

      发现现在有个性的图太多了,各式各样,好多都没见过,很难考虑得到这些情况,所以图表库的灵活性与定制化越发重要,但我发现很少有人认真去看图表库,

都喜欢瞄瞄有没原样的,没有继续到处找。图表真的很特别时,等着哭吧。 哈哈。

    这个例子已收录在XCL-Charts图表库的demo中,有兴趣的可以去看看。

 

 MAIL: xcl_168@aliyun.com

 BLOG: http://blog.csdn.net/xcl168

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值