配色: 字号:
Android绘图机制(四)——使用HelloCharts开源框架搭建一系列炫酷图表,柱形图,折线图,饼状图和动画特效,抽丝剥茧带你认识图表之美
2016-10-18 | 阅:  转:  |  分享 
  
Android绘图机制(四)——使用HelloCharts开源框架搭建一系列炫酷图表,柱形图,折线图,饼状图和动画特效,抽丝剥茧带你认识图表之美

一.官方截图







二.项目架构



这里我们首先来看一下我排版的思维导图





然后跳转一个Activity

@Override

publicvoidonItemClick(AdapterViewadapter,Viewview,

intposition,longid){

Intentintent;



switch(position){

case0:

//LineChart;

intent=newIntent(getActivity(),LineChartActivity.class);

startActivity(intent);

break;

case1:

//ColumnChart;

intent=newIntent(getActivity(),ColumnChartActivity.class);

startActivity(intent);

break;

case2:

//PieChart;

intent=newIntent(getActivity(),PieChartActivity.class);

startActivity(intent);

break;

case3:

//BubbleChart;

intent=newIntent(getActivity(),BubbleChartActivity.class);

startActivity(intent);

break;

case4:

//PreviewLineChart;

intent=newIntent(getActivity(),

PreviewLineChartActivity.class);

startActivity(intent);

break;

case5:

//PreviewColumnChart;

intent=newIntent(getActivity(),

PreviewColumnChartActivity.class);

startActivity(intent);

break;

case6:

//ComboChart;

intent=newIntent(getActivity(),

ComboLineColumnChartActivity.class);

startActivity(intent);

break;

case7:

//LineColumnDependency;

intent=newIntent(getActivity(),

LineColumnDependencyActivity.class);

startActivity(intent);

break;

case8:

//Tempolinechart;

intent=newIntent(getActivity(),TempoChartActivity.class);

startActivity(intent);

break;

case9:

//Speedlinechart;

intent=newIntent(getActivity(),SpeedChartActivity.class);

startActivity(intent);

break;

case10:

//GoodBadfilledlinechart;

intent=newIntent(getActivity(),GoodBadChartActivity.class);

startActivity(intent);

break;

case11:

//GoodBadfilledlinechart;

intent=newIntent(getActivity(),

ViewPagerChartsActivity.class);

startActivity(intent);

break;

default:

break;

}

}

Activity继承的是FragmentActivity,我们在FragmentActivity内部编写一个Fragment这样就可以绑定主Activity而不用继承自View去多写一个类了

publicstaticclassPlaceholderFragmentextendsFragment



所以你看到的项目也是非常简洁的



项目只有一个主Activity——MainActivity和一个关于软件的AboutActivity,然后就是十二个对应的类了

好了,我们可以编写了

三,实现图标



1.折线图







从这里我们就可以看出,其实图表操作主要还是看menu菜单,所以,我们先实现

我们fragment要绑定的布局

fragment_line_chart




android:id="@+id/chart"

android:layout_width="match_parent"

android:layout_height="match_parent">





LineChartActivity



packagelecho.lib.hellocharts.samples;



importjava.util.ArrayList;

importjava.util.List;



importlecho.lib.hellocharts.animation.ChartAnimationListener;

importlecho.lib.hellocharts.gesture.ZoomType;

importlecho.lib.hellocharts.listener.LineChartOnValueSelectListener;

importlecho.lib.hellocharts.model.Axis;

importlecho.lib.hellocharts.model.Line;

importlecho.lib.hellocharts.model.LineChartData;

importlecho.lib.hellocharts.model.PointValue;

importlecho.lib.hellocharts.model.ValueShape;

importlecho.lib.hellocharts.model.Viewport;

importlecho.lib.hellocharts.util.ChartUtils;

importlecho.lib.hellocharts.view.Chart;

importlecho.lib.hellocharts.view.LineChartView;

importandroid.os.Bundle;

importandroid.support.v4.app.Fragment;

importandroid.support.v4.app.FragmentActivity;

importandroid.view.LayoutInflater;

importandroid.view.Menu;

importandroid.view.MenuInflater;

importandroid.view.MenuItem;

importandroid.view.View;

importandroid.view.ViewGroup;

importandroid.widget.Toast;



publicclassLineChartActivityextendsFragmentActivity{



@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_line_chart);

if(savedInstanceState==null){

getSupportFragmentManager().beginTransaction()

.add(R.id.container,newPlaceholderFragment()).commit();

}

}



/

Afragmentcontainingalinechart.

/

publicstaticclassPlaceholderFragmentextendsFragment{



privateLineChartViewchart;

privateLineChartDatadata;

privateintnumberOfLines=1;

privateintmaxNumberOfLines=4;

privateintnumberOfPoints=12;



float[][]randomNumbersTab=newfloat[maxNumberOfLines][numberOfPoints];



privatebooleanhasAxes=true;

privatebooleanhasAxesNames=true;

privatebooleanhasLines=true;

privatebooleanhasPoints=true;

privateValueShapeshape=ValueShape.CIRCLE;

privatebooleanisFilled=false;

privatebooleanhasLabels=false;

privatebooleanisCubic=false;

privatebooleanhasLabelForSelected=false;

privatebooleanpointsHaveDifferentColor;



publicPlaceholderFragment(){

}



@Override

publicViewonCreateView(LayoutInflaterinflater,ViewGroupcontainer,

BundlesavedInstanceState){

setHasOptionsMenu(true);

ViewrootView=inflater.inflate(R.layout.fragment_line_chart,

container,false);



chart=(LineChartView)rootView.findViewById(R.id.chart);

chart.setOnValueTouchListener(newValueTouchListener());



//Generatesomerandomevalues.

generateValues();



generateData();



//Disableviewpirtrecalculations,seetoggleCubic()methodfor

//moreinfo.

chart.setViewportCalculationEnabled(false);



resetViewport();



returnrootView;

}



//MENU

@Override

publicvoidonCreateOptionsMenu(Menumenu,MenuInflaterinflater){

inflater.inflate(R.menu.line_chart,menu);

}



//menu的操作

@Override

publicbooleanonOptionsItemSelected(MenuItemitem){

intid=item.getItemId();

if(id==R.id.action_reset){

reset();

generateData();

returntrue;

}

if(id==R.id.action_add_line){

addLineToData();

returntrue;

}

if(id==R.id.action_toggle_lines){

toggleLines();

returntrue;

}

if(id==R.id.action_toggle_points){

togglePoints();

returntrue;

}

if(id==R.id.action_toggle_cubic){

toggleCubic();

returntrue;

}

if(id==R.id.action_toggle_area){

toggleFilled();

returntrue;

}

if(id==R.id.action_point_color){

togglePointColor();

returntrue;

}

if(id==R.id.action_shape_circles){

setCircles();

returntrue;

}

if(id==R.id.action_shape_square){

setSquares();

returntrue;

}

if(id==R.id.action_shape_diamond){

setDiamonds();

returntrue;

}

if(id==R.id.action_toggle_labels){

toggleLabels();

returntrue;

}

if(id==R.id.action_toggle_axes){

toggleAxes();

returntrue;

}

if(id==R.id.action_toggle_axes_names){

toggleAxesNames();

returntrue;

}

if(id==R.id.action_animate){

prepareDataAnimation();

chart.startDataAnimation();

returntrue;

}

if(id==R.id.action_toggle_selection_mode){

toggleLabelForSelected();



Toast.makeText(

getActivity(),

"Selectionmodesetto"

+chart.isValueSelectionEnabled()

+"selectanypoint.",Toast.LENGTH_SHORT)

.show();

returntrue;

}

if(id==R.id.action_toggle_touch_zoom){

chart.setZoomEnabled(!chart.isZoomEnabled());

Toast.makeText(getActivity(),

"IsZoomEnabled"+chart.isZoomEnabled(),

Toast.LENGTH_SHORT).show();

returntrue;

}

if(id==R.id.action_zoom_both){

chart.setZoomType(ZoomType.HORIZONTAL_AND_VERTICAL);

returntrue;

}

if(id==R.id.action_zoom_horizontal){

chart.setZoomType(ZoomType.HORIZONTAL);

returntrue;

}

if(id==R.id.action_zoom_vertical){

chart.setZoomType(ZoomType.VERTICAL);

returntrue;

}

returnsuper.onOptionsItemSelected(item);

}



privatevoidgenerateValues(){

for(inti=0;i
for(intj=0;j
randomNumbersTab[i][j]=(float)Math.random()100f;

}

}

}



privatevoidreset(){

numberOfLines=1;



hasAxes=true;

hasAxesNames=true;

hasLines=true;

hasPoints=true;

shape=ValueShape.CIRCLE;

isFilled=false;

hasLabels=false;

isCubic=false;

hasLabelForSelected=false;

pointsHaveDifferentColor=false;



chart.setValueSelectionEnabled(hasLabelForSelected);

resetViewport();

}



privatevoidresetViewport(){

//Resetviewportheightrangeto(0,100)

finalViewportv=newViewport(chart.getMaximumViewport());

v.bottom=0;

v.top=100;

v.left=0;

v.right=numberOfPoints-1;

chart.setMaximumViewport(v);

chart.setCurrentViewport(v);

}



privatevoidgenerateData(){



Listlines=newArrayList();

for(inti=0;i


Listvalues=newArrayList();

for(intj=0;j
values.add(newPointValue(j,randomNumbersTab[i][j]));

}



Lineline=newLine(values);

line.setColor(ChartUtils.COLORS[i]);

line.setShape(shape);

line.setCubic(isCubic);

line.setFilled(isFilled);

line.setHasLabels(hasLabels);

line.setHasLabelsOnlyForSelected(hasLabelForSelected);

line.setHasLines(hasLines);

line.setHasPoints(hasPoints);

if(pointsHaveDifferentColor){

line.setPointColor(ChartUtils.COLORS[(i+1)

%ChartUtils.COLORS.length]);

}

lines.add(line);

}



data=newLineChartData(lines);



if(hasAxes){

AxisaxisX=newAxis();

AxisaxisY=newAxis().setHasLines(true);

if(hasAxesNames){

axisX.setName("AxisX");

axisY.setName("AxisY");

}

data.setAxisXBottom(axisX);

data.setAxisYLeft(axisY);

}else{

data.setAxisXBottom(null);

data.setAxisYLeft(null);

}



data.setBaseValue(Float.NEGATIVE_INFINITY);

chart.setLineChartData(data);



}



/

Addslinestodata,afterthatdatashouldbesetagainwith

{@linkLineChartView#setLineChartData(LineChartData)}.Last4thline

hasnon-monotonicallyxvalues.

/

privatevoidaddLineToData(){

if(data.getLines().size()>=maxNumberOfLines){

Toast.makeText(getActivity(),"Samplesappusesmax4lines!",

Toast.LENGTH_SHORT).show();

return;

}else{

++numberOfLines;

}



generateData();

}



privatevoidtoggleLines(){

hasLines=!hasLines;



generateData();

}



privatevoidtogglePoints(){

hasPoints=!hasPoints;



generateData();

}



privatevoidtoggleCubic(){

isCubic=!isCubic;



generateData();



if(isCubic){

/

手动设置高一点最大立方行,因为有时超过或低于最大值/最小值。为此使用Viewport.inest()

方法并传递负值作为dy参数或手动设置顶部和底部的值

。在这个例子中我知道Y值(0100)范围内我手动设置视口高度范围(105)

。让这个作品在动画应该使用Chart.setViewportCalculationEnabled

(false)之前修改窗口。记住你叫setLineChartData后设置窗口()。

/

finalViewportv=newViewport(chart.getMaximumViewport());

v.bottom=-5;

v.top=105;

//Youhavetosetmaxandcurrentviewportsseparately.

chart.setMaximumViewww.shanxiwang.netwport(v);

//Ichangingcurrentviewportwithanimationinthiscase.

chart.setCurrentViewportWithAnimation(v);

}else{

//Ifnotcubicrestoreviewportto(0,100)range.

finalViewportv=newViewport(chart.getMaximumViewport());

v.bottom=0;

v.top=100;



/

你必须单独设置最大和当前视窗。在这种情况下,如果我想要动画我必须先设置currentviewport和使用动画侦听器。

最大视窗将onAnimationFinished方法。

/

chart.setViewportAnimationListener(newChartAnimationListener(){



@Override

publicvoidonAnimationStarted(){

//TODOAuto-generatedmethodstub



}



@Override

publicvoidonAnimationFinished(){

//设置最大viewpirt和删除侦听器。

chart.setMaximumViewport(v);

chart.setViewportAnimationListener(null);



}

});

//设置当前viewpirt动画;

chart.setCurrentViewportWithAnimation(v);

}



}



privatevoidtoggleFilled(){

isFilled=!isFilled;



generateData();

}



privatevoidtogglePointColor(){

pointsHaveDifferentColor=!pointsHaveDifferentColor;



generateData();

}



privatevoidsetCircles(){

shape=ValueShape.CIRCLE;



generateData();

}



privatevoidsetSquares(){

shape=ValueShape.SQUARE;



generateData();

}



privatevoidsetDiamonds(){

shape=ValueShape.DIAMOND;



generateData();

}



privatevoidtoggleLabels(){

hasLabels=!hasLabels;



if(hasLabels){

hasLabelForSelected=false;

chart.setValueSelectionEnabled(hasLabelForSelected);

}



generateData();

}



privatevoidtoggleLabelForSelected(){

hasLabelForSelected=!hasLabelForSelected;



chart.setValueSelectionEnabled(hasLabelForSelected);



if(hasLabelForSelected){

hasLabels=false;

}



generateData();

}



privatevoidtoggleAxes(){

hasAxes=!hasAxes;



generateData();

}



privatevoidtoggleAxesNames(){

hasAxesNames=!hasAxesNames;



generateData();

}



/

动画值你必须改变目标的值,然后调用{@link图表#

startDataAnimation()}方法(不要混淆View.animate())。如果你操作数据之前设置你不必叫{@link

LineChartView#setLineChartData(LineChartData)}。

/

privatevoidprepareDataAnimation(){

for(Lineline:data.getLines()){

for(PointValuevalue:line.getValues()){

//这里我只修改目标XY值,但可以修改目标。

value.setTarget(value.getX(),(float)Math.random()100);

}

}

}



privateclassValueTouchListenerimplements

LineChartOnValueSelectListener{



@Override

publicvoidonValueSelected(intlineIndex,intpointIndex,

PointValuevalue){

Toast.makeText(getActivity(),"选择:"+value,

Toast.LENGTH_SHORT).show();

}



@Override

publicvoidonValueDeselected(){

//TODOAuto-generatedmethodstub



}



}

}

}

从上面其实可以很容易的就看出,我们一个activity然后add了一个fragment,而一个fragment的实现,有一个xml,在xml中就要用上自定义的view的标签了,而所有的操作,都在menu的菜单上,每个菜单对应的是一个方法,看上去是很多的代码,其实只要你耐心一下,你会发现很多的规律,而且这里也只是才去了随机数,项目中的数据可改性还是很大的,下面的就不一一说明了,现在打字都很卡,编辑器的原因,然道是内容太多了?可是这个原理也不好分章节去写,毕竟有12个重复的写法,那样就太无聊了,我们还是来直接说一下我上次的这个demo的结构



这个我整理过,所以你只要导入hellocharts-library和hellocharts-samples,然后让hellocharts-samples依赖hellocharts-library就可以直接运行了



我们接下来再放几张运行图就直接上Demo吧





















献花(0)
+1
(本文系网络学习天...首藏)