本文介绍了Android 曲线图的绘制示例代码,分享给大家,具体如下:
效果展示
效果展示.gif
使用方式
// 初始化数据表格相关 with(mTableView) { // 配置坐标系 setupCoordinator("日", "人", /*这里是横坐标的值*/0f, 5f, 10f, 15f, 20f, 25f, 30f) // 添加曲线, 确保纵坐标的数值位数相等 addWave(ContextCompat.getColor(this@MainActivity, R.color.colorYellow), false, 0f, 10f, 30f, 54f, 30f, 100f, 10f) addWave(ContextCompat.getColor(this@MainActivity, R.color.colorGreen), false, 0f, 30f, 20f, 20f, 46f, 25f, 5f) addWave(ContextCompat.getColor(this@MainActivity, R.color.colorPink), false, 0f, 30f, 20f, 50f, 46f, 30f, 30f) addWave(Color.parseColor("#8596dee9"), true, 0f, 15f, 10f, 10f, 40f, 20f, 5f) }
实现思路
代码实现
/** * Created by FrankChoo on 2017/12/29. * Email: frankchoochina@gmail.com * Version: 1.0 * Description: 表格自定义View */ public class TableView extends View { private List<WaveConfigData> mWaves;// 数值集合 // 坐标轴的数值 private int mCoordinateYCount = 8; private float[] mCoordinateXValues;// 外界传入 private float[] mCoordinateYValues;// 动态计算 // 坐标的单位 private String mXUnit; private String mYUnit; // 所有曲线中所有数据中的最大值 private float mGlobalMaxValue;// 用于确认是否需要调整坐标系 private Paint mCoordinatorPaint; private Paint mTextPaint; private Paint mWrapPaint; // 坐标轴上描述性文字的空间大小 private int mTopUnitHeight;// 顶部Y轴单位高度 private int mBottomTextHeight; private int mLeftTextWidth; // 网格尺寸 private int mGridWidth, mGridHeight; private float mAnimProgress; public TableView(Context context) { this(context, null); } public TableView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public TableView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); post(new Runnable() { @Override public void run() { showAnimator(); } }); } private void init() { // 初始化数据集合的容器 mWaves = new ArrayList<>(); // 坐标系的单位 mBottomTextHeight = dp2px(40);// X轴底部字体的高度 mLeftTextWidth = mBottomTextHeight;// Y轴左边字体的宽度 mTopUnitHeight = dp2px(30);// 顶部Y轴的单位 // 初始化坐标轴Paint mCoordinatorPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG); mCoordinatorPaint.setColor(Color.LTGRAY); // 初始化文本Paint mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG); mTextPaint.setColor(Color.GRAY); mTextPaint.setTextSize(sp2px(12)); // 初始化曲线Paint mWrapPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG); mWrapPaint.setPathEffect(new CornerPathEffect(200f)); } /** * 配置坐标轴信息 * * @param xUnit X 轴的单位 * @param yUnit Y 轴的单位 * @param coordinateXValues X 坐标轴上的数值 */ public void setupCoordinator(String xUnit, String yUnit, float... coordinateXValues) { mXUnit = xUnit; mYUnit = yUnit; mCoordinateXValues = coordinateXValues; } /** * 添加一条曲线, 确保与横坐标的数值对应 * * @param color * @param isCoverRegion * @param values */ public void addWave(int color, boolean isCoverRegion, float... values) { mWaves.add(new WaveConfigData(color, isCoverRegion, values)); // 根据value的值去计算纵坐标的数值 float maxValue = 0; for (float value : values) { maxValue = Math.max(maxValue, value); } if (maxValue < mGlobalMaxValue) return; mGlobalMaxValue = maxValue; // 保证网格的数值都为 5 的倍数 float gridValue = mGlobalMaxValue / (mCoordinateYCount - 1); if (gridValue % 5 != 0) { gridValue += 5 - (gridValue % 5); } // 给纵坐标的数值赋值 mCoordinateYValues = new float[mCoordinateYCount]; for (int i = 0; i < mCoordinateYCount; i++) { mCoordinateYValues[i] = i * gridValue; } invalidate(); } @Override protected void onDraw(Canvas canvas) { drawCoordinate(canvas); drawWrap(canvas); } public void showAnimator() { ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f).setDuration(1000); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mAnimProgress = (float) animation.getAnimatedValue(); invalidate(); } }); animator.start(); } /** * 绘制坐标系 */ private void drawCoordinate(Canvas canvas) { Point start = new Point(); Point stop = new Point(); // 1. 绘制横轴线和纵坐标单位 int xLineCount = mCoordinateYValues.length; mGridHeight = (getHeight() - getPaddingTop() - getPaddingBottom() - mBottomTextHeight - mTopUnitHeight) / (xLineCount - 1); for (int i = 0; i < xLineCount; i++) { start.x = getPaddingLeft() + mLeftTextWidth; start.y = getHeight() - getPaddingBottom() - mBottomTextHeight - mGridHeight * i; stop.x = getRight() - getPaddingRight(); stop.y = start.y; // 绘制横轴线 canvas.drawLine(start.x, start.y, stop.x, stop.y, mCoordinatorPaint); // 绘制纵坐标单位 if (i == 0) continue; String drawText = String.valueOf((int) mCoordinateYValues[i]); Paint.FontMetricsInt fontMetrics = mTextPaint.getFontMetricsInt(); float offsetY = ((fontMetrics.bottom - fontMetrics.top) / 2 + fontMetrics.bottom) / 2; float baseLine = start.y + offsetY; float left = getPaddingLeft() + mLeftTextWidth / 2 - mTextPaint.measureText(drawText) / 2; canvas.drawText(drawText, left, baseLine, mTextPaint); // 绘制Y轴单位 if (i == xLineCount - 1) { drawText = mYUnit; baseLine = getPaddingTop() + mTopUnitHeight / 2; canvas.drawText(drawText, left, baseLine, mTextPaint); } } // 2. 绘制纵轴线和横坐标单位 int yLineCount = mCoordinateXValues.length; mGridWidth = (getWidth() - getPaddingLeft() - getPaddingRight() - mLeftTextWidth) / (yLineCount - 1); for (int i = 0; i < yLineCount; i++) { start.x = getPaddingTop() + mLeftTextWidth + mGridWidth * i; start.y = getPaddingTop() + mTopUnitHeight; stop.x = start.x; stop.y = getHeight() - mBottomTextHeight - getPaddingBottom(); // 绘制纵轴线 canvas.drawLine(start.x, start.y, stop.x, stop.y, mCoordinatorPaint); // 绘制横坐标单位 String drawText = String.valueOf((int) mCoordinateXValues[i]); Paint.FontMetricsInt fontMetrics = mTextPaint.getFontMetricsInt(); float offsetY = ((fontMetrics.bottom - fontMetrics.top) / 2 + fontMetrics.bottom) / 2; float baseLine = getHeight() - getPaddingBottom() - mBottomTextHeight / 2 + offsetY; float left = start.x - mTextPaint.measureText(drawText) / 2; // 绘制X轴单位 if (i == 0) { drawText = mXUnit; left = getPaddingLeft() + mLeftTextWidth / 2 - mTextPaint.measureText(drawText) / 2; } canvas.drawText(drawText, left, baseLine, mTextPaint); } } /** * 绘制曲线 */ private void drawWrap(Canvas canvas) { canvas.clipRect(new RectF( mLeftTextWidth, getPaddingTop() + mTopUnitHeight, (getRight() - getPaddingRight()) * mAnimProgress, getHeight() - getPaddingBottom() - mBottomTextHeight) ); float yHeight = mGridHeight * (mCoordinateYCount - 1); for (WaveConfigData wave : mWaves) { Path path = new Path(); path.moveTo(0, getHeight()); float maxY = mCoordinateYValues[mCoordinateYCount - 1];// Y轴坐标的最大值 for (int index = 1; index < wave.values.length; index++) { path.lineTo( mLeftTextWidth + mGridWidth * index, getHeight() - getPaddingBottom() - mBottomTextHeight - yHeight * (wave.values[index] / maxY) ); } if (wave.isCoverRegion) { mWrapPaint.setStyle(Paint.Style.FILL); path.lineTo(getRight() - getPaddingRight(), getHeight()); path.close(); } else { mWrapPaint.setStyle(Paint.Style.STROKE); mWrapPaint.setStrokeWidth(10); } mWrapPaint.setColor(wave.color); canvas.drawPath(path, mWrapPaint); } } private int dp2px(float dp) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics()); } private int sp2px(float sp) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, getResources().getDisplayMetrics()); } public static class WaveConfigData { int color; boolean isCoverRegion; float values[]; public WaveConfigData(int color, boolean isCoverRegion, float[] values) { this.color = color; this.isCoverRegion = isCoverRegion; this.values = values; } } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
我画了4条线从中心到按钮,我给你看的照片。我不知道如何在图片中画出红色的曲线。 [在此处输入图像说明] 或 [在此输入图像说明(更简单)]
本文向大家介绍Python绘制3d螺旋曲线图实例代码,包括了Python绘制3d螺旋曲线图实例代码的使用技巧和注意事项,需要的朋友参考一下 Line plots 绘制2D或3D数据 参数 描述 xs, ys X轴,Y轴坐标定点 zs Z值,每一个点的值都是1 zdir 绘制2D集合时使用z的方向 其他的参数:plot() Python代码: 效果图: 总结 以上就是本文关于Python绘制3d螺旋
本文向大家介绍C#绘制曲线图的方法,包括了C#绘制曲线图的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了C#绘制曲线图的方法。分享给大家供大家参考。具体如下: 1. 曲线图效果: 2. C#代码: 3. 数据缩小一个级别的效果: 4. 完整代码 DrawingCurve.cs: 希望本文所述对大家的C#程序设计有所帮助。
本文向大家介绍WPF如何绘制光滑连续贝塞尔曲线示例代码,包括了WPF如何绘制光滑连续贝塞尔曲线示例代码的使用技巧和注意事项,需要的朋友参考一下 1.需求 WPF本身没有直接把点集合绘制成曲线的函数。可以通过贝塞尔曲线函数来绘制。 贝兹曲线由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋,我们在绘图工具上看到的钢笔工具就是来做这种矢量曲线的。当然在一些比较成熟的位图软件中也有贝塞尔曲线工
本文向大家介绍python绘制分布折线图的示例,包括了python绘制分布折线图的示例的使用技巧和注意事项,需要的朋友参考一下 用Python 绘制分布(折线)图,使用的是 plot()函数。 一个简单的例子: 结果: 以上就是python绘制分布折线图的示例代码的详细内容,更多关于python绘制分布折线图的资料请关注呐喊教程其它相关文章!
问题内容: 我正在尝试用Java绘制曲线。一个简单的以(X,Y)开始,(X,Y)结束和曲线量的贝塞尔曲线就足够了。 我找不到在Swing中执行此操作的方法。如果不在Swing中,我可以使用一些简单的数学方法吗?我将如何在Swing中实现它? 编辑:我知道如何通过重写paint(Graphics g)方法绘制形状和线条。 问题答案: 您可以使用Java 2D Object Path2D.Double