IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> android 大屏图表 MPAndroidChart 水平柱状图 水平圆角柱状图 -> 正文阅读

[移动开发]android 大屏图表 MPAndroidChart 水平柱状图 水平圆角柱状图

//图表库
 implementation  'com.github.PhilJay:MPAndroidChart:v3.1.0'

X轴:XAxis
Y轴:YAxis
图例:Legend
描述:Description
限制线:LimitLine
显示的视图:MarkerView (就是选择中的时候显示的样子)

MPAndroidChart最重要的核心功能

许多不同的图表类型:LineChart(线型图),BarChart(条状图,垂直,水平,堆叠,分组),PieChart(饼图),ScatterChart(散点图),CandleStickChart(K线图、蜡烛图),RadarChart(雷达图、蜘蛛网络图表),BubbleChart(气泡图)
组合图表(例如,一条线和一条条)
在两个轴上缩放(带有触摸手势,单独的轴或捏缩放)
拖动/平移(带有触摸手势)
分开的(双)y轴
突出显示值(带有可自定义的弹出视图)
将图表保存到SD卡(作为图像)
预定义的颜色模板
图例(自动生成,可自定义)
可自定义的轴(x轴和y轴)
动画(在x轴和y轴上建立动画)
极限线(提供其他信息,最大值等)
触摸,手势和选择回调的侦听器
完全可定制(绘画,字体,图例,颜色,背景,虚线等)
通过MPAndroidChart-Realm库支持Realm.io移动数据库
在Line-Chart和BarChart中平滑渲染多达10.000个数据点(在运行Android 6.0的2014 OnePlus One上测试)
轻量级(方法计数?1.4K)
可作为.jar文件使用(大小仅为500kb)
可作为gradle依赖项并通过Maven获得
Google-PlayStore演示应用程序
广泛使用,对GitHub和stackoverflow 都提供了强大的支持– mpandroidchart
也可用于iOS:图表(API的工作方式相同)
也可用于Xamarin:MPAndroidChart.Xamarin
对动态和实时数据的有限的支持

水平柱状图

<?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.HorizontalBarChart
        android:id="@+id/chart1"
        android:layout_width="444px"
        android:layout_height="444px"
        android:background="@android:color/white" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="500px"
        android:orientation="horizontal">

        <Button
            android:id="@+id/actionToggleBarBorders"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="边框"></Button>

        <Button
            android:id="@+id/actionToggleValues"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="显示条形框的值"></Button>

        <Button
            android:id="@+id/actionToggleIcons"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="显示图标"></Button>

        <Button
            android:id="@+id/actionToggleHighlight"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="高亮显示"></Button>

        <Button
            android:id="@+id/actionTogglePinch"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="手势"></Button>


    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="590px"
        android:orientation="horizontal">

        <Button
            android:id="@+id/actionToggleAutoScaleMinMax"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="比例"></Button>

        <Button
            android:id="@+id/animateX"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="X轴动画"></Button>

        <Button
            android:id="@+id/animateY"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Y轴动画"></Button>

        <Button
            android:id="@+id/animateXY"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="XY轴动画"></Button>

        <Button
            android:id="@+id/actionSave"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="保存"></Button>
    </LinearLayout>

    <SeekBar
        android:id="@+id/seekBar2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:visibility="gone"
        android:layout_alignParentLeft="true"
        android:layout_alignParentBottom="true"
        android:layout_margin="8dp"
        android:layout_marginRight="5dp"
        android:layout_toLeftOf="@+id/tvYMax"
        android:max="200"
        android:paddingBottom="12dp" />

    <SeekBar
        android:id="@+id/seekBar1"
        android:layout_width="match_parent"
        android:visibility="gone"
        android:layout_height="wrap_content"
        android:layout_above="@+id/seekBar2"
        android:layout_margin="8dp"
        android:layout_marginRight="5dp"
        android:layout_marginBottom="35dp"
        android:layout_toLeftOf="@+id/tvXMax"
        android:max="500"
        android:paddingBottom="12dp" />

    <TextView
        android:id="@+id/tvXMax"
        android:layout_width="50dp"
        android:visibility="gone"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/seekBar1"
        android:layout_alignParentRight="true"
        android:layout_marginRight="10dp"
        android:layout_marginBottom="15dp"
        android:gravity="right"
        android:text="@string/dash"
        android:textAppearance="?android:attr/textAppearanceMedium" />

    <TextView
        android:id="@+id/tvYMax"
        android:visibility="gone"
        android:layout_width="50dp"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/seekBar2"
        android:layout_alignParentRight="true"
        android:layout_marginRight="10dp"
        android:layout_marginBottom="15dp"
        android:gravity="right"
        android:text="@string/dash"
        android:textAppearance="?android:attr/textAppearanceMedium" />

</RelativeLayout>

package com.xxmassdeveloper.mpchartexample;import com.sbas.xueliapplication.R;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.RectF;
import android.net.Uri;
import android.os.Bundle;
import androidx.core.content.ContextCompat;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;

import com.github.mikephil.charting.charts.HorizontalBarChart;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.XAxis.XAxisPosition;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
import com.github.mikephil.charting.utils.MPPointF;
import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;

import java.util.ArrayList;
import java.util.List;

public class HorizontalBarChartActivity extends DemoBase implements
        OnChartValueSelectedListener, View.OnClickListener {

    private HorizontalBarChart chart;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_horizontalbarchart);

        setTitle("HorizontalBarChartActivity");



        chart = findViewById(R.id.chart1);
        chart.setOnChartValueSelectedListener(this);
        // chart.setHighlightEnabled(false);

        chart.setDrawBarShadow(false);

        chart.setDrawValueAboveBar(true);

        chart.getDescription().setEnabled(false);

        // if more than 60 entries are displayed in the chart, no values will be
        // drawn
        chart.setMaxVisibleValueCount(60);

        // scaling can now only be done on x- and y-axis separately
        chart.setPinchZoom(false);

        // draw shadows for each bar that show the maximum value
        // chart.setDrawBarShadow(true);

        chart.setDrawGridBackground(false);

        XAxis xl = chart.getXAxis();
        xl.setPosition(XAxisPosition.BOTTOM);
        xl.setTypeface(tfLight);
        xl.setDrawAxisLine(true);
        xl.setDrawGridLines(false);
        xl.setGranularity(10f);

        YAxis yl = chart.getAxisLeft();
        yl.setTypeface(tfLight);
        yl.setDrawAxisLine(true);
        yl.setDrawGridLines(true);
        yl.setAxisMinimum(0f); // this replaces setStartAtZero(true)
//        yl.setInverted(true);

        YAxis yr = chart.getAxisRight();
        yr.setTypeface(tfLight);
        yr.setDrawAxisLine(true);
        yr.setDrawGridLines(false);
        yr.setAxisMinimum(0f); // this replaces setStartAtZero(true)
//        yr.setInverted(true);

        chart.setFitBars(true);
        chart.animateY(2500);

        // setting data
        setDataHorizontalBarChar(5,50);

        Legend l = chart.getLegend();
        l.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
        l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);
        l.setOrientation(Legend.LegendOrientation.HORIZONTAL);
        l.setDrawInside(false);
        l.setFormSize(8f);
        l.setXEntrySpace(4f);

        initButton();
    }

    private void initButton() {
        Button actionToggleBarBorders =  findViewById(R.id.actionToggleBarBorders);
        actionToggleBarBorders.setOnClickListener(this::onClick);
        Button actionToggleValues =  findViewById(R.id.actionToggleValues);
        actionToggleValues.setOnClickListener(this::onClick);
        Button actionToggleIcons =  findViewById(R.id.actionToggleIcons);
        actionToggleIcons.setOnClickListener(this::onClick);
        Button actionToggleHighlight =  findViewById(R.id.actionToggleHighlight);
        actionToggleHighlight.setOnClickListener(this::onClick);
        Button actionTogglePinch =  findViewById(R.id.actionTogglePinch);
        actionTogglePinch.setOnClickListener(this::onClick);
        Button actionToggleAutoScaleMinMax =  findViewById(R.id.actionToggleAutoScaleMinMax);
        actionToggleAutoScaleMinMax.setOnClickListener(this::onClick);
        Button animateX =  findViewById(R.id.animateX);
        animateX.setOnClickListener(this::onClick);
        Button animateY =  findViewById(R.id.animateY);
        animateY.setOnClickListener(this::onClick);
        Button animateXY =  findViewById(R.id.animateXY);
        animateXY.setOnClickListener(this::onClick);
        Button actionSave =  findViewById(R.id.actionSave);
        actionSave.setOnClickListener(this::onClick);


    }

    private void setDataHorizontalBarChar(int count, float range) {

        float barWidth = 9f;
        float spaceForBar = 10f;
        ArrayList<BarEntry> values = new ArrayList<>();

        for (int i = 0; i < count; i++) {
            float val = (float) (Math.random() * range);
            values.add(new BarEntry(i * spaceForBar, val,
                    getResources().getDrawable(R.drawable.star)));
        }

        BarDataSet set1;

        if (chart.getData() != null &&
                chart.getData().getDataSetCount() > 0) {
            set1 = (BarDataSet) chart.getData().getDataSetByIndex(0);
            set1.setValues(values);
            chart.getData().notifyDataChanged();
            chart.notifyDataSetChanged();
        } else {
            set1 = new BarDataSet(values, "DataSet 1");

            set1.setDrawIcons(false);

            ArrayList<IBarDataSet> dataSets = new ArrayList<>();
            dataSets.add(set1);

            BarData data = new BarData(dataSets);
            data.setValueTextSize(10f);
            data.setValueTypeface(tfLight);
            data.setBarWidth(barWidth);
            chart.setData(data);
        }
    }



    @Override
    protected void saveToGallery() {
        saveToGallery(chart, "HorizontalBarChartActivity");
    }


    private final RectF mOnValueSelectedRectF = new RectF();

    @Override
    public void onValueSelected(Entry e, Highlight h) {

        if (e == null)
            return;

        RectF bounds = mOnValueSelectedRectF;
        chart.getBarBounds((BarEntry) e, bounds);

        MPPointF position = chart.getPosition(e, chart.getData().getDataSetByIndex(h.getDataSetIndex())
                .getAxisDependency());

        Log.i("bounds", bounds.toString());
        Log.i("position", position.toString());

        MPPointF.recycleInstance(position);
    }

    @Override
    public void onNothingSelected() {}

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.viewGithub: {
                Intent i = new Intent(Intent.ACTION_VIEW);
                i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/HorizontalBarChartActivity.java"));
                startActivity(i);
                break;
            }
            case R.id.actionToggleValues: {
                List<IBarDataSet> sets = chart.getData()
                        .getDataSets();

                for (IBarDataSet iSet : sets) {
                    iSet.setDrawValues(!iSet.isDrawValuesEnabled());
                }
                chart.invalidate();
                break;
            }
            case R.id.actionToggleIcons: {
                List<IBarDataSet> sets = chart.getData()
                        .getDataSets();

                for (IBarDataSet iSet : sets) {
                    iSet.setDrawIcons(!iSet.isDrawIconsEnabled());
                }

                chart.invalidate();
                break;
            }
            case R.id.actionToggleHighlight: {
                if(chart.getData() != null) {
                    chart.getData().setHighlightEnabled(!chart.getData().isHighlightEnabled());
                    chart.invalidate();
                }
                break;
            }
            case R.id.actionTogglePinch: {
                if (chart.isPinchZoomEnabled())
                    chart.setPinchZoom(false);
                else
                    chart.setPinchZoom(true);

                chart.invalidate();
                break;
            }
            case R.id.actionToggleAutoScaleMinMax: {
                chart.setAutoScaleMinMaxEnabled(!chart.isAutoScaleMinMaxEnabled());
                chart.notifyDataSetChanged();
                break;
            }
            case R.id.actionToggleBarBorders: {
                for (IBarDataSet set : chart.getData().getDataSets())
                    ((BarDataSet)set).setBarBorderWidth(set.getBarBorderWidth() == 1.f ? 0.f : 1.f);

                chart.invalidate();
                break;
            }
            case R.id.animateX: {
                chart.animateX(2000);
                break;
            }
            case R.id.animateY: {
                chart.animateY(2000);
                break;
            }
            case R.id.animateXY: {
                chart.animateXY(2000, 2000);
                break;
            }
            case R.id.actionSave: {
                if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
                    saveToGallery();
                } else {
                    requestStoragePermission(chart);
                }
                break;
            }
        }
    }
}

package com.xxmassdeveloper.mpchartexample.notimportant;

import android.Manifest;
import android.content.pm.PackageManager;
import android.graphics.Typeface;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.snackbar.Snackbar;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.view.View;
import android.widget.Toast;

import com.github.mikephil.charting.charts.Chart;
import com.sbas.xueliapplication.R;

/**
 * Base class of all Activities of the Demo Application.
 *
 * @author Philipp Jahoda
 */
public abstract class DemoBase extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback {

    protected final String[] months = new String[] {
            "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"
    };

    protected final String[] parties = new String[] {
            "Party A", "Party B", "Party C", "Party D", "Party E", "Party F", "Party G", "Party H",
            "Party I", "Party J", "Party K", "Party L", "Party M", "Party N", "Party O", "Party P",
            "Party Q", "Party R", "Party S", "Party T", "Party U", "Party V", "Party W", "Party X",
            "Party Y", "Party Z"
    };

    private static final int PERMISSION_STORAGE = 0;

    protected Typeface tfRegular;
    protected Typeface tfLight;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        tfRegular = Typeface.createFromAsset(getAssets(), "OpenSans-Regular.ttf");
        tfLight = Typeface.createFromAsset(getAssets(), "OpenSans-Light.ttf");
    }

    protected float getRandom(float range, float start) {
        return (float) (Math.random() * range) + start;
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        overridePendingTransition(R.anim.move_left_in_activity, R.anim.move_right_out_activity);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == PERMISSION_STORAGE) {
            if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                saveToGallery();
            } else {
                Toast.makeText(getApplicationContext(), "Saving FAILED!", Toast.LENGTH_SHORT)
                        .show();
            }
        }
    }

    protected void requestStoragePermission(View view) {
        if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            Snackbar.make(view, "Write permission is required to save image to gallery", Snackbar.LENGTH_INDEFINITE)
                    .setAction(android.R.string.ok, new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            ActivityCompat.requestPermissions(DemoBase.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_STORAGE);
                        }
                    }).show();
        } else {
            Toast.makeText(getApplicationContext(), "Permission Required!", Toast.LENGTH_SHORT)
                    .show();
            ActivityCompat.requestPermissions(DemoBase.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_STORAGE);
        }
    }

    protected void saveToGallery(Chart chart, String name) {
        if (chart.saveToGallery(name + "_" + System.currentTimeMillis(), 70))
            Toast.makeText(getApplicationContext(), "Saving SUCCESSFUL!",
                    Toast.LENGTH_SHORT).show();
        else
            Toast.makeText(getApplicationContext(), "Saving FAILED!", Toast.LENGTH_SHORT)
                    .show();
    }

    protected abstract void saveToGallery();
}

?如果不想要上边的线? ? ??yl.setEnabled(false);

        YAxis yl = chart.getAxisLeft();
        yl.setEnabled(false);
        yl.setTypeface(tfLight);
        yl.setDrawAxisLine(true);
        yl.setDrawGridLines(false);
        yl.setAxisMinimum(0f); // this replaces setStartAtZero(true)
//        yl.setInverted(true);

如果想要圆角柱状图? 修改

HorizontalBarChartRenderer.java

?

?

            if (isCustomFill) {
                dataSet.getFill(pos)
                        .fillRect(
                                c, mRenderPaint,
                                buffer.buffer[j],
                                buffer.buffer[j + 1],
                                buffer.buffer[j + 2],
                                buffer.buffer[j + 3],
                                isInverted ? Fill.Direction.LEFT : Fill.Direction.RIGHT);
            }
            else {
//                c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],
//                        buffer.buffer[j + 3], mRenderPaint);
                RectF rectF=new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],buffer.buffer[j + 3]);
                c.drawRoundRect(rectF,(float)25,(float)25,mRenderPaint);

            }

但是,如果想要自定义四个角的弧度,就需要使用Path类绘制。做以下修改:?

HorizontalBarChartRenderer.java

            if (isCustomFill) {
                dataSet.getFill(pos)
                        .fillRect(
                                c, mRenderPaint,
                                buffer.buffer[j],
                                buffer.buffer[j + 1],
                                buffer.buffer[j + 2],
                                buffer.buffer[j + 3],
                                isInverted ? Fill.Direction.LEFT : Fill.Direction.RIGHT);
            }
            else {
//                c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],
//                        buffer.buffer[j + 3], mRenderPaint);
//                RectF rectF=new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],buffer.buffer[j + 3]);
//                c.drawRoundRect(rectF,(float)25,(float)25,mRenderPaint);
                RectF rectF=new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],buffer.buffer[j + 3]);
                Path path = new Path();
               //float数组中4个角分别是左上、右上、右下、左下
                path.addRoundRect(rectF,new float[]{0, 0, 20, 20, 20, 20, 0, 0},Path.Direction.CCW);
                c.drawPath(path,mRenderPaint);

            }

?

?

调整图形的宽度。

?

?

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-10-08 20:53:18  更:2022-10-08 20:53:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 4:26:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码