本次我学习的是在teechart中读取数据库中的数据,同时实现党鼠标在曲线图上移动是有十字线显示,并且能够指示当前指示的数据是多少。实现的效果如下图所示:
如上图所示,红色的曲线数据来自我的sqlserver2000,黑色的十字线交点是我的鼠标,右侧指示posX和posY是鼠标的位置对应的坐标值,x和y只有当鼠标在曲线上时才会显示,表面数据点的坐标。
在Teechart中实现数据库的链接其实是很简单的,可以直接在属性里面更改。我这里没有采用这种简单的方法,我采用的是通过代码自己进行链接。主要用到了ado,该数据库链接技术我在另一篇随笔里面已经讲过了,按照那篇文章的步骤就可以建立连接,说说主要步骤,初始化:AfxOleInit(),导入库:#import,新建超级指针变量,连接,执行查询,获取数据集。
获得数据以后,就是怎样把数据在图表上显示出来。我把该部分的程序写在了绘图按钮响应函数中:
if (m_chart.GetSeriesCount()<1)
{
m_chart.AddSeries(6);
}
while (!m_pRecordset->GetadoEOF())
{
m_chart.Series(0).Add(m_pRecordset->GetCollect("y"),(_bstr_t)m_pRecordset->GetCollect("x"),0);
m_pRecordset->MoveNext();
}
代码很简单,简单说明,首先添加一个序列,为防止重复添加,我增加了一个判断。然后一个while循环,只要没有读到数据的末尾就一直读取,我的数据表里面有两个字段,一个是x,一个是y,所以调用serias 0的add函数添加这两个字段的值,一个作为x轴的值,一个作为y轴的值,主要用到的函数就一个,GetCollect函数,该函数是记录集超级指针的函数,作用是取得某字段的数据然后返回,参数就是字段名,返回值为_variant_t类型,由于add函数的第二个参数是LPCTSTR类型,即常量字符串指针类型,所以将_variant_t进行一下强制转换。读取完一个记录以后别忘了将指针下移,即moveNext。
至此,点击绘图以后就可以显示曲线了。下一步是要实现鼠标移动的时候的十字线绘制以及坐标显示。
首先添加鼠标移动的消息响应函数,这个可以通过在控件上点击右键,事件,找到onMouseMove消息添加即可,然后添加如下代码:
void CChartADODlg::OnOnMouseMoveTchart1(long Shift, long X, long Y)
{
// TODO: Add your control notification handler code here
m_chart.Repaint();
long x1,y1,x2,y2;
x1 = m_chart.GetAxis().GetLeft().GetPosition();
y1 = m_chart.GetAxis().GetTop().GetPosition();
x2 = m_chart.GetAxis().GetRight().GetPosition();
y2 = m_chart.GetAxis().GetBottom().GetPosition();
if (X>=x1&&Y>=y1&&X<=x2&&Y<=y2)
{
m_chart.GetCanvas().DrawLine(x1,Y,x2,Y);
m_chart.GetCanvas().DrawLine(X,y1,X,y2);
}
DOUBLE posX,posY;
posX = m_chart.GetAxis().GetBottom().CalcPosPoint(X)+1;
posY = m_chart.GetAxis().GetLeft().CalcPosPoint(Y);
dataX = posX;
dataY = posY;
CString cs;
cs.Format("posX:%f posY:%f\r\n",posX,posY);
TRACE(cs);
SetDlgItemText(IDC_STATIC_X,cs);
}
上述代码执行时,首先对图表进行重绘,如果不加这一句大家一看就知道会发生什么效果。
后面保存图表绘图区的四个坐标,然后当鼠标在图表的绘图区域以内时,绘制两条交叉的线,利用DrawLine函数。接下来是显示在静态文本框中,文本框中显示的应该是数据区的坐标值,而不是鼠标的屏幕坐标值,所以应该进行一下转化,用到的函数是CalPosPoint函数,至于为什么计算x坐标要在后面加1我也不太清楚,就是在做的过程中发现需要加1才能对,比较诡异。
后面的代码就是显示了,不用赘述。
另外,当鼠标指针指向曲线时得显示当前的数据值,很简单,只需要添加一个消息响应函数,OnMouseEnterSeries即可
void CChartADODlg::OnOnMouseEnterSeriesTchart1(long SeriesIndex)
{
// TODO: Add your control notification handler code here
if (SeriesIndex==0)
{
CString cs;
cs.Format("x:%f y:%f",dataX,dataY);
SetDlgItemText(IDC_STATIC_Y,cs);
}
}
其中用到的dataX和dataY其实就是onMouseMove中计算出来的。当鼠标离开曲线时要把显示清空,所以再添加一个响应函数:
void CChartADODlg::OnOnMouseLeaveSeriesTchart1(long SeriesIndex)
{
// TODO: Add your control notification handler code here
SetDlgItemText(IDC_STATIC_Y,"");
}
至此,今天的任务就完成了~~~