头文件
#pragma once
#include "osg/ref_ptr"
#include "osg/Group"
#include "osg/Geometry"
#include "osg/Texture2D"
#include "osg/PrimitiveSet"
#include "osgText/text"
#include "Tools/DllDefine.h"
#include "OSGPlusUnit.h"
#include <list>
using namespace std;
class CEqmDrawLineGraphic;
class CUPPCServerDataAccess;
#pragma warning(disable:4482)
class DLLEXPORT COSGPlusLineChart :
public COSGPlusUnit
{
public:
COSGPlusLineChart(double fPosX, double fPosY,double fWidth, double fHeight, wstring strXName, wstring strYName, wstring strTitle,CEqmDrawLineGraphic* pLineGraphic);
~COSGPlusLineChart(void);
void SetDataAccess(CUPPCServerDataAccess* pAccess); //设置链接数据库的指针
void CreateAxis(); //创建整个坐标轴
void CreateGrid(); //创建网格
void CreateTitle(); //创建标题
void CreateLines(); //创建osg绘图所用到的所有线的信息
void CreateYScale(); //创建Y轴的刻度和文字
void CreateXScale(); //创建X轴的刻度和时间
CEqmDrawLineGraphic* GetLineGraphic(); //获取线的信息的指针
void UpdateLineChart(); //更新折线图
void CalPointYCoordinate(CString strPointName,const int nIndex); //计算制定index的当前点的Y坐标
void Update();
void UpdateLineVertice(const int nIndex); //更新线的顶点坐标
public:
bool m_bAutoUpdate; //更新图表的标识
wstring m_strXAxisName; //横轴名称
wstring m_strYAxisName; //纵轴名称
wstring m_strChartName; //图表的名称
private:
const double GetMaxLimit( const double dValue );
bool IsNeedUpdate(); //是否达到更新的条件
void UpdateLineBound(const int nIndex); //更新边界点
void UpdateXAxisTime(); //更新X轴的时间
CString GetTimeByIndex(const int nIndex); //获取X轴不同刻度的时间
void ShiftAllPoint(const int nIndex); //移动线上的顶点坐标
void CraeteLegend(); //创建提示信息
CEqmDrawLineGraphic* m_pLineGraphic; //图表的信息指针
int m_nUpdateInterval; //更新的周期
int m_nTimeAccumulate; //时间累加计数
vector<osg::ref_ptr<osg::Vec3Array>> m_veclineVertice; //osg线顶点坐标向量
vector<osg::ref_ptr<osg::DrawElementsUInt>> m_vecLineBound; //osg线边界向量
vector<osg::ref_ptr<osg::Geometry>> m_veclineGeometry; //osg线几何体向量
vector<osg::ref_ptr<osgText::Text>> m_vecTextTime; //时间向量
vector<osg::ref_ptr<osgText::Text>> m_vecTextYScale; //纵轴刻度文字向量
vector<double> m_vecdCurPointHeight; //不同线的当前点高度向量
vector<double> m_vecXAxisCoordinate; //横轴刻度坐标向量
osg::ref_ptr<osg::Vec3Array> m_scaleLineTimeVertice; //横轴时间文字信息的顶点坐标
CUPPCServerDataAccess* m_pUPPCServerDataAccess; //数据库链接指针
double m_dMaxValue; //最大值
};
cpp
#include "StdAfx.h"
#include "OSGPlusLineChart.h"
#include "osg/Geode"
#include "osg/Referenced"
#include "osgDB/ReadFile"
#include "osg/BlendFunc"
#include "osg/AlphaFunc"
#include "osg/MatrixTransform"
#include "osg/ShapeDrawable"
#include "Tools/CustomTools/CustomTools.h"
#include "Tools/Util/UtilString.h"
#include "EqmDrawLineGraphic.h"
#include "../ServerDataAccess/UPPCServerDataAccess.h"
#include "time.h"
//常量定义
static const int STATIC_TITLE_X_TO_RECTANGLE_LEFT = 30;
static const int STATIC_GRIDLINE_GAP = 10;
static const int STATIC_SCALE_TEXT_NUM = 5;
static const int STATIC_TEXT_SCALE_TOP_TO_SCALE_LINE = 5;
static const int STATIC_TEXT_SCALE_LEFT_TO_SCALE_LINE = 40;
static const int STATIC_TIME_SCALE_LEFT_TO_SCALE_LINE = 20;
static const double STATIC_EPS = 1e-9;
static const double STATIC_PIXEL_PER_2SECOND = (double)(STATIC_GRIDLINE_GAP*10)/(double)360.0f;
static const double STATIC_LAYER = 0.3f;
//外部引用
extern SYSTEMTIME Time_tToSystemTime(time_t t);
extern time_t SystemTimeToTime_t( const SYSTEMTIME& st );
COSGPlusLineChart::COSGPlusLineChart(double fPosX, double fPosY,double fWidth, double fHeight, wstring strXName, wstring strYName, wstring strTitle, CEqmDrawLineGraphic* pLineGraphic)
:COSGPlusUnit(fPosX, fPosY, fWidth, fHeight, STATIC_LAYER)
,m_strXAxisName(strXName)
,m_strYAxisName(strYName)
,m_strChartName(strTitle)
,m_pLineGraphic(pLineGraphic)
,m_nUpdateInterval(0)
,m_nTimeAccumulate(0)
,m_dMaxValue(0.0f)
{
m_pUPPCServerDataAccess = NULL;
m_fPosX = m_fPosX - fWidth/2+20;
m_fPosY = m_fPosY - fHeight/2;
m_fWidth -= 90;
m_nUpdateInterval = m_pLineGraphic->GetUpdateInterval();
CreateTitle();
CreateAxis();
CreateGrid();
CreateYScale();
CreateXScale();
CreateLines();
CraeteLegend();
}
COSGPlusLineChart::~COSGPlusLineChart(void)
{
}
void COSGPlusLineChart::CreateAxis()
{
osg::ref_ptr<osg::Geode> geodeAxis = new osg::Geode;
addChild(geodeAxis);
osg::ref_ptr<osg::Geometry> lineGeometry = new osg::Geometry;
geodeAxis->addDrawable(lineGeometry);
osg::ref_ptr<osg::Vec3Array> lineVertice = new osg::Vec3Array;
lineGeometry->setVertexArray(lineVertice);
lineVertice->push_back(osg::Vec3(m_fPosX,m_fPosY,STATIC_LAYER));
lineVertice->push_back(osg::Vec3(m_fPosX+m_fWidth,m_fPosY,STATIC_LAYER));
lineVertice->push_back(osg::Vec3(m_fPosX+m_fWidth,m_fPosY+m_fHeight-STATIC_TITLE_X_TO_RECTANGLE_LEFT,STATIC_LAYER));
lineVertice->push_back(osg::Vec3(m_fPosX,m_fPosY+m_fHeight-STATIC_TITLE_X_TO_RECTANGLE_LEFT,STATIC_LAYER));
osg::ref_ptr<osg::DrawElementsUInt> tempAxisBound = new osg::DrawElementsUInt(osg::PrimitiveSet::LINE_LOOP, 0);
for (size_t i=0;i<lineVertice->size();++i)
{
tempAxisBound->push_back(i);
}
lineGeometry->addPrimitiveSet(tempAxisBound);
osg::ref_ptr<osg::Vec3Array> HUDnormals = new osg::Vec3Array;
HUDnormals->push_back(osg::Vec3(0.0f,0.0f,1.0f));
osg::Vec4Array* colarray = new osg::Vec4Array;
colarray->push_back(osg::Vec4(120/255.0f,120/255.0f,120/255.0f,1.0f));
lineGeometry->setNormalArray(HUDnormals);
lineGeometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
lineGeometry->setColorArray(colarray);
lineGeometry->setColorBinding(osg::Geometry::BIND_OVERALL);
}
void COSGPlusLineChart::CreateGrid()
{
osg::ref_ptr<osg::Geode> geodeGrid = new osg::Geode;
addChild(geodeGrid);
osg::ref_ptr<osg::Geometry> gridGeometry = new osg::Geometry;
geodeGrid->addDrawable(gridGeometry);
const int nNumInnerLineOfWidth = (int)(m_fWidth/STATIC_GRIDLINE_GAP);
const int nNumInnerLineOfHeight = (int)((m_fHeight-STATIC_TITLE_X_TO_RECTANGLE_LEFT)/STATIC_GRIDLINE_GAP);
int nNumWidth = 0;
int nNumHeight = 0;
if (nNumInnerLineOfWidth*STATIC_GRIDLINE_GAP<(int)m_fWidth)
{
nNumWidth = nNumInnerLineOfWidth + 1;
}
else
{
nNumWidth = nNumInnerLineOfWidth;
}
if (nNumInnerLineOfHeight*STATIC_GRIDLINE_GAP<(int)(m_fHeight-STATIC_TITLE_X_TO_RECTANGLE_LEFT))
{
nNumHeight = nNumInnerLineOfHeight + 1;
}
else
{
nNumHeight = nNumInnerLineOfHeight;
}
osg::ref_ptr<osg::Vec3Array> gridVertice = new osg::Vec3Array;
for (int j=0;j<=nNumHeight;++j)
{
for (int i=0;i<=nNumWidth;++i)
{
double x = 0.f;
double y = 0.f;
if (nNumWidth == nNumInnerLineOfWidth)
{
x = m_fPosX+STATIC_GRIDLINE_GAP*i;
}
else
{
if (i<=nNumInnerLineOfWidth)
{
x = m_fPosX+STATIC_GRIDLINE_GAP*i;
}
else
{
x = m_fPosX+m_fWidth;
}
}
if (nNumHeight == nNumInnerLineOfHeight)
{
y = m_fPosY+STATIC_GRIDLINE_GAP*j;
}
else
{
if (j<=nNumInnerLineOfHeight)
{
y = m_fPosY+STATIC_GRIDLINE_GAP*j;
}
else
{
y = m_fPosY+m_fHeight-STATIC_TITLE_X_TO_RECTANGLE_LEFT;
}
}
gridVertice->push_back(osg::Vec3(x,y,STATIC_LAYER));
}
}
gridGeometry->setVertexArray(gridVertice);
for (int m=1;m<=nNumWidth-1;++m)
{
osg::ref_ptr<osg::DrawElementsUInt> tempYBound = new osg::DrawElementsUInt(osg::PrimitiveSet::LINES, 0);
gridGeometry->addPrimitiveSet(tempYBound);
tempYBound->push_back(m);
tempYBound->push_back(nNumHeight*(nNumWidth+1)+m);
}
for (int n=1;n<=nNumHeight-1;++n)
{
osg::ref_ptr<osg::DrawElementsUInt> tempXBound = new osg::DrawElementsUInt(osg::PrimitiveSet::LINES, 0);
gridGeometry->addPrimitiveSet(tempXBound);
tempXBound->push_back(n*(nNumWidth+1));
tempXBound->push_back(n*(nNumWidth+1)+nNumWidth);
}
osg::ref_ptr<osg::Vec3Array> HUDnormals = new osg::Vec3Array;
HUDnormals->push_back(osg::Vec3(0.0f,0.0f,1.0f));
osg::Vec4Array* colarray = new osg::Vec4Array;
colarray->push_back(osg::Vec4(140/255.0f,140/255.0f,140/255.0f,0.1f));
gridGeometry->setNormalArray(HUDnormals);
gridGeometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
gridGeometry->setColorArray(colarray);
gridGeometry->setColorBinding(osg::Geometry::BIND_OVERALL);
geodeGrid->getOrCreateStateSet()->setMode(GL_BLEND,osg::StateAttribute::ON);
geodeGrid->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
}
void COSGPlusLineChart::CreateTitle()
{
osg::ref_ptr<osg::Geode> geodeTextTitle = new osg::Geode;
osg::ref_ptr<osgText::Text> textTitle = new osgText::Text;
osg::ref_ptr<osgText::Font> textFont = new osgText::Font;
textFont = osgText::readFontFile(Project::Tools::tstringToString(L"msyh.ttf"));
textTitle->setFont(textFont.get());
textTitle->setText(m_pLineGraphic->GetTitleName().GetString());
textTitle->setCharacterSize(20);
textTitle->setAutoRotateToScreen(true);
textTitle->setDataVariance(osg::Object::DYNAMIC);
textTitle->setColor(osg::Vec4(0/255.0, 0/255.0, 0/255.0, 1.0f));
textTitle->setPosition(osg::Vec3(m_fPosX+STATIC_TITLE_X_TO_RECTANGLE_LEFT,m_fPosY+m_fHeight,STATIC_LAYER));
textTitle->setAlignment(osgText::TextBase::AlignmentType::LEFT_TOP);
geodeTextTitle->addDrawable( textTitle.get() );
addChild(geodeTextTitle);
}
void COSGPlusLineChart::CreateLines()
{
osg::ref_ptr<osg::Geode> geodeLines = new osg::Geode;
addChild(geodeLines);
vector<_Graph_Item_Property>& itemVec = m_pLineGraphic->GetItemVector();
for (size_t i=0;i<itemVec.size();++i)
{
osg::ref_ptr<osg::Geometry> lineGeometry = new osg::Geometry;
geodeLines->addDrawable(lineGeometry);
m_veclineGeometry.push_back(lineGeometry);
osg::ref_ptr<osg::Vec3Array> lineVertice = new osg::Vec3Array;
m_veclineVertice.push_back(lineVertice);
osg::ref_ptr<osg::DrawElementsUInt> lineBound = new osg::DrawElementsUInt(osg::PrimitiveSet::LINE_STRIP, 0);
lineBound->push_back(0);
m_vecLineBound.push_back(lineBound);
lineGeometry->addPrimitiveSet(lineBound);
osg::ref_ptr<osg::Vec3Array> HUDnormals = new osg::Vec3Array;
HUDnormals->push_back(osg::Vec3(0.0f,0.0f,1.0f));
osg::Vec4Array* colarray = new osg::Vec4Array;
colarray->push_back(osg::Vec4(GetRValue(itemVec[i].color)/255.0f,GetGValue(itemVec[i].color)/255.0f,GetBValue(itemVec[i].color)/255.0f,1.0f));
lineGeometry->setNormalArray(HUDnormals);
lineGeometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
lineGeometry->setColorArray(colarray);
lineGeometry->setColorBinding(osg::Geometry::BIND_OVERALL);
m_vecdCurPointHeight.push_back(m_fPosY);
}
}
CEqmDrawLineGraphic* COSGPlusLineChart::GetLineGraphic()
{
return m_pLineGraphic;
}
bool COSGPlusLineChart::IsNeedUpdate()
{
if (m_nTimeAccumulate >= m_nUpdateInterval - 600)
{
m_nTimeAccumulate = 0;
return true;
}
else
{
m_nTimeAccumulate += 40;
return false;
}
return false;
}
void COSGPlusLineChart::CreateYScale()
{
double dRealYHeight = m_fHeight - STATIC_TITLE_X_TO_RECTANGLE_LEFT;
osg::ref_ptr<osg::Geode> geodeTextScale = new osg::Geode;
addChild(geodeTextScale);
osg::ref_ptr<osgText::Font> textFont = new osgText::Font;
textFont = osgText::readFontFile(Project::Tools::tstringToString(L"ebrima.ttf"));
double dScaleYStart[STATIC_SCALE_TEXT_NUM];
for (int i=0;i<STATIC_SCALE_TEXT_NUM;++i)
{
dScaleYStart[i] = m_fPosY+dRealYHeight*i/(STATIC_SCALE_TEXT_NUM-1);
osg::ref_ptr<osgText::Text> textScale = new osgText::Text;
textScale->setFont(textFont.get());
CString strScale;
double dScale = i/(double)(STATIC_SCALE_TEXT_NUM-1)*m_dMaxValue;
strScale.Format(L"%.1f",dScale);
textScale->setText(strScale.GetString());
textScale->setCharacterSize(10);
textScale->setAutoRotateToScreen(true);
textScale->setDataVariance(osg::Object::DYNAMIC);
textScale->setColor(osg::Vec4(0/255.0, 0/255.0, 0/255.0, 1.0f));
textScale->setPosition(osg::Vec3(m_fPosX-8,dScaleYStart[i]+STATIC_TEXT_SCALE_TOP_TO_SCALE_LINE,STATIC_LAYER));
textScale->setAlignment(osgText::TextBase::AlignmentType::RIGHT_TOP);
textScale->setMaximumWidth(STATIC_TEXT_SCALE_LEFT_TO_SCALE_LINE);
m_vecTextYScale.push_back(textScale);
geodeTextScale->addDrawable(textScale.get());
}
osg::ref_ptr<osg::Geode> geodeScaleLine = new osg::Geode;
addChild(geodeScaleLine);
osg::ref_ptr<osg::Geometry> scaleLineGeometry = new osg::Geometry;
geodeScaleLine->addDrawable(scaleLineGeometry);
osg::ref_ptr<osg::Vec3Array> scaleLineVertice = new osg::Vec3Array;
scaleLineGeometry->setVertexArray(scaleLineVertice);
for (int j=0;j<STATIC_SCALE_TEXT_NUM;++j)
{
scaleLineVertice->push_back(osg::Vec3(m_fPosX-7,dScaleYStart[j],STATIC_LAYER));
scaleLineVertice->push_back(osg::Vec3(m_fPosX-2,dScaleYStart[j],STATIC_LAYER));
}
for (int k=0;k<STATIC_SCALE_TEXT_NUM;++k)
{
osg::ref_ptr<osg::DrawElementsUInt> tempBound = new osg::DrawElementsUInt(osg::PrimitiveSet::LINES, 0);
scaleLineGeometry->addPrimitiveSet(tempBound);
tempBound->push_back(k*2);
tempBound->push_back(k*2+1);
}
osg::ref_ptr<osg::Vec3Array> HUDnormals = new osg::Vec3Array;
HUDnormals->push_back(osg::Vec3(0.0f,0.0f,1.0f));
osg::Vec4Array* colarray = new osg::Vec4Array;
colarray->push_back(osg::Vec4(120/255.0f,120/255.0f,120/255.0f,1.0f));
scaleLineGeometry->setNormalArray(HUDnormals);
scaleLineGeometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
scaleLineGeometry->setColorArray(colarray);
scaleLineGeometry->setColorBinding(osg::Geometry::BIND_OVERALL);
}
void COSGPlusLineChart::UpdateLineBound(const int nIndex)
{
m_vecLineBound[nIndex]->clear();
const size_t size = m_veclineVertice[nIndex]->size();
for (size_t j=0;j<size;++j)
{
m_vecLineBound[nIndex]->push_back(j);
}
}
void COSGPlusLineChart::UpdateLineVertice(const int nIndex)
{
Project::Tools::Scoped_Lock<Mutex> lock(m_lock);
osg::Vec3 vec3(m_fWidth+m_fPosX, m_vecdCurPointHeight[nIndex], STATIC_LAYER+0.01);
const size_t size = m_veclineVertice[nIndex]->size();
if (size > 0)
{
if (m_veclineVertice[nIndex]->at(0).x()-STATIC_PIXEL_PER_2SECOND <= m_fPosX)
{
m_veclineVertice[nIndex]->erase(m_veclineVertice[nIndex]->begin());
}
}
ShiftAllPoint(nIndex);
m_veclineVertice[nIndex]->push_back(vec3);
}
void COSGPlusLineChart::UpdateXAxisTime()
{
if(m_veclineVertice.size()<=0)
return;
const size_t sizePoint = m_veclineVertice[0]->size();
if (sizePoint > 0)
{
const size_t sizeTime = m_vecXAxisCoordinate.size();
for (size_t j=0;j<sizeTime;++j)
{
if (m_veclineVertice[0]->at(0).x()-STATIC_PIXEL_PER_2SECOND <= m_vecXAxisCoordinate[j])
{
m_vecTextTime[j]->setText(GetTimeByIndex(j).GetString());
}
}
}
}
void COSGPlusLineChart::UpdateLineChart()
{
vector<_Graph_Item_Property>& itemVec = m_pLineGraphic->GetItemVector();
for (size_t i=0;i<itemVec.size();++i)
{
m_veclineGeometry[i]->setVertexArray(m_veclineVertice[i]);
UpdateLineBound(i);
}
UpdateXAxisTime();
for (int i=0;i<STATIC_SCALE_TEXT_NUM;++i)
{
CString strScale;
double dScale = i/(double)(STATIC_SCALE_TEXT_NUM-1)*m_dMaxValue;
strScale.Format(L"%.1f",dScale);
m_vecTextYScale[i]->setText(strScale.GetString());
}
}
void COSGPlusLineChart::CreateXScale()
{
osg::ref_ptr<osg::Geode> geodeScaleLine = new osg::Geode;
addChild(geodeScaleLine);
osg::ref_ptr<osg::Geometry> scaleLineGeometry = new osg::Geometry;
geodeScaleLine->addDrawable(scaleLineGeometry);
m_scaleLineTimeVertice = new osg::Vec3Array;
scaleLineGeometry->setVertexArray(m_scaleLineTimeVertice);
int i=0;
while ((m_fWidth-i*STATIC_GRIDLINE_GAP*10)>0)
{
m_scaleLineTimeVertice->push_back(osg::Vec3(m_fPosX+m_fWidth-i*STATIC_GRIDLINE_GAP*10,m_fPosY-2,STATIC_LAYER));
m_scaleLineTimeVertice->push_back(osg::Vec3(m_fPosX+m_fWidth-i*STATIC_GRIDLINE_GAP*10,m_fPosY-7,STATIC_LAYER));
m_vecXAxisCoordinate.push_back(m_fPosX+m_fWidth-i*STATIC_GRIDLINE_GAP*10);
++i;
}
for (int k=0;k<i;++k)
{
osg::ref_ptr<osg::DrawElementsUInt> tempBound = new osg::DrawElementsUInt(osg::PrimitiveSet::LINES, 0);
scaleLineGeometry->addPrimitiveSet(tempBound);
tempBound->push_back(k*2);
tempBound->push_back(k*2+1);
}
osg::ref_ptr<osg::Vec3Array> HUDnormals = new osg::Vec3Array;
HUDnormals->push_back(osg::Vec3(0.0f,0.0f,1.0f));
osg::Vec4Array* colarray = new osg::Vec4Array;
colarray->push_back(osg::Vec4(120/255.0f,120/255.0f,120/255.0f,1.0f));
scaleLineGeometry->setNormalArray(HUDnormals);
scaleLineGeometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
scaleLineGeometry->setColorArray(colarray);
scaleLineGeometry->setColorBinding(osg::Geometry::BIND_OVERALL);
osg::ref_ptr<osg::Geode> geodeTextYScale = new osg::Geode;
addChild(geodeTextYScale);
osg::ref_ptr<osgText::Font> textFont = new osgText::Font;
textFont = osgText::readFontFile(Project::Tools::tstringToString(L"ebrima.ttf"));
for (size_t j=0;j<m_scaleLineTimeVertice->size()/2;++j)
{
osg::ref_ptr<osgText::Text> textTime = new osgText::Text;
m_vecTextTime.push_back(textTime);
textTime->setFont(textFont.get());
CString strTime;
strTime.Format(L"00:00:00");
textTime->setText(strTime.GetString());
textTime->setCharacterSize(10);
textTime->setAutoRotateToScreen(true);
textTime->setDataVariance(osg::Object::DYNAMIC);
textTime->setColor(osg::Vec4(0/255.0, 0/255.0, 0/255.0, 1.0f));
textTime->setPosition(osg::Vec3(m_scaleLineTimeVertice->at(j*2+1).x()-STATIC_TIME_SCALE_LEFT_TO_SCALE_LINE,m_scaleLineTimeVertice->at(j*2+1).y()-5,STATIC_LAYER));
textTime->setAlignment(osgText::TextBase::AlignmentType::LEFT_TOP);
textTime->setMaximumWidth(50);
geodeTextYScale->addDrawable(textTime.get());
}
}
void COSGPlusLineChart::CalPointYCoordinate(CString strPointName,const int nIndex)
{
double dValueItem = 0.0f;
if (m_pUPPCServerDataAccess->GetValue(strPointName.GetString(),dValueItem))
{
if (dValueItem > m_dMaxValue)
{
m_dMaxValue = GetMaxLimit(dValueItem);
}
const double dRealHeight = m_fHeight - STATIC_TITLE_X_TO_RECTANGLE_LEFT;
const double dPercent = dValueItem/m_dMaxValue;
Project::Tools::Scoped_Lock<Mutex> lock(m_lock);
m_vecdCurPointHeight[nIndex] = dRealHeight*dPercent + m_fPosY;
}
}
void COSGPlusLineChart::ShiftAllPoint(const int nIndex)
{
const size_t size = m_veclineVertice[nIndex]->size();
for (size_t i=0;i<size;++i)
{
double d = m_veclineVertice[nIndex]->at(i).x() - STATIC_PIXEL_PER_2SECOND;
if (d <= m_fPosX)
{
m_veclineVertice[nIndex]->at(i).x() = m_fPosX;
}
else
{
m_veclineVertice[nIndex]->at(i).x() = d;
}
}
}
CString COSGPlusLineChart::GetTimeByIndex( const int nIndex )
{
SYSTEMTIME tm;
GetLocalTime(&tm);
time_t t = SystemTimeToTime_t(tm);
t -= nIndex*60*6;
tm = Time_tToSystemTime(t);
CTime curTime(tm);
CString strCurTime;
strCurTime.Format(L"%02d:%02d:%02d",curTime.GetHour(),curTime.GetMinute(),curTime.GetSecond());
return strCurTime;
}
void COSGPlusLineChart::SetDataAccess( CUPPCServerDataAccess* pAccess )
{
if (pAccess)
{
m_pUPPCServerDataAccess = pAccess;
}
}
void COSGPlusLineChart::CraeteLegend()
{
//osg::ref_ptr<osg::Geode> geodeLegendAxis = new osg::Geode;
//addChild(geodeLegendAxis);
//osg::ref_ptr<osg::Geometry> lineGeometry = new osg::Geometry;
//geodeLegendAxis->addDrawable(lineGeometry);
//osg::ref_ptr<osg::Vec3Array> lineVertice = new osg::Vec3Array;
//lineGeometry->setVertexArray(lineVertice);
//lineVertice->push_back(osg::Vec3(m_fPosX+m_fWidth+10,m_fPosY,m_pLineGraphic->GetLayer()/10.0));
//lineVertice->push_back(osg::Vec3(m_fPosX+m_fWidth+10+80,m_fPosY,m_pLineGraphic->GetLayer()/10.0));
//lineVertice->push_back(osg::Vec3(m_fPosX+m_fWidth+10+80,m_fPosY+m_fHeight-STATIC_TITLE_X_TO_RECTANGLE_LEFT,STATIC_LAYER));
//lineVertice->push_back(osg::Vec3(m_fPosX+m_fWidth+10,m_fPosY+m_fHeight-STATIC_TITLE_X_TO_RECTANGLE_LEFT,STATIC_LAYER));
//osg::ref_ptr<osg::DrawElementsUInt> tempAxisBound = new osg::DrawElementsUInt(osg::PrimitiveSet::LINE_LOOP, 0);
//for (size_t i=0;i<lineVertice->size();++i)
//{
// tempAxisBound->push_back(i);
//}
//lineGeometry->addPrimitiveSet(tempAxisBound);
//osg::ref_ptr<osg::Vec3Array> HUDnormals = new osg::Vec3Array;
//HUDnormals->push_back(osg::Vec3(0.0f,0.0f,1.0f));
//osg::Vec4Array* colarray = new osg::Vec4Array;
//colarray->push_back(osg::Vec4(120/255.0f,120/255.0f,120/255.0f,1.0f));
//lineGeometry->setNormalArray(HUDnormals);
//lineGeometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
//lineGeometry->setColorArray(colarray);
//lineGeometry->setColorBinding(osg::Geometry::BIND_OVERALL);
osg::ref_ptr<osgText::Font> textFont = new osgText::Font;
textFont = osgText::readFontFile(Project::Tools::tstringToString(L"msyh.ttf"));
osg::ref_ptr<osg::Geode> geodeLineLegend = new osg::Geode;
addChild(geodeLineLegend);
osg::ref_ptr<osg::Geode> geodeTextLegend = new osg::Geode;
vector<_Graph_Item_Property>& itemVec = m_pLineGraphic->GetItemVector();
for (size_t i=0;i<itemVec.size();++i)
{
osg::ref_ptr<osg::Geometry> lineLegendGeometry = new osg::Geometry;
geodeLineLegend->addDrawable(lineLegendGeometry);
osg::ref_ptr<osg::Vec3Array> sampleLineVertice = new osg::Vec3Array;
sampleLineVertice->push_back(osg::Vec3(m_fPosX+m_fWidth+10+6,m_fPosY+m_fHeight-STATIC_TITLE_X_TO_RECTANGLE_LEFT-15-40*i,STATIC_LAYER));
sampleLineVertice->push_back(osg::Vec3(m_fPosX+m_fWidth+10+18,m_fPosY+m_fHeight-STATIC_TITLE_X_TO_RECTANGLE_LEFT-15-40*i,STATIC_LAYER));
lineLegendGeometry->setVertexArray(sampleLineVertice);
osg::ref_ptr<osg::DrawElementsUInt> tempBound = new osg::DrawElementsUInt(osg::PrimitiveSet::LINES, 0);
lineLegendGeometry->addPrimitiveSet(tempBound);
tempBound->push_back(0);
tempBound->push_back(1);
osg::ref_ptr<osg::Vec3Array> HUDnormals = new osg::Vec3Array;
HUDnormals->push_back(osg::Vec3(0.0f,0.0f,1.0f));
osg::Vec4Array* colarray = new osg::Vec4Array;
colarray->push_back(osg::Vec4(GetRValue(itemVec[i].color)/255.0f,GetGValue(itemVec[i].color)/255.0f,GetBValue(itemVec[i].color)/255.0f,1.0f));
lineLegendGeometry->setNormalArray(HUDnormals);
lineLegendGeometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
lineLegendGeometry->setColorArray(colarray);
lineLegendGeometry->setColorBinding(osg::Geometry::BIND_OVERALL);
osg::ref_ptr<osgText::Text> textLegend = new osgText::Text;
textLegend->setFont(textFont.get());
textLegend->setText(itemVec[i].strItemName.GetString());
textLegend->setCharacterSize(14);
textLegend->setAutoRotateToScreen(true);
textLegend->setDataVariance(osg::Object::DYNAMIC);
textLegend->setColor(osg::Vec4(0/255.0, 0/255.0, 0/255.0, 1.0f));
textLegend->setPosition(osg::Vec3(m_fPosX+m_fWidth+10+22,m_fPosY+m_fHeight-STATIC_TITLE_X_TO_RECTANGLE_LEFT-15-40*i+7,STATIC_LAYER));
textLegend->setAlignment(osgText::TextBase::AlignmentType::LEFT_TOP);
textLegend->setMaximumWidth(60);
geodeTextLegend->addDrawable(textLegend.get());
addChild(geodeTextLegend);
}
}
void COSGPlusLineChart::Update()
{
Project::Tools::Scoped_Lock<Mutex> lock(m_lock);
COSGPlusUnit::Update();
if (IsNeedUpdate() && m_bNeedUpdate)
{
UpdateLineChart();
m_bNeedUpdate = false;
}
}
const double COSGPlusLineChart::GetMaxLimit( const double dValue )
{
return double((int(dValue/8)+10)*8);
}