原文:一款天气app的温度曲线图的实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tyhzsd/article/details/50544639
最近在开发一款天气app,有一个功能是显示当天24小时每三个小时的气温状况,这个功能无疑要用图表来实现最好了。所以在github上找到一个国人开发的图表库,XCL-Charts。
先上效果图:



首先创建一个SplineChartView继承自GraphicalView,再主要实现三个方法

第一个是关于图表的渲染

private void chartRender()

{

try {

        //设置绘图区默认缩进px值,留置空间显示Axis,Axistitle....
int [] ltrb = getBarLnDefaultSpadding();
chart.setPadding(ltrb[0] + DensityUtil.dip2px(this.getContext(), 20), ltrb[1],
ltrb[2]+DensityUtil.dip2px(this.getContext(), 30), ltrb[3]); //显示边框
chart.showRoundBorder(); //数据源
chart.setCategories(labels);
chart.setDataSource(chartData);
// chart.setCustomLines(mCustomLineDataset); //坐标系
//数据轴最大值
chart.getDataAxis().setAxisMax(40);
chart.getDataAxis().setAxisMin(-40);
//数据轴刻度间隔
chart.getDataAxis().setAxisSteps(2); //标签轴最大值
chart.setCategoryAxisMax(5);
//标签轴最小值
chart.setCategoryAxisMin(0); //背景网格
PlotGrid plot = chart.getPlotGrid();
plot.hideHorizontalLines();
plot.hideVerticalLines(); chart.getPlotArea().setBackgroundColor(true, Color.GRAY); chart.getCategoryAxis().getAxisPaint().setColor(Color.WHITE);
chart.getCategoryAxis().getAxisPaint().setTextSize(6);
chart.getCategoryAxis().hideTickMarks();
chart.getCategoryAxis().getTickLabelPaint().setColor(Color.WHITE);
chart.getCategoryAxis().getTickLabelPaint().setFakeBoldText(true);
chart.getCategoryAxis().setTickLabelMargin(25);
chart.getCategoryAxis().getTickLabelPaint().setTextSize(25); //不使用精确计算,忽略Java计算误差,提高性能
chart.disableHighPrecision(); chart.disablePanMode();
chart.hideBorder();
chart.getPlotLegend().hide();
chart.getDataAxis().hide(); } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e("tag", e.toString());
}
}

其中chart.getPlotArea().setBackgroundColor(true, Color.GRAY);是设置图表绘制区的颜色,chart.getDataAxis().setAxisMax(40);在我的app中表示能显示的最高温度是40摄氏度,chart.getDataAxis().setAxisMin(-40);表示能显示的最低温度是-40摄氏度。

第二个和第三个都是绑定数据的。

public void setChartDataSet(List temps)

{

//线1的数据集

List linePoint1 = new ArrayList();

linePoint1.add(new PointD(0d, Double.parseDouble(temps.get(0))));

linePoint1.add(new PointD(1d, Double.parseDouble(temps.get(1))));

linePoint1.add(new PointD(2d, Double.parseDouble(temps.get(2))));

linePoint1.add(new PointD(3d, Double.parseDouble(temps.get(3))));

linePoint1.add(new PointD(4d, Double.parseDouble(temps.get(4))));

linePoint1.add(new PointD(5d, Double.parseDouble(temps.get(5))));

    SplineData dataSeries1 = new SplineData("Go",linePoint1,
Color.WHITE );
//把线弄细点
dataSeries1.getLinePaint().setStrokeWidth(3);
dataSeries1.setLineStyle(XEnum.LineStyle.DASH);
dataSeries1.setLabelVisible(false);
dataSeries1.setDotStyle(XEnum.DotStyle.RING);
dataSeries1.getDotPaint().setColor(getResources().getColor(R.color.white));
dataSeries1.getPlotLine().getPlotDot().setRingInnerColor(getResources().getColor(R.color.grey)); chartData.add(dataSeries1);
this.invalidate();
} public void setChartLabels(List<String> weather){
String[] times={"20:00\n","23:00\n","2:00\n","5:00\n","8:00\n","11:00\n"};
for(int i=0;i<weather.size();i++){
labels.add(times[i]+weather.get(i));
}
this.invalidate();
}
由于需要动态添加数据,也就是温度,这里我设置了6个时段的温度,每个时段三个小时。在setChartDataSet方法中添加了参数,dataSeries1.getLinePaint().setStrokeWidth(3);设置了绘制曲线的线宽度,dataSeries1.setLineStyle(XEnum.LineStyle.DASH)设置了曲线的类型。setChartLabels(List<String> weather)设置了横轴坐标表示什么意思,在这里表示时段和天气状态。

第四个是图批注

public void setChartAnchor(List<String> temps){
//激活点击监听
chart.ActiveListenItemClick();
//为了让触发更灵敏,可以扩大5px的点击监听范围
chart.extPointClickRange(5);
chart.showClikedFocus(); //批注
List<AnchorDataPoint> mAnchorSet = new ArrayList<AnchorDataPoint>(); AnchorDataPoint an2 = new AnchorDataPoint(0,0,XEnum.AnchorStyle.TOBOTTOM);
an2.setBgColor(Color.WHITE);
an2.setLineWidth(15);
an2.setLineStyle(XEnum.LineStyle.DASH); an2.setTextColor(Color.WHITE);
an2.setTextSize(55);
an2.setAnchor(temps.get(0)); AnchorDataPoint an3 = new AnchorDataPoint(0,1,XEnum.AnchorStyle.TOBOTTOM);
an3.setBgColor(Color.WHITE);
an3.setLineStyle(XEnum.LineStyle.DASH);
an3.setTextColor(Color.WHITE);
an3.setTextSize(55);
an3.setAnchor(temps.get(1)); //从点到底的标识线
//从点到底的标识线
AnchorDataPoint an4 = new AnchorDataPoint(0,2,XEnum.AnchorStyle.TOBOTTOM);
an4.setBgColor(Color.WHITE);
an4.setLineWidth(15);
an4.setLineStyle(XEnum.LineStyle.DASH);
an4.setTextColor(Color.WHITE);
an4.setTextSize(55);
an4.setAnchor(temps.get(2)); AnchorDataPoint an5 = new AnchorDataPoint(0,3,XEnum.AnchorStyle.TOBOTTOM);
an5.setBgColor(Color.WHITE);
an5.setLineWidth(15);
an5.setLineStyle(XEnum.LineStyle.DASH);
an5.setTextColor(Color.WHITE);
an5.setTextSize(55);
an5.setAnchor(temps.get(3)); AnchorDataPoint an6 = new AnchorDataPoint(0,4,XEnum.AnchorStyle.TOBOTTOM);
an6.setBgColor(Color.WHITE);
an6.setLineWidth(15);
an6.setLineStyle(XEnum.LineStyle.DASH);
an6.setTextColor(Color.WHITE);
an6.setTextSize(55);
an6.setAnchor(temps.get(4)); AnchorDataPoint an7 = new AnchorDataPoint(0,5,XEnum.AnchorStyle.TOBOTTOM);
an7.setBgColor(Color.WHITE);
an7.setLineWidth(15);
an7.setLineStyle(XEnum.LineStyle.DASH);
an7.setTextColor(Color.WHITE);
an7.setTextSize(55);
an7.setAnchor(temps.get(5)); mAnchorSet.add(an2);
mAnchorSet.add(an3);
mAnchorSet.add(an4);
mAnchorSet.add(an5);
mAnchorSet.add(an6);
mAnchorSet.add(an7);
chart.setAnchorDataPoint(mAnchorSet); this.invalidate();
}

an2.setBgColor(Color.WHITE);

an2.setLineWidth(15);

an2.setLineStyle(XEnum.LineStyle.DASH);

an2.setTextColor(Color.WHITE);

an2.setTextSize(55);

an2.setAnchor(temps.get(0));

上面第一行依然是设置背景色为白色,第二行是批注线的宽度,第三行是设置批注线为虚线,第四、五行设置了批注文字的颜色和大小,第六行则是将批注文字绑定到an2上。

附上完整代码

package com.example.springweather.customview;

import java.util.ArrayList;

import java.util.LinkedList;

import java.util.List;

import org.xclcharts.chart.PointD;

import org.xclcharts.chart.SplineChart;

import org.xclcharts.chart.SplineData;

import org.xclcharts.common.DensityUtil;

import org.xclcharts.renderer.XEnum;

import org.xclcharts.renderer.info.AnchorDataPoint;

import org.xclcharts.renderer.plot.PlotGrid;

import org.xclcharts.view.ChartView;

import org.xclcharts.view.GraphicalView;

import com.example.springweather.R;

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.util.AttributeSet;

import android.util.Log;

public class SplineChartView extends GraphicalView {

private SplineChart chart = new SplineChart();

//分类轴标签集合

private LinkedList labels = new LinkedList();

private LinkedList chartData = new LinkedList();

Paint pToolTip = new Paint(Paint.ANTI_ALIAS_FLAG);

public SplineChartView(Context context) {
super(context);
// TODO Auto-generated constructor stub
initView();
} public SplineChartView(Context context, AttributeSet attrs){
super(context, attrs);
initView();
} public SplineChartView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView();
} @Override
public void refreshChart() {
super.refreshChart();
labels.clear();
chartData.clear();
} private void initView()
{
List<String> weather=new ArrayList<String>();
for(int i=0;i<6;i++){
weather.add("晴");
}
List<String> temps=new ArrayList<String>();
for(int i=0;i<6;i++){
temps.add("1");
}
setChartLabels(weather);
setChartDataSet(temps);
setChartAnchor(temps); chartRender();
} @Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
//图所占范围大小
chart.setChartRange(w,h);
} protected int[] getBarLnDefaultSpadding()
{
int [] ltrb = new int[4];
ltrb[0] = DensityUtil.dip2px(getContext(), 0); //left
ltrb[1] = DensityUtil.dip2px(getContext(), 0); //top
ltrb[2] = DensityUtil.dip2px(getContext(), 0); //right
ltrb[3] = DensityUtil.dip2px(getContext(), 30); //bottom
return ltrb;
}
private void chartRender()
{
try { //设置绘图区默认缩进px值,留置空间显示Axis,Axistitle....
int [] ltrb = getBarLnDefaultSpadding();
chart.setPadding(ltrb[0] + DensityUtil.dip2px(this.getContext(), 20), ltrb[1],
ltrb[2]+DensityUtil.dip2px(this.getContext(), 30), ltrb[3]); //显示边框
chart.showRoundBorder(); //数据源
chart.setCategories(labels);
chart.setDataSource(chartData);
// chart.setCustomLines(mCustomLineDataset); //坐标系
//数据轴最大值
chart.getDataAxis().setAxisMax(40);
chart.getDataAxis().setAxisMin(-40);
//数据轴刻度间隔
chart.getDataAxis().setAxisSteps(2); //标签轴最大值
chart.setCategoryAxisMax(5);
//标签轴最小值
chart.setCategoryAxisMin(0); //背景网格
PlotGrid plot = chart.getPlotGrid();
plot.hideHorizontalLines();
plot.hideVerticalLines(); chart.getPlotArea().setBackgroundColor(true, Color.GRAY); chart.getCategoryAxis().getAxisPaint().setColor(Color.WHITE);
chart.getCategoryAxis().getAxisPaint().setTextSize(6);
chart.getCategoryAxis().hideTickMarks();
chart.getCategoryAxis().getTickLabelPaint().setColor(Color.WHITE);
chart.getCategoryAxis().getTickLabelPaint().setFakeBoldText(true);
chart.getCategoryAxis().setTickLabelMargin(25);
chart.getCategoryAxis().getTickLabelPaint().setTextSize(25); //不使用精确计算,忽略Java计算误差,提高性能
chart.disableHighPrecision(); chart.disablePanMode();
chart.hideBorder();
chart.getPlotLegend().hide();
chart.getDataAxis().hide(); } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e("tag", e.toString());
}
} public void setChartDataSet(List<String> temps)
{
//线1的数据集
List<PointD> linePoint1 = new ArrayList<PointD>();
linePoint1.add(new PointD(0d, Double.parseDouble(temps.get(0))));
linePoint1.add(new PointD(1d, Double.parseDouble(temps.get(1))));
linePoint1.add(new PointD(2d, Double.parseDouble(temps.get(2))));
linePoint1.add(new PointD(3d, Double.parseDouble(temps.get(3))));
linePoint1.add(new PointD(4d, Double.parseDouble(temps.get(4))));
linePoint1.add(new PointD(5d, Double.parseDouble(temps.get(5)))); SplineData dataSeries1 = new SplineData("Go",linePoint1,
Color.WHITE );
//把线弄细点
dataSeries1.getLinePaint().setStrokeWidth(3);
dataSeries1.setLineStyle(XEnum.LineStyle.DASH);
dataSeries1.setLabelVisible(false);
dataSeries1.setDotStyle(XEnum.DotStyle.RING);
dataSeries1.getDotPaint().setColor(getResources().getColor(R.color.white));
dataSeries1.getPlotLine().getPlotDot().setRingInnerColor(getResources().getColor(R.color.grey)); chartData.add(dataSeries1);
this.invalidate();
} public void setChartLabels(List<String> weather){
String[] times={"20:00\n","23:00\n","2:00\n","5:00\n","8:00\n","11:00\n"};
for(int i=0;i<weather.size();i++){
labels.add(times[i]+weather.get(i));
}
this.invalidate();
} public void setChartAnchor(List<String> temps){
//激活点击监听
chart.ActiveListenItemClick();
//为了让触发更灵敏,可以扩大5px的点击监听范围
chart.extPointClickRange(5);
chart.showClikedFocus(); //批注
List<AnchorDataPoint> mAnchorSet = new ArrayList<AnchorDataPoint>(); AnchorDataPoint an2 = new AnchorDataPoint(0,0,XEnum.AnchorStyle.TOBOTTOM);
an2.setBgColor(Color.WHITE);
an2.setLineWidth(15);
an2.setLineStyle(XEnum.LineStyle.DASH); an2.setTextColor(Color.WHITE);
an2.setTextSize(55);
an2.setAnchor(temps.get(0)); AnchorDataPoint an3 = new AnchorDataPoint(0,1,XEnum.AnchorStyle.TOBOTTOM);
an3.setBgColor(Color.WHITE);
an3.setLineStyle(XEnum.LineStyle.DASH);
an3.setTextColor(Color.WHITE);
an3.setTextSize(55);
an3.setAnchor(temps.get(1)); //从点到底的标识线
//从点到底的标识线
AnchorDataPoint an4 = new AnchorDataPoint(0,2,XEnum.AnchorStyle.TOBOTTOM);
an4.setBgColor(Color.WHITE);
an4.setLineWidth(15);
an4.setLineStyle(XEnum.LineStyle.DASH);
an4.setTextColor(Color.WHITE);
an4.setTextSize(55);
an4.setAnchor(temps.get(2)); AnchorDataPoint an5 = new AnchorDataPoint(0,3,XEnum.AnchorStyle.TOBOTTOM);
an5.setBgColor(Color.WHITE);
an5.setLineWidth(15);
an5.setLineStyle(XEnum.LineStyle.DASH);
an5.setTextColor(Color.WHITE);
an5.setTextSize(55);
an5.setAnchor(temps.get(3)); AnchorDataPoint an6 = new AnchorDataPoint(0,4,XEnum.AnchorStyle.TOBOTTOM);
an6.setBgColor(Color.WHITE);
an6.setLineWidth(15);
an6.setLineStyle(XEnum.LineStyle.DASH);
an6.setTextColor(Color.WHITE);
an6.setTextSize(55);
an6.setAnchor(temps.get(4)); AnchorDataPoint an7 = new AnchorDataPoint(0,5,XEnum.AnchorStyle.TOBOTTOM);
an7.setBgColor(Color.WHITE);
an7.setLineWidth(15);
an7.setLineStyle(XEnum.LineStyle.DASH);
an7.setTextColor(Color.WHITE);
an7.setTextSize(55);
an7.setAnchor(temps.get(5)); mAnchorSet.add(an2);
mAnchorSet.add(an3);
mAnchorSet.add(an4);
mAnchorSet.add(an5);
mAnchorSet.add(an6);
mAnchorSet.add(an7);
chart.setAnchorDataPoint(mAnchorSet); this.invalidate();
} @Override
public void render(Canvas canvas) {
try{
canvas.drawColor(Color.GRAY);
chart.render(canvas);
} catch (Exception e){
Log.e("tag", e.toString());
}
}

}

一款天气app的温度曲线图的实现的更多相关文章

  1. 推荐一款移动端天气App即刻天气

    推荐一款移动端天气App即刻天气 一 应用描述 即刻天气预报是一个提供全国各城市15日天气预报和空气质量的APP,包含全国3000个城市天气预报,3万个乡镇天气,15日及48小时空气质量预报,是万千用 ...

  2. 用Swift实现一款天气预报APP(二)

    这个系列的目录: 用Swift实现一款天气预报APP(一) 用Swift实现一款天气预报APP(二) 用Swift实现一款天气预报APP(三) 上篇中主要讲了界面的一些内容,这篇主要讨论网络请求,获得 ...

  3. 用Swift实现一款天气预报APP(一)

    这个系列的目录: 用Swift实现一款天气预报APP(一) 用Swift实现一款天气预报APP(二) 用Swift实现一款天气预报APP(三) Swift作为现在苹果极力推广的语言,发展的非常快.这个 ...

  4. DB天气app冲刺第六天

    更改计划 以前是准备完全自己写一个天气App 而且加上自己已经成功的做了一个安卓开发的小例子了,就感觉可以做的出来了.结果这五天证明自己一开始的思路就错了.所以上次跟别的同学问了一下.看了一下他们的方 ...

  5. 【酷我天气】完整的天气App项目

    本人完全自主设计与开发的一款轻量级简约好用的天气App,无广告,无烦人的通知栏信息,定位精准,天气信息数据准确,还支持更换背景皮肤哦,颜值爆表. 实现的功能: 1自动定位:自动获取用户所在的城市位置然 ...

  6. 用Swift实现一款天气预报APP(三)

    这个系列的目录: 用Swift实现一款天气预报APP(一) 用Swift实现一款天气预报APP(二) 用Swift实现一款天气预报APP(三) 通过前面的学习,一个天气预报的APP已经基本可用了.至少 ...

  7. 【总结整理】自带天气app,为什么还要下载

    很简单那就说明用户对天气这个功能的需求并没有表面那么简单呗,还有更深层次的需求~ 先声明我自己是没有这方面需求的,我就纯属YY一下 既然数据都一样的话,那是什么让用户觉得天气APP更专业呢? 1.历史 ...

  8. 个人开发者做一款Android App需要知道的事情

    个人开发者做一款Android App需要知道的事情 在大学时, 自己是学计算机专业的,而且还和老师一起做过一年半的项目. 有时候是不是有这样的想法,做一个自己的网站.但一直未付诸行动.2012年时, ...

  9. 利用react native创建一个天气APP

    我们将构建一个实列程序:天气App,(你可以在react native 中创建一个天气应用项目),我们将学习使用并结合可定义模板(stylesheets).盒式布局(flexbox).网络通信.用户输 ...

随机推荐

  1. TEMPDB

    TEMPDB暴涨 阅读目录 前言 正文 原因 解决 补充 回到顶部 前言   tempdb暴增,造成磁盘空间不足,甚至影响业务运行.     回到顶部 正文   如图,tempdb log文件从7.4 ...

  2. 【50.26%】【hdu 5907】Find Q

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/131072 K (Java/Others) 问题描述 Byteasar迷恋上了 ...

  3. 浅谈java中异常抛出后代码是否会继续执行

    问题 今天遇到一个问题,在下面的代码中,当抛出运行时异常后,后面的代码还会执行吗,是否需要在异常后面加上return语句呢? public void add(int index, E element) ...

  4. android环境安装

    引言   在windows安装Android的开发环境不简单也说不上算复杂,本文写给第一次想在自己Windows上建立Android开发环境投入Android浪潮的朋友们,为了确保大家能顺利完成开发环 ...

  5. Drupal 7 模块开发 建立模块帮助信息(hook_help)

    建立模块请參考 <Drupal 7 模块开发 建立> 假设你要支持中文,文件格式必须保存为 UTF-8.NO BOM ------------------------------ hook ...

  6. 【机器学习实战】第7章 集成方法(随机森林和 AdaBoost)

    第7章 集成方法 ensemble method 集成方法: ensemble method(元算法: meta algorithm) 概述 概念:是对其他算法进行组合的一种形式. 通俗来说: 当做重 ...

  7. 【转】优先队列priority_queue 用法详解

    http://www.cnblogs.com/void/archive/2012/02/01/2335224.html 优先队列是队列的一种,不过它可以按照自定义的一种方式(数据的优先级)来对队列中的 ...

  8. Net Core 实现谷歌翻译ApI 免费版

    原文:Net Core 实现谷歌翻译ApI 免费版 由于谷歌翻译官方API是付费版本,本着免费和开源的精神.分享一下用 Net Core 实现谷歌翻译API的代码. 项目引用的Nuget 包: Cha ...

  9. [React] Render Basic SVG Components in React

    React loves svg just as much as it loves html. In this lesson we cover how simple it is to make SVG ...

  10. iOS开发系列之三 - UITextField 使用方法小结

    // 初始化输入框并设置位置和大小 UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(10, 100, 30 ...