简单的一元函数绘制(仅限加法减法)
用到了MPAndroidChart 具体可看 详解
implementation ("com.github.PhilJay:MPAndroidChart:v3.1.0")
settings.gradle.kts
pluginManagement {
repositories {
google()
mavenCentral()
maven { url=uri("https://www.jitpack.io")}
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven { url=uri("https://www.jitpack.io")}
}
}
rootProject.name = "chart"
include(":app")
CustomMarkerView.java
package com.example.chart;
import android.annotation.SuppressLint;
import android.content.Context;
import android.widget.TextView;
import com.github.mikephil.charting.components.MarkerView;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.utils.MPPointF;
public class CustomMarkerView extends MarkerView {
private TextView tvContent;
public CustomMarkerView(Context context, int layoutResource) {
super(context, layoutResource);
tvContent = findViewById(R.id.tvContent);
}
// 每次重绘指示器时调用此函数更新文本内容
@SuppressLint("DefaultLocale")
@Override
public void refreshContent(Entry e, Highlight highlight) {
tvContent.setText(String.format("x: %.1f, y: %.1f", e.getX(), e.getY()));
super.refreshContent(e, highlight);
}
// 控制指示器的位置,这里将指示器显示在所选点的上方
@Override
public MPPointF getOffset() {
return new MPPointF(-(getWidth() / 2f), -getHeight() - 10);
}
}
MainActivity.java
package com.example.chart;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.MarkerView;
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.listener.ChartTouchListener;
import com.github.mikephil.charting.listener.OnChartGestureListener;
import java.util.ArrayList;
//public class MainActivity extends AppCompatActivity {
//
// @Override
// protected void onCreate(Bundle savedInstanceState) {
// super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_main);
// }
//}
public class MainActivity extends AppCompatActivity {
// 创建 LineChart 对象
private LineChart chart;
private EditText text_x;
private EditText text_y;
private EditText text_shux;
private EditText text_shuy;
private EditText text_f;
private EditText text_jie;
private Button btn_start;
@SuppressLint("MissingInflatedId")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 设置布局文件
setContentView(R.layout.activity_main);
// 从布局文件中获取 LineChart 控件
chart = findViewById(R.id.chart);
// 设置图表可拖动,但不可缩放,并去掉图表的描述
chart.setDragEnabled(true);
chart.setScaleEnabled(false);
chart.setDescription(null);
// 获取 X 轴并设置其位置在底部,同时关闭网格线的显示
XAxis xAxis = chart.getXAxis();
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setDrawGridLines(true);
// 获取左侧的 Y 轴并显示网格线
YAxis leftAxis = chart.getAxisLeft();
leftAxis.setDrawGridLines(true);
// 获取右侧的 Y 轴并禁用它
YAxis rightAxis = chart.getAxisRight();
rightAxis.setEnabled(false);
//接入
text_x = findViewById(R.id.text_x);
text_y = findViewById(R.id.text_y);
text_shux = findViewById(R.id.text_shux);
text_shuy = findViewById(R.id.text_shuy);
text_f = findViewById(R.id.text_f);
text_jie = findViewById(R.id.text_jie);
btn_start = findViewById(R.id.btn_start);
ArrayList values = new ArrayList<>();
btn_start.setOnClickListener(v -> {
String fu=text_f.getText().toString();
// Toast.makeText(this,fu,Toast.LENGTH_SHORT).show();
int shux=Integer.parseInt(text_shux.getText().toString());
int shuy=Integer.parseInt(text_shuy.getText().toString());
int jie=Integer.parseInt(text_jie.getText().toString());
if(fu.equals("+")){
Toast.makeText(this,"click+",Toast.LENGTH_SHORT).show();
for (int i = -20; i < 21; i++) {
// float val = (float) (Math.random() * 30); // 随机生成温度
float y= (float) (jie - shux * i) /shuy;
values.add(new Entry(i, y));
}
LineDataSet set1 = new LineDataSet(values, "data");
// 设置数据集的依赖轴、颜色、值的文字颜色和线宽
set1.setAxisDependency(YAxis.AxisDependency.LEFT);
set1.setColor(Color.BLUE);
set1.setValueTextColor(Color.RED);
set1.setLineWidth(2f);
//开启高亮线下部分填充
// set1.setDrawFilled(true);
// set1.setFillAlpha(10);//透明度
// set1.setFillColor(Color.RED);//填充颜色
// 设置高亮线颜色,关闭绘制圆点和值
set1.setHighLightColor(Color.rgb(244, 117, 117));
set1.setDrawCircles(false);
set1.setDrawValues(false);
// 设置线条为三次贝塞尔曲线
set1.setMode(LineDataSet.Mode.CUBIC_BEZIER);
// 使用数据集创建 LineData 对象
LineData data = new LineData(set1);
// 将 LineData 设置给图表
chart.setData(data);
// 设置图表默认显示的 x 范围和初始位置
chart.setVisibleXRangeMaximum(10);
chart.moveViewToX(0);
// 允许高亮线-指示器
chart.setHighlightPerDragEnabled(true);
// 设置图表数据后调用自定义的 moveHighlight() 方法
chart.setData(data);
moveHighlight();
} else if (fu.equals("-")) {
Toast.makeText(this,"click-",Toast.LENGTH_SHORT).show();
for (int i = -20; i < 21; i++) {
// float val = (float) (Math.random() * 30); // 随机生成温度
float y= (float) (shux * i-jie) /shuy;
values.add(new Entry(i, y));
}
LineDataSet set1 = new LineDataSet(values, "data");
// 设置数据集的依赖轴、颜色、值的文字颜色和线宽
set1.setAxisDependency(YAxis.AxisDependency.LEFT);
set1.setColor(Color.RED);
set1.setValueTextColor(Color.RED);
set1.setLineWidth(2f);
//开启高亮线下部分填充
// set1.setDrawFilled(true);
// set1.setFillAlpha(10);//透明度
// set1.setFillColor(Color.RED);//填充颜色
// 设置高亮线颜色,关闭绘制圆点和值
set1.setHighLightColor(Color.rgb(244, 117, 117));
set1.setDrawCircles(false);
set1.setDrawValues(false);
// 设置线条为三次贝塞尔曲线
set1.setMode(LineDataSet.Mode.CUBIC_BEZIER);
// 使用数据集创建 LineData 对象
LineData data = new LineData(set1);
// 将 LineData 设置给图表
chart.setData(data);
// 设置图表默认显示的 x 范围和初始位置
chart.setVisibleXRangeMaximum(10);
chart.moveViewToX(0);
// 允许高亮线-指示器
chart.setHighlightPerDragEnabled(true);
// 设置图表数据后调用自定义的 moveHighlight() 方法
chart.setData(data);
moveHighlight();
}//
});
// 假设有24个数据点,每个代表一小时
// for (int i = 0; i < 24; i++) {
// float val = (float) (Math.random() * 30); // 随机生成温度
// values.add(new Entry(i, val));
// }
// 使用数据点集合创建 LineDataSet 对象,表示温度数据集
// LineDataSet set1 = new LineDataSet(values, "data");
//
// // 设置数据集的依赖轴、颜色、值的文字颜色和线宽
// set1.setAxisDependency(YAxis.AxisDependency.LEFT);
// set1.setColor(Color.RED);
// set1.setValueTextColor(Color.RED);
// set1.setLineWidth(2f);
//
// //开启高亮线下部分填充
// set1.setDrawFilled(true);
// set1.setFillAlpha(10);//透明度
// set1.setFillColor(Color.RED);//填充颜色
//
//
// // 设置高亮线颜色,关闭绘制圆点和值
// set1.setHighLightColor(Color.rgb(244, 117, 117));
// set1.setDrawCircles(false);
// set1.setDrawValues(false);
//
// // 设置线条为三次贝塞尔曲线
// set1.setMode(LineDataSet.Mode.CUBIC_BEZIER);
//
// // 使用数据集创建 LineData 对象
// LineData data = new LineData(set1);
//
// // 将 LineData 设置给图表
// chart.setData(data);
//
// // 设置图表默认显示的 x 范围和初始位置
// chart.setVisibleXRangeMaximum(6);
// chart.moveViewToX(10);
//
// // 允许高亮线-指示器
// chart.setHighlightPerDragEnabled(true);
//
// // 设置图表数据后调用自定义的 moveHighlight() 方法
// chart.setData(data);
// moveHighlight();
// 设置图表手势监听器
chart.setOnChartGestureListener(new OnChartGestureListener() {
@Override
public void onChartGestureStart(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
// 当图表手势开始时调用
// 无需实现此方法,因为我们在此应用中不需要处理图表手势开始的事件
}
@Override
public void onChartGestureEnd(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
// 当图表手势结束时调用
// 无需实现此方法,因为我们在此应用中不需要处理图表手势结束的事件
}
@Override
public void onChartLongPressed(MotionEvent me) {
// 当用户长按图表时调用
// 无需实现此方法,因为我们在此应用中不需要处理长按事件
}
@Override
public void onChartDoubleTapped(MotionEvent me) {
// 当用户双击图表时调用
// 无需实现此方法,因为我们在此应用中不需要处理双击事件
}
@Override
public void onChartSingleTapped(MotionEvent me) {
// 当用户单击图表时调用
// 无需实现此方法,因为我们在此应用中不需要处理单击事件
}
@Override
public void onChartFling(MotionEvent me1, MotionEvent me2, float velocityX, float velocityY) {
// 当用户用快速滑动手势在图表上进行滑动时调用
// 无需实现此方法,因为我们在此应用中不需要处理滑动事件
}
@Override
public void onChartScale(MotionEvent me, float scaleX, float scaleY) {
// 当图表缩放时调用
// 在缩放时更新指示器的位置
// moveHighlight();
}
@Override
public void onChartTranslate(MotionEvent me, float dX, float dY) {
// 当图表平移时调用
// 在平移时更新指示器的位置
// moveHighlight();
}
});
// 启用绘制 MarkerView,并设置自定义的 MarkerView
chart.setDrawMarkers(true);
MarkerView mv = new CustomMarkerView(this, R.layout.marker_view);
mv.setChartView(chart);
chart.setMarker(mv);
}
// 一个自定义方法来移动高亮指示器到当前视图的中心位置
private void moveHighlight() {
// 获取当前可见区域最低的 X 值
float lowestVisibleX =-20;
// 获取当前可见区域最高的 X 值
float highestVisibleX = 20;
float VisibleChartWidth = chart.getHighestVisibleX() - chart.getLowestVisibleX();
//获取图表的总长度
float totalChartWidth = chart.getXChartMax() - chart.getXChartMin();
// 计算中心位置的 X 值
float x = lowestVisibleX + lowestVisibleX * (VisibleChartWidth / (totalChartWidth - VisibleChartWidth));
// 创建一个高亮对象,指定 X、Y、以及数据集索引
Highlight highlight = new Highlight(x, 0, 0);
// 将高亮设置到图表上,并刷新图表
chart.highlightValue(highlight, true);
chart.invalidate(); // 刷新图表
}
}
/layout/activity_main.xml
/layout/marker_view.xml