MPAndroidChart的详细使用——坐标轴(X轴、Y轴、零线)

画图表常用的坐标轴(X轴、Y轴)属性来了~

上一篇:MPAndroidChart的详细使用——高亮
下一篇:MPAndroidChart的详细使用——设置数据
前面这些都是X轴和Y轴都具备的属性,后面有一点点是X轴或者Y轴的特性。

开启 / 关闭 对于轴上某部分的控制
setEnabled(boolean enabled)开启或关闭轴。如果禁用,则不管其他设置如何,都不会绘制轴(X、Y轴)。
setDrawLabels(boolean enabled)是否绘制坐标值。
setDrawAxisLine(boolean enabled)是否绘制坐标线。
setDrawGridLines(boolean enabled)是否绘制轴的网格线。
自定义轴范围(最小/最大)
setAxisMaximum(float max)设置此轴的自定义最大值。
resetAxisMaximum()撤消(删除)设置的最大值。
setAxisMinimum(float min)设置此轴的自定义最小值。
resetAxisMinimum()撤消(删除)设置的最小值
setInverted(boolean enabled)是否将轴反转(最高的值将在底部,最低的值在顶部)
setSpaceTop(float percent)设置图表中最高值的顶部间距(占总轴范围的百分比),与轴上的最高值相比。
setSpaceBottom(float percent)将图表中最低值的底部间距(以总轴范围的百分比)与轴上的最低值相比较。
setShowOnlyMinMax(boolean enabled)如果启用,此轴将只显示它的最小值和最大值。这将覆盖定义的标签计数(如果不是强制的话)。
setLabelCount(int count, boolean force)设置y轴的标签数。请注意,这个数字不是固定的(如果force==false),并且只能近似。如果启用了强制(True),则会绘制精确的标签计数–这会导致轴上的不均匀数字。
setPosition(YAxisLabelPosition pos)设置绘制轴标签的位置。内部图表或外部图表。
setGranularity(float gran)设置y轴值之间的最小间隔。这可用于避免在缩放到为轴设置的小数数不再允许区分两个轴值时重复值。
setGranularityEnabled(boolean enabled)启用粒度特性,在缩放时限制y轴的间隔。默认值:false
自定义轴的样式
setTextColor(int color)设置轴标签的颜色。
setTextSize(float size)在dp中设置轴标签的文本大小。
setTypeface(Typeface tf)建立一个习惯Typeface轴心标签。
setGridColor(int color)设置此轴的网格线的颜色。
setGridLineWidth(float width)设置此轴的网格线的宽度。
setAxisLineColor(int color)设置此轴的轴线的颜色。
setAxisLineWidth(float width)设置此轴的轴线的宽度。
enableGridDashedLine(float lineLength, float spaceLength, float phase)允许以虚线方式绘制网格线,例如:“-”。“lineLength”控制行段的长度,“spaceLength”控制行之间的空间,“phase”控制起始点。
格式化坐标轴

可以使用ValueFormatter类来格式化轴值。

极限线

边界线和约束线都是极限线,用来显示特殊信息,如边界或约束。极限线在Y轴对象时以水平方向绘制,在X轴对象时以垂直方向绘制。

addLimitLine(LimitLine l)增加一个新的LimitLine到这个轴。
removeLimitLine(LimitLine l)移除指定的LimitLine从这个轴。
setDrawLimitLinesBehindData(boolean enabled)是否允许控制极限线和实际数据的顺序。如果此值设置为true,则极限线绘制在实际数据后面,否则绘制在前面。默认值:false
下面是一个实例:
图表可能会显示用户在应用程序中记录的各种血压测量结果。为了告知使用者收缩压超过140 mmHg被认为是健康风险,您可以添加LimitLine以提供这方面的资料。
YAxis leftAxis = chart.getAxisLeft();

LimitLine ll = new LimitLine(140f, "高血压界定线");
ll.setLineColor(Color.RED);
ll.setLineWidth(4f);
ll.setTextColor(Color.BLACK);
ll.setTextSize(12f);
// .. 更多的样式设置

leftAxis.addLimitLine(ll);
X轴的特性
//实例化X轴对象进行使用
XAxis xAxis = chart.getXAxis();
//设置X轴位置 有以下几种   TOP   BOTTOM   BOTH_SIDED   TOP_INSIDE    BOTTOM_INSIDE
xAxis.setPosition(XAxisPosition.BOTTOM);
//设置X轴标签数据绘制的角度   也就是X轴上数据标签的旋转角度
xAxis.setLabelRotationAngle(90)
xAxis.setTextSize(10f);
xAxis.setTextColor(Color.RED);
xAxis.setDrawAxisLine(true);
xAxis.setDrawGridLines(false);
// 自定义X轴上的数据格式
xAxis.setValueFormatter(new MyCustomFormatter());
Y轴的特性
YAxis leftAxis = chart.getAxisLeft();
YAxis rightAxis = chart.getAxisRight();

YAxis leftAxis = chart.getAxis(AxisDependency.LEFT);
YAxis rightAxis = chart.getAxis(AxisDependency.RIGHT);

// 雷达图获取YAxis方法  由于雷达图只有一个Y轴(其他图有两个),所以有独特的方法
YAxis yAxis = radarChart.getYAxis(); 
Y轴的统一性

在没有定义一边的情况下,图表上的两条Y轴数据以及样式比例都是一样的,如果想把两边的Y轴设置成不一样的比例,可以通过设置数据对应的轴来实现这一点,通过更改DataSet的AxisDependency来实现

LineDataSet dataSet = ...;
dataSet.setAxisDependency(AxisDependency.RIGHT);
Y轴上的零线

除了网格线之外,在Y轴,有零线,它在轴上的零(0)值处,类似于网格线,但可以单独配置。

setDrawZeroLine(boolean enabled)启用/禁用绘制零线。
setZeroLineWidth(float width)设置零行的线宽。
setZeroLineColor(int color)设置零行的颜色。

实例代码:

// 数据在左边的Y轴
YAxis left = mChart.getAxisLeft();//实例化Y轴对象
left.setDrawLabels(false); // 不设置坐标轴数据标签
left.setDrawAxisLine(false); // 不绘制坐标轴线
left.setDrawGridLines(false); // 不绘制网格线
left.setDrawZeroLine(true); // 绘制零线
mChart.getAxisRight().setEnabled(false); // 不绘制右边Y轴

更多实例代码:

YAxis yAxis = mChart.getAxisLeft();//实例化Y轴对象
yAxis.setTypeface(...); // 设置Y轴上数据的字体
yAxis.setTextSize(12f); // 设置Y轴上数据字体大小
yAxis.setAxisMinimum(0f); // 设置Y轴最小值为0
yAxis.setAxisMaximum(100f); // 设置Y轴最大值为100
yAxis.setTextColor(Color.BLACK); // 设置字体颜色
yAxis.setValueFormatter(new MyValueFormatter());//设置Y轴数据显示格式
yAxis.setGranularity(1f); // 设置间隔为1
yAxis.setLabelCount(6, true); // 强制设置标签个数
  • 8
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
esp8266 语音播放 //Priorities of the reader and the decoder thread. Higher = higher prio. #define PRIO_READER 11 #define PRIO_MAD 1 //The mp3 read buffer size. 2106 bytes should be enough for up to 48KHz mp3s according to the sox sources. Used by libmad. #define READBUFSZ (2106) static char readBuf[READBUFSZ]; static long bufUnderrunCt; //Reformat the 16-bit mono sample to a format we can send to I2S. static int sampToI2s(short s) { //We can send a 32-bit sample to the I2S subsystem and the DAC will neatly split it up in 2 //16-bit analog values, one for left and one for right. //Duplicate 16-bit sample to both the L and R channel int samp=s; samp=(samp)&0xffff; samp=(samp<65535) samp=65535; if (samp>11]; err=(samp&0x7ff); //Save rounding error. return samp; } //2nd order delta-sigma DAC //See http://www.beis.de/Elektronik/DeltaSigma/DeltaSigma.html for a nice explanation static int sampToI2sDeltaSigma(short s) { int x; int val=0; int w; static int i1v=0, i2v=0; static int outReg=0; for (x=0; x<32; x++) { val<0) w-=32767; else w+=32767; //Difference 1 w+=i1v; i1v=w; //Integrator 1 if (outReg>0) w-=32767; else w+=32767; //Difference 2 w+=i2v; i2v=w; //Integrator 2 outReg=w; //register if (w>0) val|=1; //comparator } return val; } //Calculate the number of samples that we add or delete. Added samples means a slightly lower //playback rate, deleted samples means we increase playout speed a bit. This returns an //8.24 fixed-point number int recalcAddDelSamp(int oldVal) { int ret; long prevUdr=0; static int cnt; int i; static int minFifoFill=0; i=spiRamFifoFill(); if (i<minFifoFill) minFifoFill=i; //Do the rest of the calculations plusminus every 100mS (assuming a sample rate of 44KHz) cnt++; if (cnt<1500) return oldVal; cnt=0; if (spiRamFifoLen()<10*1024) { //The FIFO is very small. We can't do calculations on how much it's filled on average, so another //algorithm is called for. int tgt=1600; //we want an average of this amount of bytes as the average minimum buffer fill //Calculate underruns this cycle int udr=spiRamGetUnderrunCt()-prevUdr; //If we have underruns, the minimum buffer fill has been lower than 0. if (udr!=0) minFifoFill=-1; //If we're below our target decrease playback speed, and vice-versa. ret=oldVal+((minFifoFill-tgt)*ADD_DEL_BUFFPERSAMP_NOSPIRAM); prevUdr+=udr; minFifoFill=9999; } else { //We have a larger FIFO; we can adjust according to the FIFO fill rate. int tgt=spiRamFifoLen()/2; ret=(spiRamFifoFill()-tgt)*ADD_DEL_BUFFPERSAMP; } return ret; } //This routine is called by the NXP modifications of libmad. It passes us (for the mono synth) //32 16-bit samples. void render_sample_block(short *short_sample_buff, int no_samples) { //Signed 16.16 fixed point number: the amount of samples we need to add or delete //in every 32-sample static int sampAddDel=0; //Remainder of sampAddDel cumulatives static int sampErr=0; int i; int samp; #ifdef ADD_DEL_SAMPLES sampAddDel=recalcAddDelSamp(sampAddDel); #endif sampErr+=sampAddDel; for (i=0; i(1<<24)) { sampErr-=(1<<24); //...and don't output an i2s sample } else if (sampErr<-(1<<24)) { sampErr+=(1<bufend-stream->next_frame; memmove(readBuf, stream->next_frame, rem); while (rem<sizeof(readBuf)) { n=(sizeof(readBuf)-rem); //Calculate amount of bytes we need to fill buffer. i=spiRamFifoFill(); if (i<n) n=i; //If the fifo can give us less, only take that amount if (n==0) { //Can't take anything? //Wait until there is enough data in the buffer. This only happens when the data feed //rate is too low, and shouldn't normally be needed! // printf("Buf uflow, need %d bytes.\n", sizeof(readBuf)-rem); bufUnderrunCt++; //We both silence the output as well as wait a while by pushing silent samples into the i2s system. //This waits for about 200mS for (n=0; nerror, mad_stream_errorstr(stream)); return MAD_FLOW_CONTINUE; } //This is the main mp3 decoding task. It will grab data from the input buffer FIFO in the SPI ram and //output it to the I2S port. void ICACHE_FLASH_ATTR tskmad(void *pvParameters) { int r; struct mad_stream *stream; struct mad_frame *frame; struct mad_synth *synth; //Allocate structs needed for mp3 decoding stream=malloc(sizeof(struct mad_stream)); frame=malloc(sizeof(struct mad_frame)); synth=malloc(sizeof(struct mad_synth)); if (stream==NULL) { printf("MAD: malloc(stream) failed\n"); return; } if (synth==NULL) { printf("MAD: malloc(synth) failed\n"); return; } if (frame==NULL) { printf("MAD: malloc(frame) failed\n"); return; } //Initialize I2S i2sInit(); bufUnderrunCt=0; printf("MAD: Decoder start.\n"); //Initialize mp3 parts mad_stream_init(stream); mad_frame_init(frame); mad_synth_init(synth); while(1) { input(stream); //calls mad_stream_buffer internally while(1) { r=mad_frame_decode(frame, stream); if (r==-1) { if (!MAD_RECOVERABLE(stream->error)) { //We're most likely out of buffer and need to call input() again break; } error(NULL, stream, frame); continue; } mad_synth_frame(synth, frame); } } } int getIpForHost(const char *host, struct sockaddr_in *ip) { struct hostent *he; struct in_addr **addr_list; he=gethostbyname(host); if (he==NULL) return 0; addr_list=(struct in_addr **)he->h_addr_list; if (addr_list[0]==NULL) return 0; ip->sin_family=AF_INET; memcpy(&ip->sin_addr, addr_list[0], sizeof(ip->sin_addr)); return 1; } //Open a connection to a webserver and request an URL. Yes, this possibly is one of the worst ways to do this, //but RAM is at a premium here, and this works for most of the cases. int ICACHE_FLASH_ATTR openConn(const char *streamHost, const char *streamPath) { int n, i; while(1) { struct sockaddr_in remote_ip; bzero(&remote_ip, sizeof(struct sockaddr_in)); if (!getIpForHost(streamHost, &remote_ip)) { vTaskDelay(1000/portTICK_RATE_MS); continue; } int sock=socket(PF_INET, SOCK_STREAM, 0); if (sock==-1) { continue; } remote_ip.sin_port = htons(streamPort); printf("Connecting to server %s...\n", ipaddr_ntoa((const ip_addr_t*)&remote_ip.sin_addr.s_addr)); if (connect(sock, (struct sockaddr *)(&remote_ip), sizeof(struct sockaddr))!=00) { close(sock); printf("Conn err.\n"); vTaskDelay(1000/portTICK_RATE_MS); continue; } //Cobble together HTTP request write(sock, "GET ", 4); write(sock, streamPath, strlen(streamPath)); write(sock, " HTTP/1.0\r\nHost: ", 17); write(sock, streamHost, strlen(streamHost)); write(sock, "\r\n\r\n", 4); //We ignore the headers that the server sends back... it's pretty dirty in general to do that, //but it works here because the MP3 decoder skips it because it isn't valid MP3 data. return sock; } } //Reader task. This will try to read data from a TCP socket into the SPI fifo buffer. void ICACHE_FLASH_ATTR tskreader(void *pvParameters) { int madRunning=0; char wbuf[64]; int n, l, inBuf; int t; int fd; int c=0; while(1) { fd=openConn(streamHost, streamPath); printf("Reading into SPI RAM FIFO...\n"); do { n=read(fd, wbuf, sizeof(wbuf)); if (n>0) spiRamFifoWrite(wbuf, n); c+=n; if ((!madRunning) && (spiRamFifoFree()0); close(fd); printf("Connection closed.\n"); } } //Simple task to connect to an access point, initialize i2s and fire up the reader task. void ICACHE_FLASH_ATTR tskconnect(void *pvParameters) { //Wait a few secs for the stack to settle down vTaskDelay(3000/portTICK_RATE_MS); //Go to station mode wifi_station_disconnect(); if (wifi_get_opmode() != STATION_MODE) { wifi_set_opmode(STATION_MODE); } //Connect to the defined access point. struct station_config *config=malloc(sizeof(struct station_config)); memset(config, 0x00, sizeof(struct station_config)); sprintf(config->ssid, AP_NAME); sprintf(config->password, AP_PASS); wifi_station_set_config(config); wifi_station_connect(); free(config); //Fire up the reader task. The reader task will fire up the MP3 decoder as soon //as it has read enough MP3 data. if (xTaskCreate(tskreader, "tskreader", 230, NULL, PRIO_READER, NULL)!=pdPASS) printf("Error creating reader task!\n"); //We're done. Delete this task. vTaskDelete(NULL); } //We need this to tell the OS we're running at a higher clock frequency. extern void os_update_cpu_frequency(int mhz); void ICACHE_FLASH_ATTR user_init(void) { //Tell hardware to run at 160MHz instead of 80MHz //This actually is not needed in normal situations... the hardware is quick enough to do //MP3 decoding at 80MHz. It, however, seems to help with receiving data over long and/or unstable //links, so you may want to turn it on. Also, the delta-sigma code seems to need a bit more speed //than the other solutions to keep up with the output samples, so it's also enabled there. #if defined(DELTA_SIGMA_HACK) SET_PERI_REG_MASK(0x3ff00014, BIT(0)); os_update_cpu_frequency(160); #endif //Set the UART to 115200 baud UART_SetBaudrate(0, 115200); //Initialize the SPI RAM chip communications and see if it actually retains some bytes. If it //doesn't, warn user. if (!spiRamFifoInit()) { printf("\n\nSPI RAM chip fail!\n"); while(1); } printf("\n\nHardware initialized. Waiting for network.\n"); xTaskCreate(tskconnect, "tskconnect", 200, NULL, 3, NULL); }
### 回答1: 使用 mpandroidchart 库可以通过调用 `XAxis.setGranularity(float granularity)` 方法来设置 x 坐标间隔。参数 granularity 是间隔大小,可以是浮数。例如,设置间隔为 2,可以使用 `xAxis.setGranularity(2f)`。 ### 回答2: MPAndroidChart是一款强大的Android图表库,用于创建各种类型的图表,包括折线图、柱状图、饼图等。要设置x坐标间隔,需要通过设置X标签格式化程序(XAxisValueFormatter)来实现。 首先,我们需要获取X对象,可以通过Chart对象的getXAxis()方法来获取。然后,通过调用XAxis对象的setLabelCount()方法,可以设置x坐标间隔的数量。例如,如果想设置每隔2个值显示一个坐标标签,可以调用setLabelCount(2, true)方法。 然而,有时设置坐标间隔的数量并不足以满足我们的需求。例如,当我们的数据集非常庞大时,坐标标签可能会重叠在一起,变得难以阅读。为了解决这个问题,我们可以创建一个自定义的XAxisValueFormatter,通过对坐标标签进行格式化来显示我们想要的信息。 要创建一个自定义的XAxisValueFormatter,我们需要实现XAxisValueFormatter接口,并重写getFormattedValue(float value, AxisBase axis)方法。在这个方法中,我们可以根据value的值来确定我们需要显示的坐标标签。例如,我们可以将value乘以10,并返回一个字符串类型的结果。 最后,我们将自定义的XAxisValueFormatter设置给X对象,通过调用XAxis对象的setValueFormatter()方法来实现。这样,图表将按照我们设置的坐标标签格式进行展示。 总之,通过设置X标签格式化程序,我们可以自定义和控制MPAndroidChart中x坐标的间隔。 ### 回答3: 在使用MPAndroidChart库中设置X坐标间隔的方法是使用`XAxis`类的`setLabelCount`方法。 首先,通过`LineChart`或者`BarChart`等图表对象的`getXAxis()`方法获取X对象,例如:`XAxis xAxis = chart.getXAxis();` 然后,通过调用`xAxis.setLabelCount(int count)`方法,传入一个整数值作为参数,该整数值表示希望显示的X标签的数量。 如果希望固定显示特定数量的标签,可以直接设置标签数量为指定值,例如:`xAxis.setLabelCount(5);` 表示固定显示5个X标签。 还可以根据数据集的数量来动态计算标签显示数量,例如:`xAxis.setLabelCount(dataSet.getEntryCount());` 表示根据数据集数量来决定显示多少个X标签。 此外,默认情况下,MPAndroidChart库会自动计算并平均分配X标签的位置和间隔,如果需要自定义X标签的间隔可以使用`setSpaceBetweenLabels(int space)`方法,设置希望的间隔数值即可。 总结起来,使用`XAxis`类的`setLabelCount`方法可以设置X坐标间隔的显示数量,使用`setSpaceBetweenLabels`方法可以自定义X标签的间隔。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值