最近因项目需求,看了很多的折线图插件,但是都没有直接支持滑动查看的,而我们的项目的数据量较大需要滑动来展示。
滑动折线图的制作基本思想就是通过折线图插件在屏幕上绘制少量的比如6个数据,之后根据用户的滑动手势,将数据数组进行修改,最后通知界面刷新。
需要使用的插件是:Graph Maker,自行下载
首先需要先做一下手势判断,这里我们需要两个变量,来记录手指刚点击屏幕时的坐标,和后来滑动之后的坐标。
mFirstPos,mSecondPos,都是Vector2类型的,
我们还需要在脚本中实现IDragHandler来在OnDrag函数中进行手指滑动的位置监听
具体代码如下:
void Update(){
//当点击时获取当前的手指位置
if (Input.GetMouseButtonDown(0))
{
mFirstPos = Input.mousePosition;
mBoolLeft = true;
}
}
这里我给的判定边界是50,当手指移动距离达到50以上时将会进行一次重绘
public void OnDrag(PointerEventData eventData)
{
mSecondPos = eventData.position;
if (mSecondPos.x - mFirstPos.x > 50)//右
{
getRightDate();
ax.Refresh();
mFirstPos = mSecondPos;
}
if (mSecondPos.x - mFirstPos.x <-50)//左
{
getLeftDate();
ax.Refresh();
mFirstPos = mSecondPos;
}
}
我们可以发现,当你知道用户手指移动的手势之后我们还需要解决数据的刷新问题,我们在界面上显示的是一个较短的数组,假设每次折线图只展示6个数据,那么这个数组的长度就是6,而我们真实的数据数组可能长度有300。为了进行数据的更新我们可以定了两个位置指针,分别指向界面数组需显示数据的开始位置和结束为止,每次需要刷新新数据显示的时候我们就移动这两个指针,然后将界面数组的内容用我们的真实数据数组里两个指针范围内的数据填充,就可以达到更新界面底层数据源的问题了,需要注意的是,这里我们需要做一下边缘检测以防野指针的情况报错。
下面我以向右方请求数据为例
void getRightDate()
{
//数据尚未滑到最右端
dateList.Clear();//清空折线位置数组
labelDateList.Clear();//清空x轴坐标数组,此处的oneTouchDisplay是指每次触发一次数据请求我们更新多少个数据
if (leftPoint - oneTouchDisplay > 0)
{
rightPoint -= oneTouchDisplay;
leftPoint -= oneTouchDisplay;
for (int i = leftPoint; i < rightPoint + 1; i++)
{
dateList.Add(allPointList[i]);
labelDateList.Add(mylist[i]);
}
}
else
{
int temp = leftPoint;
leftPoint = 0;
rightPoint = rightPoint - temp;
for (int i = leftPoint; i < rightPoint + 1; i++)
{
dateList.Add(allPointList[i]);
labelDateList.Add(mylist[i]);
}
}
}
更新完数据,我们再调用一下Refresh();方法请求界面刷新即可将新的数据展示到折线图中,
下面贴上完整代码 (我这里在初始化数据的时候做了一下携程是因为不知道什么原因,不做携程刚初始化时,界面不会展示我们设置的默认数据)
public class DatePickerController : MonoBehaviour,IDragHandler{
private bool mBoolLeft = false;
private bool mBoolRight = false;
private Vector2 mFirstPos = Vector2.zero;//第一次
private Vector2 mSecondPos = Vector2.zero;//第二次
private Vector2 mOldPosition1 = new Vector2(0, 0);
private Vector2 mOldPosition2 = new Vector2(0, 0);
private float mOldDistance = 0f;
private float mNewDistance = 0f;
private WMG_Series grap;
private WMG_Axis_Graph ax;
private WMG_List<Vector2> dateList;
private WMG_List<string> labelDateList;
private int oneTouchDisplay = 1;//每次滑动新增的展示数据量
void Start()
{
grap = this.transform.Find("LineGraph/Series/Series1").GetComponent<WMG_Series>();
ax = this.transform.Find("LineGraph").GetComponent<WMG_Axis_Graph>();
StartCoroutine(initDate());
}
public WMG_List<Vector2> allPointList;
private bool canLeftMove = false;
private bool canRightMove = true;
private int leftPoint = 0;
private int rightPoint;
private WMG_List<string> mylist;
IEnumerator initDate()
{
yield return new WaitForSeconds(0f);
//模拟数据,只有直接将返回的数据复制到这两个list就行了
allPointList = new WMG_List<Vector2>();
allPointList.Add(new Vector2(1, 0.5f));
allPointList.Add(new Vector2(2, 1f));
allPointList.Add(new Vector2(3, 4f));
allPointList.Add(new Vector2(4, 8f));
allPointList.Add(new Vector2(5, 11f));
allPointList.Add(new Vector2(6, 12f));
allPointList.Add(new Vector2(7, 11f));
allPointList.Add(new Vector2(8, 8f));
allPointList.Add(new Vector2(9, 4f));
allPointList.Add(new Vector2(10, 1f));
allPointList.Add(new Vector2(11, 0.5f));
allPointList.Add(new Vector2(12, 3f));
allPointList.Add(new Vector2(1, 0.5f));
allPointList.Add(new Vector2(13, 2f));
allPointList.Add(new Vector2(14, 1f));
allPointList.Add(new Vector2(15, 3f));
allPointList.Add(new Vector2(16, 4f));
allPointList.Add(new Vector2(17, 1f));
allPointList.Add(new Vector2(18, 0.2f));
allPointList.Add(new Vector2(19, 5f));
allPointList.Add(new Vector2(20, 1f));
mylist=new WMG_List<string>();
mylist.Add("dsaffdsaf");
mylist.Add("fdasfdasf");
mylist.Add("fdafdsa");
mylist.Add("dfasfdas1");
mylist.Add("dfasfdas2");
mylist.Add("dfasfdas3");
mylist.Add("dfasfdas4");
mylist.Add("dfasfdas5");
mylist.Add("dfasfdas6");
mylist.Add("dfasfdas7");
mylist.Add("dfasfdas8");
mylist.Add("dfasfdas9");
mylist.Add("dfasfdas10");
mylist.Add("dfasfdas11");
mylist.Add("dfasfdas12");
mylist.Add("dfasfdas13");
mylist.Add("dfasfdas14");
mylist.Add("dfasfdas15");
mylist.Add("dfasfdas16");
mylist.Add("dfasfdas17");
mylist.Add("dfasfdas18");
labelDateList = ax.xAxis.axisLabels;
dateList = grap.pointValues;
int count = labelDateList.Count;
dateList.Clear();
labelDateList.Clear();
for (int i = 0; i < count; i++)
{
dateList.Add(allPointList[i]);
labelDateList.Add(mylist[i]);
}
ax.Refresh();
leftPoint = 0;
rightPoint = 5;
}
void getLeftDate()
{
//数据尚未滑到最左端
dateList.Clear();
labelDateList.Clear();
if (rightPoint + oneTouchDisplay < allPointList.Count)
{
rightPoint += oneTouchDisplay;
leftPoint += oneTouchDisplay;
for (int i = leftPoint; i < rightPoint + 1; i++)
{
dateList.Add(allPointList[i]);
labelDateList.Add(mylist[i]);
}
}
else
{
int temp = rightPoint;
rightPoint = allPointList.Count - 1;
leftPoint += rightPoint - temp;
for (int i = leftPoint; i < rightPoint + 1; i++)
{
dateList.Add(allPointList[i]);
labelDateList.Add(mylist[i]);
}
}
}
void getRightDate()
{
//数据尚未滑到最右端
dateList.Clear();
labelDateList.Clear();
if (leftPoint - oneTouchDisplay > 0)
{
rightPoint -= oneTouchDisplay;
leftPoint -= oneTouchDisplay;
for (int i = leftPoint; i < rightPoint + 1; i++)
{
dateList.Add(allPointList[i]);
labelDateList.Add(mylist[i]);
}
}
else
{
int temp = leftPoint;
leftPoint = 0;
rightPoint = rightPoint - temp;
for (int i = leftPoint; i < rightPoint + 1; i++)
{
dateList.Add(allPointList[i]);
labelDateList.Add(mylist[i]);
}
}
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
mFirstPos = Input.mousePosition;
mBoolLeft = true;
}
}
public void OnDrag(PointerEventData eventData)
{
mSecondPos = eventData.position;
if (mSecondPos.x - mFirstPos.x > 50)//右
{
getRightDate();
ax.Refresh();
mFirstPos = mSecondPos;
}
if (mSecondPos.x - mFirstPos.x <-50)//左
{
getLeftDate();
ax.Refresh();
mFirstPos = mSecondPos;
}
}
}