2018-05-29 11:49:58 CV_Jason 阅读数 2539
  • 微信h5支付开发-php开发微信h5支付demo

    会员免费看,http://edu.csdn.net/lecturer/842右侧可办理会员卡。微信h5支付开发是子恒老师《子恒说微信开发》视频教程的第17部。详细讲解了微信H5支付开发,内容包含开通H5支付,实现微信h5支付,订单查询,关闭订单等等。欢迎反馈,微信号:QQ68183131

    8011 人正在学习 去看看 秦子恒


前言

实验室的项目需要做一个折线图波形,来显示数据。在MATLAB上,只需要一个plot函数就行了,但是在Android上,需要借助一个第三方开源库MPAndroid来实现。本文是对MPAndroidCharts的一个学习和总结。
  MPAndroidChart是一款基于Android的开源图表库,它能实现很多常用的图表类型,如:线型图、饼图、柱状图和散点图。除此之外,它还提供了一些对图表的操作功能,如拖拽、缩放、显示动画效果等。基本上,该开源库能够满足一般性图表绘制需求。

开发环境

开发环境主要包括开源库版本、IDE的环境和操作系统,不同环境会有不同的配置和使用方法,很多技术贴不喜欢在文章开头声明自己所用的开发环境,这样会对人产生很大的误导。

  • Windows 10 Enterprise 64bit
  • Android Studio 3.1.2
  • Gradle 4.1
  • MPAndroidChart 2.2.5

安装和配置

在project的build.gradle文件中的buildscript 节点下加入如下代码:

allprojects {
    repositories {
        maven { url 'https://jitpack.io' }
    }
}

在APP的build.gradle 文件中的dependencies配置依赖库,我们使用V2.2.5的版本(并不是最新版):

implementation 'com.github.PhilJay:MPAndroidChart:v2.2.5'

配置完之后,点击Sysnc Now 就行了。

一个简单的折线图Demo

布局文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.github.mikephil.charting.charts.LineChart
        android:id="@+id/chart1"
        android:layout_width="match_parent"
        android:layout_height="300dp"
         />
</RelativeLayout>

Activity文件


package com.example.jason.mpandroidchatrsdemo;

import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.WindowManager;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;

import com.github.mikephil.charting.animation.Easing;
import com.github.mikephil.charting.charts.LineChart;

import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.Legend.LegendForm;
import com.github.mikephil.charting.components.LimitLine;
import com.github.mikephil.charting.components.LimitLine.LimitLabelPosition;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
import com.github.mikephil.charting.listener.ChartTouchListener;
import com.github.mikephil.charting.listener.OnChartGestureListener;
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
import com.github.mikephil.charting.utils.Utils;
import java.util.ArrayList;

public class MainActivity extends FragmentActivity implements OnChartGestureListener, OnChartValueSelectedListener {

    private LineChart mChart;
    private TextView tvX, tvY;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 设置表格的一些属性
        mChart = (LineChart) findViewById(R.id.chart1);
        // 在图表执行动作时,为定制回调设置一个动作监听器。
        mChart.setOnChartGestureListener(this);
        // 为图表设置一个既定的监听器
        mChart.setOnChartValueSelectedListener(this);
        // 把这个设为true来绘制网格背景,如果false则不绘制
        mChart.setDrawGridBackground(false);

        // 把这个设置为false,禁用所有手势和图表上的触摸,默认:true
        mChart.setTouchEnabled(false);

        // 设置图标拖动为允许
        mChart.setDragEnabled(true);
        // 设置图表缩放为允许
        mChart.setScaleEnabled(true);
        mChart.setScaleXEnabled(true);
        mChart.setScaleYEnabled(true);

        mChart.setDescription("");

        // 挤压缩放设置为允许,即X轴和Y轴会成比例缩放,如果设置为false,则变成单独缩放
        mChart.setPinchZoom(true);

        // 返回代表所有x标签的对象,这个方法可以用来获得XAxis对象并修改它(例如改变标签的位置、样式等)
        XAxis xAxis = mChart.getXAxis();
        // 返回左y轴对象。在水平的柱状图中,这是最上面的轴。
        YAxis leftAxis = mChart.getAxisLeft();
        leftAxis.removeAllLimitLines();

        // 使网格线在虚线模式下绘制,例如像这个“------”。只有在硬件加速被关闭的情况下才会起作用。记住,硬件加速会提高性能。
        leftAxis.enableGridDashedLine(10f, 10f, 0f);
        // 将其设置为true,无论是否启用其他网格线,都要画出零线。默认值:假
        leftAxis.setDrawZeroLine(false);

        // limit lines are drawn behind data (and not on top)
        // 如果这被设置为true,那么界限就会被绘制在实际的数据后面,否则就在上面。默认值:假
        leftAxis.setDrawLimitLinesBehindData(true);

        mChart.getAxisRight().setEnabled(false);
        mChart.getAxisLeft().setEnabled(false);
        mChart.getXAxis().setEnabled(false);

        // add data
        // 这是自己设定的添加数据的方法,count设置了数据的个数,range设置了波动范围
        setData(45, 100);

        // 调用动画对图表显示进行处理
        mChart.animateX(2500, Easing.EasingOption.EaseInOutQuart);

        // get the legend (only possible after setting data)
        // 返回图表的图例对象。这个方法可以用来获得图例的实例,以便定制自动生成的图例。
        Legend l = mChart.getLegend();
        l.setForm(LegendForm.LINE);
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
    }

    // 这个应该是设置数据的函数了
    private void setData(int count, float range) {

        // 这个应该就是x轴的数据了
        ArrayList<String> xVals = new ArrayList<String>();
        // 从 0 到 count设置x轴的数据
        for (int i = 0; i < count; i++) {
            xVals.add((i) + "");
        }
        // 这个是y轴的数据
        ArrayList<Entry> yVals = new ArrayList<Entry>();
        // 设置y轴的数据,在这里,是用random函数来生成的
        for (int i = 0; i < count; i++) {

            float mult = (range + 1);
            float val = (float) (Math.random() * mult) + 3;// + (float)
            // ((mult *
            // 0.1) / 10);
            yVals.add(new Entry(val, i));
        }
        // MPAC自定义的一种类
        // create a dataset and give it a type
        LineDataSet set1 = new LineDataSet(yVals, "BVP - WAVE");
        // set1.setFillAlpha(110);
        // set1.setFillColor(Color.RED);

        // set the line to be drawn like this "- - - - - -"
        // 下面是设置线的各种属性
        // 允许在虚线模式下画出线,例如像这个“------”。只有在硬件加速被关闭的情况下才会起作用。记住,硬件加速会提高性能。
        set1.enableDashedLine(10f, 5f, 0f);
        // 允许在虚线模式下画出高光线,例如,像这样“------”
        set1.enableDashedHighlightLine(10f, 5f, 0f);
        set1.setColor(Color.RED);
        set1.setCircleColor(Color.RED);
        set1.setLineWidth(2f);
        set1.setCircleRadius(0f);
        // 把这个设置为true,允许在每个数据圆上画一个洞。
        set1.setDrawCircleHole(false);
        set1.setValueTextSize(0f);
        //

        set1.setDrawFilled(false);


        if(Utils.getSDKInt() >= 18) {
            // fill drawable only supported on api level 18 and above
            //Drawable drawable = ContextCompat.getDrawable(this, R.drawable.fade_red);
            //set1.setFillDrawable(drawable);
            set1.setFillColor(Color.BLUE);
        } else {
            set1.setFillColor(Color.BLACK);
        }

        ArrayList<ILineDataSet> dataSets = new ArrayList<ILineDataSet>();
        dataSets.add(set1); // add the datasets

        // create a data object with the datasets
        LineData data = new LineData(xVals,dataSets);

        // set data
        mChart.setData(data);
    }

    @Override
    public void onChartGestureStart(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
        Log.i("Gesture", "START, x: " + me.getX() + ", y: " + me.getY());
    }

    @Override
    public void onChartGestureEnd(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
        Log.i("Gesture", "END, lastGesture: " + lastPerformedGesture);

        // un-highlight values after the gesture is finished and no single-tap
        if(lastPerformedGesture != ChartTouchListener.ChartGesture.SINGLE_TAP)
            mChart.highlightValues(null); // or highlightTouch(null) for callback to onNothingSelected(...)
    }

    @Override
    public void onChartLongPressed(MotionEvent me) {
        Log.i("LongPress", "Chart longpressed.");
    }

    @Override
    public void onChartDoubleTapped(MotionEvent me) {
        Log.i("DoubleTap", "Chart double-tapped.");
    }

    @Override
    public void onChartSingleTapped(MotionEvent me) {
        Log.i("SingleTap", "Chart single-tapped.");
    }

    @Override
    public void onChartFling(MotionEvent me1, MotionEvent me2, float velocityX, float velocityY) {
        Log.i("Fling", "Chart flinged. VeloX: " + velocityX + ", VeloY: " + velocityY);
    }

    @Override
    public void onChartScale(MotionEvent me, float scaleX, float scaleY) {
        Log.i("Scale / Zoom", "ScaleX: " + scaleX + ", ScaleY: " + scaleY);
    }

    @Override
    public void onChartTranslate(MotionEvent me, float dX, float dY) {
        Log.i("Translate / Move", "dX: " + dX + ", dY: " + dY);
    }

    @Override
    public void onValueSelected(Entry e, int dataSetIndex, Highlight h) {
        Log.i("Entry selected", e.toString());
        Log.i("LOWHIGH", "low: " + mChart.getLowestVisibleXIndex() + ", high: " + mChart.getHighestVisibleXIndex());
        Log.i("MIN MAX", "xmin: " + mChart.getXChartMin() + ", xmax: " + mChart.getXChartMax() + ", ymin: " + mChart.getYChartMin() + ", ymax: " + mChart.getYChartMax());
    }

    @Override
    public void onNothingSelected() {
        Log.i("Nothing selected", "Nothing selected.");
    }
}


效果展示

折线图

本例的GitHub链接

参考链接

  1. MPAndroidChart的GitHub地址
  2. MPAndroidChart官方文档
  3. 笑谈Android图表-MPAndroidChart
2019-12-28 16:54:06 jerry872235631 阅读数 974
  • 微信h5支付开发-php开发微信h5支付demo

    会员免费看,http://edu.csdn.net/lecturer/842右侧可办理会员卡。微信h5支付开发是子恒老师《子恒说微信开发》视频教程的第17部。详细讲解了微信H5支付开发,内容包含开通H5支付,实现微信h5支付,订单查询,关闭订单等等。欢迎反馈,微信号:QQ68183131

    8011 人正在学习 去看看 秦子恒

框架地址

GITHUB  MPAndroid :https://github.com/PhilJay/MPAndroidChart

  HelloCharts  https://github.com/lecho/hellocharts-android

在此贴出关键代码,源码上传 需要的下载观看  作者会不断更新

DEMO地址 http://download.csdn.net/detail/jerry872235631/9684707

1.柱状图

 

 public void showColumnView(List<ReportOrder> reportOrderList) {
        mReportOrderList = new ArrayList<>();
        mReportOrderList.addAll(reportOrderList);
        //显示多少个集合
        int numColumns = WEEK_ARRAY.length;
        //X轴坐标
        List<AxisValue> axisValues = new ArrayList<>();
        //定义线的集合
        List<Column> columns = new ArrayList<>();
        // 节点数据结合
        List<SubcolumnValue> values;
        //每个集合的柱子遍历
        for (int i = 0; i < numColumns; ++i) {
            values = new ArrayList<>();
            //第一个值是数值(值>0 方向朝上,值<0,方向朝下),第二个值是颜色
            values.add(new SubcolumnValue(reportOrderList.get(i).orderCount, COLOR[i]));
            //X轴添加自定义坐标
            axisValues.add(new AxisValue(i).setLabel(reportOrderList.get(i).date));
            //一个柱状图的实例
            Column column = new Column(values);
            //点击的时候是否显示柱状图的高度,和setHasLabels()和用的时候,setHasLabels()失效
            column.setHasLabelsOnlyForSelected(true);
//            column.setHasLabels(false);
            columns.add(column);
        }
        //表格的数据实例
        ColumnChartData columnData = new ColumnChartData(columns);
        //自定义X轴坐标
        Axis axisX = new Axis();
        axisX.setHasLines(false);//是否显示网格线
        axisX.setTextColor(getResources().getColor(R.color.colorSkyBlue));
        axisX.setValues(axisValues);
        //自定义Y轴
        Axis axisY = new Axis();
        axisY.setHasLines(true);
        axisY.setTextColor(getResources().getColor(R.color.colorSkyBlue));
        axisY.setHasSeparationLine(true);//分割线
        axisY.setLineColor(getResources().getColor(R.color.colorSkyBlue));
//        axisY.setMaxLabelChars(4);
        columnData.setAxisXBottom(axisX);
        columnData.setAxisYLeft(axisY);
        columnData.setValueLabelBackgroundAuto(false);//是否数据背景颜色与节点颜色一致
        columnData.setValueLabelBackgroundEnabled(false);//是否有数据背景颜色
        columnData.setValueLabelsTextColor(getResources().getColor(R.color.colorDeepGray));

//        Viewport viewport = new Viewport();
//        viewport.left = 0;
//        viewport.top = mColumnChartView.getHeight();
//        viewport.bottom = 0;
//        viewport.right = 10;
//        mColumnChartView.setMaximumViewport(viewport);
//        mColumnChartView.setCurrentViewportWithAnimation(viewport);

        mColumnChartView.setColumnChartData(columnData);
        mColumnChartView.setValueSelectionEnabled(true);
        mColumnChartView.setInteractive(true);//与用户互动
        mColumnChartView.setZoomEnabled(false);//是否支持缩放
//        mColumnChartView.setZoomType(ZoomType.HORIZONTAL_AND_VERTICAL);//缩放方向
//        mColumnChartView.setRotation(30);//图表倾斜度
        mColumnChartView.startDataAnimation(500);//延时动画
    }

2.折线图

 

 

 private void initData() {
        int number = months.length;
        List<Line> lines = new ArrayList<>();
        List<PointValue> values = new ArrayList<>();
        //X轴坐标
        List<AxisValue> axisValues = new ArrayList<>();
        for (int i = 0; i < number; i++) {
            values.add(new PointValue(i, (int) (Math.random() * 50)));
            //X轴添加自定义坐标
            axisValues.add(new AxisValue(i).setValue(i).setLabel(months[i]));
        }

        Line line = new Line(values);
        line.setColor(ChartUtils.pickColor());
        line.setStrokeWidth(1);//设置折线宽度
        line.setHasLines(true);

        line.setFilled(false);   //下面填充阴影
        line.setHasPoints(true);//是否显示节点
        line.setPointColor(Color.GREEN);//节点颜色
        line.setPointRadius(3);//节点半径
        line.setHasLabels(true);//是否显示节点数据

        line.setShape(ValueShape.DIAMOND);// 节点图形样式 DIAMOND菱形、SQUARE方形、CIRCLE圆形
        line.setCubic(true);// 是否设置为立体的
        lines.add(line);

        //自定义X轴坐标
        Axis axisX = new Axis();
        axisX.setHasLines(true);// 是否显示X轴网格线
        axisX.setHasSeparationLine(true);//设置是否有分割线
        axisX.setTextColor(Color.BLACK);
        axisX.setLineColor(getResources().getColor(R.color.colorGreen));
        axisX.setTextSize(14);
        axisX.setTypeface(Typeface.DEFAULT);//设置字体样式
        axisX.setHasTiltedLabels(true);//设置X轴文字向左旋转45度
        axisX.setName("本年度");
        axisX.setValues(axisValues);//为X轴显示的刻度值设置数据集合
        //自定义Y轴
        Axis axisY = new Axis();
        axisY.setHasLines(true);
        axisY.setTextColor(Color.BLACK);
//        axisY.setName("运单数量");
        //能看到最后几位
        axisY.setMaxLabelChars(4);

        LineChartData data = new LineChartData();
        data.setLines(lines);
        data.setAxisXBottom(axisX);
        data.setAxisYLeft(axisY);
        data.setBaseValue(Float.NEGATIVE_INFINITY);// 设置反向覆盖区域颜色
        data.setValueLabelBackgroundAuto(false);// 设置数据背景是否跟随节点颜色
        data.setValueLabelBackgroundColor(ChartUtils.pickColor());//设置数据背景颜色
        data.setValueLabelBackgroundEnabled(false);//设置数据背景颜色是否显示
        data.setValueLabelsTextColor(Color.BLUE);//设置数据文字颜色
        mLineCharView.setLineChartData(data);
        //设置图表是否可以与用户互动
        mLineCharView.setInteractive(true);
        //设置是否支持缩放
        mLineCharView.setZoomEnabled(true);
        Animation animation = new AlphaAnimation(0.3f, 1.0f);
        animation.setDuration(1000);
        mLineCharView.startAnimation(animation);
    }

3.饼图

 

HelloCharts

 

 public void showPieChartView(int columnIndex, List<ReportOrder> reportOrderList, String date) {
        List<SliceValue> values = new ArrayList<>();
        String[] orderStatusArray = getResources().getStringArray(R.array.order_status_array);
        String[] amountTypeArray = getResources().getStringArray(R.array.amount_array);
        for (int i = 0; i < reportOrderList.size(); i++) {
            float value = (float) reportOrderList.get(i).amountOrder;
            SliceValue sliceValue = new SliceValue(value, COLOR[i]);
            String amountType = amountTypeArray[i];
            Log.i(TAG, "---value:" + value);
            if (value > 0.01f) {
                String label = amountType + "¥" + ((int) value);
                sliceValue.setLabel(label);
                sliceValue.setSliceSpacing(1);
                values.add(sliceValue);
            }
        }
        Viewport viewport = new Viewport();
        viewport.left = 0;
        viewport.top = 100;
        viewport.bottom = 0;
        viewport.right = 10;
        mPieChartView.setMaximumViewport(viewport);
        mPieChartView.setCurrentViewportWithAnimation(viewport);

        PieChartData data = new PieChartData(values);
        data.setHasLabels(true);//显示标签
        data.setHasLabelsOnlyForSelected(false);//只在点击时显示标签
        data.setHasLabelsOutside(true);//标签数据是否显示在外围
        data.setHasCenterCircle(true);//是否是环形显示
        data.setValueLabelBackgroundEnabled(false);//设置数据背景颜色是否显示
        data.setValueLabelBackgroundAuto(true);//设置数据背景颜色是否与图表背景颜色一致
//        data.setValueLabelBackgroundColor(Color.GREEN);
        data.setValueLabelsTextColor(getResources().getColor(R.color.colorDeepGray));//设置标签字体颜色
        data.setSlicesSpacing(0);//设置分离距离
//        data.setValueLabelTextSize(14);//设置标签字体大小
        data.setCenterCircleScale(0.6f);//内环比例
        data.setCenterText1(date + " " + WEEK_ARRAY[columnIndex]);
        // Get roboto-italic font.
        Typeface typeface1 = Typeface.createFromAsset(getActivity().getAssets(), "Roboto-Italic.ttf");
        data.setCenterText1Typeface(typeface1);
        // Get font size from dimens.xml and convert it to sp(library uses sp values).
        data.setCenterText1FontSize(16);
        data.setCenterText2(orderStatusArray[status] + "费用");
        data.setCenterText2Color(getResources().getColor(R.color.colorSkyBlue));
        Typeface typeface2 = Typeface.createFromAsset(getActivity().getAssets(), "Roboto-Italic.ttf");
        data.setCenterText2Typeface(typeface2);
        data.setCenterText2FontSize(22);
        mPieChartView.setPieChartData(data);//为饼图设置数据
        mPieChartView.setCircleFillRatio(0.7f);//设置饼图其中的比例
        mPieChartView.setViewportCalculationEnabled(true);//设置饼图自动适应大小
        mPieChartView.setValueSelectionEnabled(true);//选择饼图的某一块变大
        mPieChartView.setAlpha(0.8f);//设置透明度
//        mPieChartView.setChartRotation(360, true);//设置饼图旋转角度,且是否为动画
        mPieChartView.setChartRotationEnabled(true);//设置饼图是否可以手动旋转
//        mPieChartView.moveToWithAnimation(1, 2);//移动到指定位置
        mPieChartView.startDataAnimation(1000);//延时开启动画
    }

MPAndroidChart

 

 

private void initPieChart(PieChart pieChart) {
    pieChart.setUsePercentValues(true);//显示成百分比
    pieChart.setDescription("BarChart Test");
    pieChart.setOffsets(5, 10, 5, 5);// 设置偏移量
    pieChart.setDrawHoleEnabled(true);//是否内环显示
    pieChart.setTransparentCircleRadius(55f); //空心圆半径
    pieChart.setHoleRadius(50f);  //内环半径
    pieChart.setDrawCenterText(true);  //饼状图中间可以添加文字
    pieChart.setRotationAngle(90); // 初始旋转角度
    pieChart.setRotationEnabled(true); // 可以手动旋转
    pieChart.setCenterText("PieChart");  //饼状图中间的文字
    //设置数据
    PieData pieData = getPieData(6);
    pieChart.setData(pieData);
    Legend mLegend = pieChart.getLegend();  //设置比例图
    mLegend.setPosition(Legend.LegendPosition.RIGHT_OF_CHART_CENTER);  //最左边显示
    mLegend.setForm(Legend.LegendForm.SQUARE);  //设置比例图的形状,默认是方形 SQUARE
    mLegend.setXEntrySpace(7f);
    mLegend.setYEntrySpace(5f);
    pieChart.animateXY(1000, 1000);  //设置动画
    pieChart.invalidate();
}

private PieData getPieData(int count) {
    int[] yy = {121, 12, 18, 20, 28, 10};
    ArrayList<String> xValues = new ArrayList<>();  //xVals用来表示每个饼块上的内容
    for (int i = 0; i < count; i++) {
        //饼块上显示成PieChart1, PieChart2, PieChart3, PieChart4,PieChart5,PieChart6
        xValues.add("PieChart" + (i + 1));
    }
    /**
     * 将一个饼形图分成六部分, 各个部分的数值比例为12:12:18:20:28:10
     * 所以 12代表的百分比就是12%
     * 在具体的实现过程中,这里是获取网络请求的list的数据
     */
    ArrayList<Entry> yValues = new ArrayList<Entry>();  //yVals用来表示封装每个饼块的实际数据
    for (int i = 0; i < count; i++) {
        yValues.add(new Entry(yy[i], i));
    }
    //y轴的集合
    PieDataSet pieDataSet = new PieDataSet(yValues, "PieChart Revenue 2014");
    pieDataSet.setSliceSpace(0f); //设置个饼状图之间的距离
    // 饼图颜色
    ArrayList<Integer> colors = new ArrayList<Integer>();
    colors.add(Color.rgb(205, 205, 205));
    colors.add(Color.rgb(114, 188, 223));
    colors.add(Color.rgb(255, 123, 124));
    colors.add(Color.rgb(57, 135, 200));
    colors.add(Color.rgb(30, 20, 200));
    colors.add(Color.rgb(80, 60, 150));
    pieDataSet.setColors(colors);
    //dataSet.setXValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);
    DisplayMetrics metrics = getResources().getDisplayMetrics();
    float px = 5 * (metrics.densityDpi / 160f);
    pieDataSet.setSelectionShift(px); // 选中态多出的长度
    return new PieData(xValues, pieDataSet);
}

 

 

 

2017-03-28 16:15:40 Accompany_you_to_go 阅读数 6778
  • 微信h5支付开发-php开发微信h5支付demo

    会员免费看,http://edu.csdn.net/lecturer/842右侧可办理会员卡。微信h5支付开发是子恒老师《子恒说微信开发》视频教程的第17部。详细讲解了微信H5支付开发,内容包含开通H5支付,实现微信h5支付,订单查询,关闭订单等等。欢迎反馈,微信号:QQ68183131

    8011 人正在学习 去看看 秦子恒

DEMO效果图

这里写图片描述

Demo和Jar包 地址

[链接: http://pan.baidu.com/s/1jIaAsa6 密码: dgwq]

MPAndroidChart是一款基于Android的开源图表库,MPAndroidChart不仅可以在Android设备上绘制各种统计图表,而且可以对图表进行拖动和缩放操作,应用起来非常灵活。

由于项目需要,对比了一些框架,感觉还是MPAndroidChart更为好用,项目中多处需要使用折线图所以特地对其做了封装

XML布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.dc.chartproject.MainActivity">

   <com.github.mikephil.charting.charts.LineChart
       android:id="@+id/spread_line_chart"
       android:layout_width="match_parent"
       android:layout_height="240dp" />

   <com.github.mikephil.charting.charts.LineChart
       android:layout_marginTop="10dp"
       android:id="@+id/line_chart"
       android:layout_width="match_parent"
       android:layout_height="240dp" />
</LinearLayout>

完整的工具类代码(Demo中各处都有详细的注释)

public class LineChartManager {

    private static String lineName = null;
    private static String lineName1 = null;

    /**
     * 创建一条折线
     * @param context 上下文
     * @param mLineChart 对象
     * @param count X轴的数据
     * @param datas Y轴的数据
     * @return LineData
     */
    public static LineData initSingleLineChart(Context context, LineChart mLineChart, int count, float[] datas) {

        ArrayList<String> xValues = new ArrayList<String>();
        for (int i = 0; i < count; i++) {
            // x轴显示的数据,这里默认使用数字下标显示
            xValues.add((i) + ":00");
        }

        // y轴的数据
        ArrayList<Entry> yValues = new ArrayList<Entry>();
        for (int i = 0; i < count; i++) {
            yValues.add(new Entry(datas[i], i));
        }
        //设置折线的样式
        LineDataSet dataSet = new LineDataSet(yValues, lineName);
        //用y轴的集合来设置参数
        dataSet.setLineWidth(1.75f); // 线宽
        dataSet.setCircleSize(2f);// 显示的圆形大小
        dataSet.setColor(Color.rgb(89, 194, 230));// 折线显示颜色
        dataSet.setCircleColor(Color.rgb(89, 194, 230));// 圆形折点的颜色
        dataSet.setHighLightColor(Color.GREEN); // 高亮的线的颜色
        dataSet.setHighlightEnabled(true);
        dataSet.setValueTextColor(Color.rgb(89, 194, 230)); //数值显示的颜色
        dataSet.setValueTextSize(8f);     //数值显示的大小

        ArrayList<LineDataSet> dataSets = new ArrayList<>();
        dataSets.add(dataSet);

        //构建一个LineData  将dataSets放入
        LineData lineData = new LineData(xValues, dataSets);
        return lineData;
    }

    /**
     * @param context    上下文
     * @param mLineChart 折线图控件
     * @param count      折线在x轴的值
     * @param datas1     折线在y轴的值
     * @param datas2     另一条折线在y轴的值
     * @Description:创建两条折线
     */
    public static LineData initDoubleLineChart(Context context, LineChart mLineChart, int count, float[] datas1, float[] datas2) {

        ArrayList<String> xValues = new ArrayList<String>();
        for (int i = 0; i < count; i++) {
            // x轴显示的数据,这里默认使用数字下标显示
            xValues.add((i) + ":00");
        }

        // y轴的数据
        ArrayList<Entry> yValues1 = new ArrayList<Entry>();
        for (int i = 0; i < count; i++) {
            yValues1.add(new Entry(datas1[i], i));
        }

        // y轴的数据
        ArrayList<Entry> yValues2 = new ArrayList<Entry>();
        for (int i = 0; i < count; i++) {
            yValues2.add(new Entry(datas2[i], i));
        }

        LineDataSet dataSet = new LineDataSet(yValues1, lineName);
        //dataSet.enableDashedLine(10f, 10f, 0f);//将折线设置为曲线(即设置为虚线)
        //用y轴的集合来设置参数
        dataSet.setLineWidth(1.75f); // 线宽
        dataSet.setCircleSize(2f);// 显示的圆形大小
        dataSet.setColor(Color.rgb(89, 194, 230));// 折线显示颜色
        dataSet.setCircleColor(Color.rgb(89, 194, 230));// 圆形折点的颜色
        dataSet.setHighLightColor(Color.GREEN); // 高亮的线的颜色
        dataSet.setHighlightEnabled(true);
        dataSet.setValueTextColor(Color.rgb(89, 194, 230)); //数值显示的颜色
        dataSet.setValueTextSize(8f);     //数值显示的大小

        LineDataSet dataSet1 = new LineDataSet(yValues2, lineName1);

        //用y轴的集合来设置参数
        dataSet1.setLineWidth(1.75f);
        dataSet1.setCircleSize(2f);
        dataSet1.setColor(Color.rgb(252, 76, 122));
        dataSet1.setCircleColor(Color.rgb(252, 76, 122));
        dataSet1.setHighLightColor(Color.GREEN);
        dataSet1.setHighlightEnabled(true);
        dataSet1.setValueTextColor(Color.rgb(252, 76, 122));
        dataSet1.setValueTextSize(8f);

        //构建一个类型为LineDataSet的ArrayList 用来存放所有 y的LineDataSet   他是构建最终加入LineChart数据集所需要的参数
        ArrayList<LineDataSet> dataSets = new ArrayList<>();

        //将数据加入dataSets
        dataSets.add(dataSet);
        dataSets.add(dataSet1);

        //构建一个LineData  将dataSets放入
        LineData lineData = new LineData(xValues, dataSets);
        return lineData;
    }

    /**
     * @Description:初始化图表的样式
     */
    public static void initDataStyle(LineChart lineChart, LineData lineData, Context context) {
        //设置点击折线点时,显示其数值
//        MyMakerView mv = new MyMakerView(context, R.layout.item_mark_layout);
//        mLineChart.setMarkerView(mv);
        lineChart.setDrawBorders(false); //在折线图上添加边框
        //lineChart.setDescription("时间/数据"); //数据描述
        lineChart.setDrawGridBackground(false); //表格颜色
        lineChart.setGridBackgroundColor(Color.GRAY & 0x70FFFFFF); //表格的颜色,设置一个透明度
        lineChart.setTouchEnabled(true); //可点击
        lineChart.setDragEnabled(true);  //可拖拽
        lineChart.setScaleEnabled(true);  //可缩放
        lineChart.setPinchZoom(false);
        lineChart.setBackgroundColor(Color.WHITE); //设置背景颜色

        lineChart.setData(lineData);

        Legend mLegend = lineChart.getLegend(); //设置标示,就是那个一组y的value的
        mLegend.setForm(Legend.LegendForm.SQUARE); //样式
        mLegend.setFormSize(6f); //字体
        mLegend.setTextColor(Color.GRAY); //颜色
        lineChart.setVisibleXRange(0, 4);   //x轴可显示的坐标范围
        XAxis xAxis = lineChart.getXAxis();  //x轴的标示
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM); //x轴位置
        xAxis.setTextColor(Color.GRAY);    //字体的颜色
        xAxis.setTextSize(10f); //字体大小
        xAxis.setGridColor(Color.GRAY);//网格线颜色
        xAxis.setDrawGridLines(false); //不显示网格线
        YAxis axisLeft = lineChart.getAxisLeft(); //y轴左边标示
        YAxis axisRight = lineChart.getAxisRight(); //y轴右边标示
        axisLeft.setTextColor(Color.GRAY); //字体颜色
        axisLeft.setTextSize(10f); //字体大小
        //axisLeft.setAxisMaxValue(800f); //最大值
        axisLeft.setLabelCount(5, true); //显示格数
        axisLeft.setGridColor(Color.GRAY); //网格线颜色

        axisRight.setDrawAxisLine(false);
        axisRight.setDrawGridLines(false);
        axisRight.setDrawLabels(false);

        //设置动画效果
        lineChart.animateY(2000, Easing.EasingOption.Linear);
        lineChart.animateX(2000, Easing.EasingOption.Linear);
        lineChart.invalidate();
        //lineChart.animateX(2500);  //立即执行动画
    }

    /**
     * @param name
     * @Description:设置折线的名称
     */
    public static void setLineName(String name) {
        lineName = name;
    }

    /**
     * @param name
     * @Description:设置另一条折线的名称
     */
    public static void setLineName1(String name) {
        lineName1 = name;
    }

}

在Activity中使用

public class MainActivity extends AppCompatActivity {


    private LineChart lineChart1, lineChart2;
    private LineData lineData;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initChart1();
        initChart2();
    }

    private void initChart2() {
        lineChart2 = (LineChart) findViewById(R.id.line_chart);
        //设置图表的描述
        lineChart2.setDescription("双曲线");
        //设置x轴的数据
        int numX = 24;
        //设置y轴的数据
        float[] datas1 = {536, 123, 769, 432, 102, 26, 94, 85, 536, 123, 769, 432, 102, 26, 94, 85, 536, 123, 769, 432, 102, 26, 94, 85};//数据
        float[] datas2 = {736, 123, 369, 132, 82, 126, 94, 85, 136, 123, 369, 632, 102, 126, 94, 85, 136, 123, 269, 432, 102, 26, 494, 85};//数据
        //设置折线的名称
        LineChartManager2.setLineName("当月值");
        //设置第二条折线y轴的数据
        LineChartManager2.setLineName1("上月值");
        //创建两条折线的图表
        lineData = LineChartManager2.initDoubleLineChart(this, lineChart1, numX, datas1, datas2);
        LineChartManager2.initDataStyle(lineChart2, lineData, this);
    }
    private void initChart1() {
        lineChart1 = (LineChart) findViewById(R.id.spread_line_chart);
        //设置图表的描述
        lineChart1.setDescription("hhhhhh");
        //设置x轴的数据
        int numX = 24;
        //设置y轴的数据
        float[] datas1 = {536, 123, 769, 432, 102, 26, 94, 85, 536, 123, 769, 432, 102, 26, 94, 85, 536, 123, 769, 432, 102, 26, 94, 85};//数据
        //设置折线的名称
        LineChartManager2.setLineName("当月值");
        //设置第二条折线y轴的数据
        LineChartManager2.setLineName1("上月值");
        //创建两条折线的图表
        lineData = LineChartManager2.initSingleLineChart(this, lineChart1, numX, datas1);
        LineChartManager2.initDataStyle(lineChart1, lineData, this);
    }

}
2016-11-09 09:19:05 u011450295 阅读数 2091
  • 微信h5支付开发-php开发微信h5支付demo

    会员免费看,http://edu.csdn.net/lecturer/842右侧可办理会员卡。微信h5支付开发是子恒老师《子恒说微信开发》视频教程的第17部。详细讲解了微信H5支付开发,内容包含开通H5支付,实现微信h5支付,订单查询,关闭订单等等。欢迎反馈,微信号:QQ68183131

    8011 人正在学习 去看看 秦子恒

     项目中最近用到各种图表,本来打算用第三方的,例如MPAndroid,这是一个十分强大的图表库,应用起来十分方便,但是最终发现和设计不太一样,没办法,只能自己写了。今天将写好的柱状图的demo贴在这,该柱状图可根据数据的功能有一下几点:

     1. 根据数据的多少,动态的绘制柱状图柱子的条数;

     2. 柱状图每条柱子的绘制都有动态的动画效果;

     3. 每条柱子有点击事件,点击时弹出提示框,显示相关信息,规定时间后,弹窗自动消失。

     好了,先上演示图:


     下边贴出相关代码:

     自定义柱状图类:

package com.example.histogram;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Handler;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import com.example.histogram.UI.UI;

import java.text.NumberFormat;

/**
 * Created by ZHANGZDon 2016/6/16 0016.
 * 柱状图
 */
public class HistoGram extends View implements Runnable {
    private Handler handler = new Handler(); // 用于延时更新,实现动画
    private float animHeight; // 进度条动画高度
    private Paint axisLinePaint; // 坐标轴画笔
    private Paint hLinePaint; // 内部水平虚线画笔
    private Paint textPaint; // 绘制文本的画笔
    private Paint recPaint; // 绘制柱状图阴影背景的画笔
    private Paint dataPaint; // 绘制柱状图的画笔
    private Paint textPaint2; // 绘制白色文本的画笔
    private Paint textPaint3; // 绘制坐标的画笔
    private Paint textPaint4;  // 绘制x轴上的白色竖线的画笔

    private String[] xTitleString; // x轴刻度
    private String[] yTitleString; // y轴刻度
    private String[] data; // 接口返回的indicatordata,用于计算柱子高度

    NumberFormat numberFormat; //用于格式化数字

    private float currentHeight; // 当前柱状图应有的高度,应由计算得来
    private int num = -1; // 画多少条柱子,因为存在刚开机数据不足24条的情况
    private float mRelativePxInHeight;
    private float mRelativePxInWidth;
    private OnChartClickListener listener;
    private int mDist;

    public void setNum(int num) {
        this.num = num;
        invalidate();
    }

    public void setData(String[] data) {
        this.data = data;
        invalidate();
    }

    public void setxTitleString(String[] title) {
        this.xTitleString = title;
        invalidate();


    }

    public HistoGram(Context context) {

        this(context, null);
    }

    public HistoGram(Context context, AttributeSet attrs) {
        this(context, attrs, 0);

    }

    public void setTitle(String[] title) {
        this.xTitleString = title;
    }

    public HistoGram(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    /**
     * 进行相关初始化操作
     * @param context
     * @param attrs
     */
    private void init(Context context, AttributeSet attrs) {
        axisLinePaint = new Paint();
        hLinePaint = new Paint();
        textPaint = new Paint();
        recPaint = new Paint();
        dataPaint = new Paint();
        textPaint2 = new Paint();
        textPaint3 = new Paint();
        textPaint4 = new Paint();

        numberFormat = NumberFormat.getNumberInstance();
        numberFormat.setMinimumFractionDigits(3);  //设置打印时保留三位小数
        axisLinePaint.setColor(Color.parseColor("#dbdde4"));  //设置坐标轴的颜色为白色
        hLinePaint.setARGB(51, 255, 255, 255);
        textPaint.setColor(Color.parseColor("#8593a1"));
//        textPaint.setTextSize(29);
        textPaint.setTextSize(UI.dip2px(getContext(), 12));
        recPaint.setColor(Color.parseColor("#f2f5fc"));
        dataPaint.setColor(Color.CYAN);
        textPaint2.setColor(Color.WHITE);
        textPaint2.setTextSize(UI.dip2px(getContext(), 12));
        textPaint3.setColor(Color.parseColor("#000000"));
        textPaint3.setTextSize(UI.dip2px(getContext(), 9));
        textPaint4.setColor(Color.parseColor("#8593a1"));
        textPaint4.setTextSize(UI.dip2px(getContext(), 6));

        axisLinePaint.setAntiAlias(true);
        hLinePaint.setAntiAlias(true);
        textPaint.setAntiAlias(true);
        recPaint.setAntiAlias(true);
        dataPaint.setAntiAlias(true);
        textPaint2.setAntiAlias(true);
        textPaint3.setAntiAlias(true);
        textPaint4.setAntiAlias(true);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if(data == null || xTitleString == null || num < 0 ) {
            return;
        }

        //绘制y轴刻度
        Paint.FontMetrics metrics = textPaint3.getFontMetrics();
        int decent = (int) metrics.descent;
        float width = getWidth();
        float height = getHeight();

        //根据原型图得出,图中每px高度在实际中的相对尺寸
        mRelativePxInHeight = height / 470;
        //根据原型图得出,图中每px宽度在实际中的相对尺寸
        mRelativePxInWidth = width / 690;

        textPaint3.setTextAlign(Paint.Align.RIGHT);


        //绘制纵坐标
        yTitleString = new String[6];
        yTitleString[5] = "0";
        yTitleString[4] = "20";
        yTitleString[3] = "40";
        yTitleString[2] = "60";
        yTitleString[1] = "80";
        yTitleString[0] = "100";

        for (int i = 0; i < yTitleString.length; i++) {
            canvas.drawText(yTitleString[i], 88 * mRelativePxInWidth, (72 + i * 56) * mRelativePxInHeight + decent, textPaint3);
        }


        //绘制x轴刻度
        textPaint3.setTextAlign(Paint.Align.CENTER);
        textPaint4.setTextAlign(Paint.Align.CENTER);
        TextPaint textPaint = new TextPaint();
        textPaint.setColor(Color.parseColor("#000000"));
        textPaint.setTextSize(UI.dip2px(getContext(), 9));
        //计算柱子之间的间隔
        //最左侧位置100 * mRelativePxInWidth,最右侧位置630 ePxInWidth,
        float totalWidth = 630 - 100;
        // 柱子与之子之间的间隔
        mDist = (int) (totalWidth / (xTitleString.length + 1));
        for (int i = 0; i < xTitleString.length; i++) {
            //绘制白色竖线
            canvas.drawLine((100 + (i+1) * mDist) * mRelativePxInWidth, 348 * mRelativePxInHeight, (100 + (i+1) * mDist) * mRelativePxInWidth, 352 * mRelativePxInHeight, axisLinePaint);
            //绘制x轴文字
            canvas.drawText(xTitleString[i], (100 + (i+1) * mDist) * mRelativePxInWidth, 370 * mRelativePxInHeight, textPaint3);
        }


//        绘制矩形阴影
        for (int i = 0; i < num; i++) {
            RectF rectF = new RectF();
//            rectF.left = 111 * relativePxInWidth + i * 22 * relativePxInWidth;
//            rectF.right = 121 * relativePxInWidth + i * 22 * relativePxInWidth;
            rectF.left = 95 * mRelativePxInWidth + (i+1) * mDist * mRelativePxInWidth;
            rectF.right = 105 * mRelativePxInWidth +(i+1) * mDist * mRelativePxInWidth;
            rectF.top = 70 * mRelativePxInHeight;
            rectF.bottom = 338 * mRelativePxInHeight;
            canvas.drawRoundRect(rectF, 10, 10, recPaint);
        }

        //        绘制x轴坐标线
        for (int i = 0; i < 6; i++) {
            canvas.drawLine(100 * mRelativePxInWidth, (66 + i * 56) * mRelativePxInHeight + decent, 630 * mRelativePxInWidth, (66 + i * 56) * mRelativePxInHeight + decent, axisLinePaint);
        }


//        延时绘制,实现动画效果。数字越大,延时越久,动画效果就会越慢
        handler.postDelayed(this, 1);
        for (int i = 0; i < num; i++) {
            RectF dataRectF = new RectF();
            dataRectF.left = 95 * mRelativePxInWidth + (i + 1) * mDist * mRelativePxInWidth;
            dataRectF.right = 105 * mRelativePxInWidth + (i + 1) * mDist * mRelativePxInWidth;

            dataPaint.setColor(Color.parseColor("#3ac2d9"));
            //获取柱子高度
            currentHeight = Float.parseFloat(data[num - 1 - i]);
            if (currentHeight == 0) {
                dataRectF.top = 346 * mRelativePxInHeight;
            } else if (currentHeight == 100) {
                dataRectF.top = 70 * mRelativePxInHeight;
            } else {
                if (animHeight >= currentHeight) {
                    dataRectF.top = 346 * mRelativePxInHeight - currentHeight / 100 * 276 * mRelativePxInHeight;
                } else {
                    dataRectF.top = 346 * mRelativePxInHeight - 276 * mRelativePxInHeight * (animHeight / 100);
                }
            }
            dataRectF.bottom = 346 * mRelativePxInHeight;
//                限制最高高度
            if (dataRectF.top < 70 * mRelativePxInHeight) {
                dataRectF.top = 70 * mRelativePxInHeight;
            }
            canvas.drawRoundRect(dataRectF, 10, 10, dataPaint);

        }
    }

    //实现柱子增长的动画效果
    @Override
    public void run() {
        animHeight += 1;

        if (animHeight >= 276 * mRelativePxInHeight) {
            return;
        } else {
            invalidate();
        }
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN: {
                //获取点击坐标
                float x = event.getX();
                float y = event.getY();
                //判断点击点的位置
                float leftx = 0;
                float rightx = 0;

                for (int i = 0; i < num; i++) {
                    leftx = 95 * mRelativePxInWidth + (i+ 1) * mDist * mRelativePxInWidth - mDist/2 * mRelativePxInWidth;
                    rightx = 105 * mRelativePxInWidth + (i+ 1) * mDist * mRelativePxInWidth + mDist/2 * mRelativePxInWidth;
                    if (x < leftx) {
                        continue;
                    }
                    if (leftx <= x && x <= rightx) {
                        //获取点击的柱子区域的y值
                        float top = 346 * mRelativePxInHeight - Float.parseFloat(data[num - 1 - i])/ 100 * 276 * mRelativePxInHeight;
                        float bottom = 346 * mRelativePxInHeight;


                        if (y >= top && y <= bottom) {
                            //判断是否设置监听
                            //将点击的第几条柱子,点击柱子顶部的坐值,用于弹出dialog提示数据,还要返回百分比currentHeidht = Float.parseFloat(data[num - 1 - i])
                            if(listener != null) {
                                Log.e("ss","x" + x +";y:" + y);
                                listener.onClick(i + 1, leftx + mDist/2,top,Float.parseFloat(data[num - 1 - i]));
                            }
                            break;

                        }
                    }

                }
                break;
            }
            case MotionEvent.ACTION_MOVE:
                Log.e("touch", "ACTION_MOVE");
                break;

            case MotionEvent.ACTION_UP:
                Log.e("touch", "ACTION_UP");
                break;
        }

        return true;
    }

    /**
     * 柱子点击时的监听接口
     */
    public interface OnChartClickListener {
        void onClick(int num, float x, float y, float value);

    }

    /**
     * 设置柱子点击监听的方法
     * @param listener
     */
    public void setOnChartClickListener(OnChartClickListener listener)  {
        this.listener = listener;
    }


}

  在xml文件中的应用:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
   android:orientation="vertical"
    tools:context="com.example.histogram.MainActivity">
    
    <TextView
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:gravity="center"
        android:text="繁忙度指示图(%)"
        android:textSize="15sp"
        android:textColor="#000000"
        />
    

    <com.example.histogram.HistoGram
        android:id="@+id/staticview"
        android:layout_width="400dp"
        android:layout_height="500dp"
        android:layout_gravity="center_horizontal"
        android:layout_marginBottom="14dp"
        android:layout_marginTop="5dp"/>
</LinearLayout>

   在activity中的实现:

package com.example.histogram;

import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.PopupWindow;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    private PopupWindow mPopupWindow;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final HistoGram histoGram = (HistoGram) findViewById(R.id.staticview);
        String[] data ={"100","20","40","20","80","20","60","30","5","20","60","30","5","5","20","60","30","5"};
        final String[] title = {"1","2","3","4","5","6","7","8","9","6","7","8","9","9","6","7","8","9"};

        histoGram.setNum(title.length);
        histoGram.setData(data);
        histoGram.setxTitleString(title);
        histoGram.setOnChartClickListener(new HistoGram.OnChartClickListener() {
            @Override
            public void onClick(int num, float x, float y, float value) {

                //显示提示窗
                View inflate = View.inflate(MainActivity.this, R.layout.popupwindow, null);
                TextView  textView = (TextView) inflate.findViewById(R.id.main_tv);
                textView.setText(value + "%\n" + title[num - 1]);
                if(mPopupWindow != null) {
                    mPopupWindow.dismiss();
                }
                mPopupWindow = new PopupWindow(inflate,140, 60, true);
                mPopupWindow.setTouchable(true);
                Log.e("ss","num" + num +";x" + x+";y"+ y + ";value" + value
                        +";(int)((- histoGram.getHeight()) + y - 65)"
                        +(int)((- histoGram.getHeight()) + y - 65)
                + "histoGram.getHeight()" + histoGram.getHeight());
                // 设置好参数之后再show
//                Toast.makeText(MainActivity.this, "num" + num +";x" + x+";y"+ y + ";value" + value
//                        +";popupWindow.getWidth()"+ mPopupWindow.getWidth()+";"+ mPopupWindow.getHeight(), Toast.LENGTH_SHORT).show();
                mPopupWindow.showAsDropDown(histoGram,(int)(x - 65),(int)((- histoGram.getHeight()) + y - 65) );
                mPopupWindow.setBackgroundDrawable(getResources().getDrawable(R.mipmap.databg_busyness));

                new Handler().postDelayed(new Runnable(){
                    public void run() {

                        mPopupWindow.dismiss();
                    }
                }, 1000);



            }
        });

    }
}

     好了,这就是所有代码,写的比较简单,也存在一些问题,希望大家多多指教吐舌头



2016-09-01 15:25:25 u012246348 阅读数 3394
  • 微信h5支付开发-php开发微信h5支付demo

    会员免费看,http://edu.csdn.net/lecturer/842右侧可办理会员卡。微信h5支付开发是子恒老师《子恒说微信开发》视频教程的第17部。详细讲解了微信H5支付开发,内容包含开通H5支付,实现微信h5支付,订单查询,关闭订单等等。欢迎反馈,微信号:QQ68183131

    8011 人正在学习 去看看 秦子恒

参考:http://www.lai18.com/content/8360860.html


先来个需求图:

该图是项目中需要的,饼图好实现,但MPChart的图例不能显示百分比,需通过自定义实现,二次封装。

Demo图:


以下为实现代码:

MainActivity:

package com.example.pieview;

import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;

import com.github.mikephil.charting.charts.PieChart;

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		PieChart pieChart = (PieChart) findViewById(R.id.pieView);
		LinearLayout legendLayout = (LinearLayout) findViewById(R.id.legend_layout);

		// 模拟数据
		float[] data = new float[] { 1.8f, 3, 5.5f, 10, 6, 5, 6, 4, 2, 1.3f,
				0.9f };
		String[] labels = new String[] { "A", "B", "C", "D", "E", "F", "G",
				"H", "J", "K", "L" };

		PieChartUtils.initPieChart(this, legendLayout, pieChart, data, labels);

	}
}
布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    tools:context=".MainActivity" >

    <com.github.mikephil.charting.charts.PieChart
        android:id="@+id/pieView"
        android:layout_width="0dp"
        android:layout_height="150dp"
        android:layout_weight="1" />

    <!-- 使用ScrollView解决数据太多时的显示问题。注意:height一定要固定 -->

    <ScrollView
        android:layout_width="0dp"
        android:layout_height="150dp"
        android:layout_weight="1" >

        <LinearLayout
            android:id="@+id/legend_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >
        </LinearLayout>
    </ScrollView>

</LinearLayout>

重点:

package com.example.epnc.utils;

import android.content.Context;
import android.graphics.Color;
import android.view.Gravity;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.github.mikephil.charting.charts.PieChart;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.PieData;
import com.github.mikephil.charting.data.PieDataSet;
import com.github.mikephil.charting.formatter.PercentFormatter;
import com.github.mikephil.charting.interfaces.datasets.IDataSet;

import java.util.ArrayList;
import java.util.Random;

/**
 * Created by TCL on 2016/9/1.
 * 饼图自定义图例的二次封装
 */
public class PieChartUtils {

    /**
     * @param context      上下文
     * @param legendLayout 外层的Legend布局
     * @param pieChart     要初始化的饼图
     * @param data         饼图上的数据
     * @param labels       饼图上的数据描述
     */
    public static void initPieChart(Context context, LinearLayout legendLayout, PieChart pieChart, float[] data,
                                    String[] labels) {
        //设置描述
        pieChart.setDescription("");
        // 设置中心圆孔半径占整个饼状图半径的百分比(100f 是最大=整个图表的半径),默认的50%的百分比(即50f)。
        pieChart.setHoleRadius(55f);
        // 设置中间文字中大小
        pieChart.setCenterTextSize(12f);
        // 百分比显示
        pieChart.setUsePercentValues(true);
        // 禁用触摸
        pieChart.setTouchEnabled(false);
        //设置内置图例不显示
        pieChart.getLegend().setEnabled(false);
        // 设置隐藏饼图上文字,只显示百分比
        pieChart.setDrawSliceText(false);


        //数值
        ArrayList<Entry> values = new ArrayList<Entry>();
        //数值描述
        ArrayList<String> valuesLabels = new ArrayList<>();
        //颜色
        int[] colors = new int[data.length];

        //随机颜色需要随机
        Random random = new Random();
        for (int i = 0; i < data.length; i++) {
            //添加数值
            values.add(new Entry(data[i], i));
            //添加数值描述
            valuesLabels.add(labels[i]);

            //随机颜色
            int red = 30 + random.nextInt(200);
            int green = 30 + random.nextInt(200);
            int blue = 30 + random.nextInt(200);

            //添加颜色
            colors[i] = Color.rgb(red, green, blue);
        }


        PieDataSet pieDataSet = new PieDataSet(values, "");
        pieDataSet.setSliceSpace(2f);
        pieDataSet.setValueTextColor(Color.WHITE);
        pieDataSet.setValueTextSize(12f);
        //将随机的颜色设置进来
        pieDataSet.setColors(colors);


        PieData pieData = new PieData(valuesLabels, pieDataSet);
        //设置百分比显示
        pieData.setValueFormatter(new PercentFormatter());

        //自定义图例 该方法一定要在setData之前执行
        setCustomizeLegend(legendLayout, context, colors, data, labels);

        //set data...
        pieChart.setData(pieData);

        //设置是否显示区域百分比的值
        for (IDataSet<?> set : pieChart.getData().getDataSets()) {
            set.setDrawValues(false);
        }
    }

    private static void setCustomizeLegend(LinearLayout legendLayout, Context context, int[] colors, float[] data,
                                           String[] labels) {
        for (int i = 0; i < data.length; i++) {
            //单个图例的layoutParams
            LinearLayout.LayoutParams singleLegendLayoutParams = new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
            // 设置比重为1
            singleLegendLayoutParams.weight = 1;
            // 单个图例的布局
            LinearLayout singleLegendLayout = new LinearLayout(context);
            // 水平排列
            singleLegendLayout.setOrientation(LinearLayout.HORIZONTAL);
            // 垂直居中
            singleLegendLayout.setGravity(Gravity.CENTER_VERTICAL);
            singleLegendLayout.setLayoutParams(singleLegendLayoutParams);


            //添加颜色方块
            LinearLayout.LayoutParams colorLayoutParams = new LinearLayout.LayoutParams(
                    20, 20);
            colorLayoutParams.setMargins(0, 0, 20, 0);
            LinearLayout colorLayout = new LinearLayout(context);
            colorLayout.setLayoutParams(colorLayoutParams);
            colorLayout.setBackgroundColor(colors[i]);
            singleLegendLayout.addView(colorLayout);


            //Label部分和百分比数值部分
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
            params.weight = 1;
            params.gravity = Gravity.CENTER;


            // 添加label
            TextView tvLabel = new TextView(context);
            tvLabel.setText(labels[i] + " ");
            tvLabel.setLayoutParams(params);
            singleLegendLayout.addView(tvLabel);


            // 添加data(百分比显示)
            TextView tvPercentData = new TextView(context);
            float total = 0;
            for (int j = 0; j < data.length; j++) {
                total += data[j];
            }
            tvPercentData.setText((data[i] / total * 100 + "").substring(0, 4) + "%");
            tvPercentData.setLayoutParams(params);
            singleLegendLayout.addView(tvPercentData);

            // legendLayout为外层布局即整个图例布局,是在xml文件中定义
            legendLayout.addView(singleLegendLayout);
        }
    }

}




没有更多推荐了,返回首页