Files
gcs-nf/App/ComponentUI/Scope/Chart.cpp
T

487 lines
11 KiB
C++

#include "Chart.h"
int Chart::ChannelIndex = 0;
Chart::Chart(QChart *chart, QWidget *parent)
{
chart->legend()->setAlignment(Qt::AlignRight);
chart->legend()->setMarkerShape(QLegend::MarkerShapeDefault);
chart->setTheme(QChart::ChartThemeQt);
//chart->setPlotArea(this->geometry());
QValueAxis *axisX = new QValueAxis();
axisX->setRange(-5, 5);
axisX->setTickCount(11);
axisX->setLabelFormat("%.2f");
chart->addAxis(axisX, Qt::AlignBottom);
QValueAxis *axisY = new QValueAxis();
axisY->setRange(-3, 3);
axisY->setTickCount(7);
//axisY->setLabelFormat("%.2f");
chart->addAxis(axisY, Qt::AlignLeft);
setParent(parent);
setChart(chart);
setScroll(true);
//默认不使用,因为使用显卡加速图形会闪
setUseOpenGL(false);
if(!updateTimer)
{
updateTimer = new QTimer(this);
connect(updateTimer,SIGNAL(timeout()),
this,SLOT(timeout()));
updateTimer->start(10);//10hz刷新
}
}
Chart::Chart(QWidget *parent)
{
setParent(parent);
chart()->legend()->setAlignment(Qt::AlignRight);
chart()->legend()->setMarkerShape(QLegend::MarkerShapeDefault);
chart()->setTheme(QChart::ChartThemeQt);
//chart()->setPlotArea(this->geometry());
QValueAxis *axisX = new QValueAxis();
//axisX->setRange(-5, 5);
//axisX->setTickCount(11);
//axisX->setLabelFormat("%.2f");
chart()->addAxis(axisX, Qt::AlignBottom);
QValueAxis *axisY = new QValueAxis();
axisY->setRange(-3, 3);
axisY->setTickCount(7);
axisY->setLabelFormat("%.2f");
chart()->addAxis(axisY, Qt::AlignLeft);
setScroll(true);
//默认不使用,因为使用显卡加速图形会闪
setUseOpenGL(false);
if(!updateTimer)
{
updateTimer = new QTimer(this);
connect(updateTimer,SIGNAL(timeout()),
this,SLOT(timeout()));
updateTimer->start(10);//20hz刷新
}
}
Chart::~Chart()
{
if(updateTimer)
{
if(updateTimer->isActive())
{
updateTimer->stop();
}
delete updateTimer;
}
}
void Chart::leaveEvent(QEvent *e)
{
isPress = false;
setCursor(Qt::ArrowCursor);
QChartView::leaveEvent(e);
}
void Chart::hideEvent(QHideEvent *e)
{
qDebug() << e;
}
void Chart::showEvent(QShowEvent *e)
{
qDebug() << e;
}
void Chart::mouseMoveEvent(QMouseEvent *e)
{
const QPoint curPos = e->pos();
if (isPress)
{
QPoint offset = curPos - lastPoint;
lastPoint = curPos;
chart()->scroll(-offset.x(), offset.y());
}
QChartView::mouseMoveEvent(e);
}
void Chart::mouseReleaseEvent(QMouseEvent *e)
{
isPress = false;
setCursor(Qt::ArrowCursor);
QChartView::mouseReleaseEvent(e);
}
void Chart::mousePressEvent(QMouseEvent *e)
{
if (e->button() == Qt::RightButton)
{
lastPoint = e->pos();
isPress = true;
setCursor(Qt::ClosedHandCursor);
}
QChartView::mousePressEvent(e);
}
void Chart::mouseDoubleClickEvent(QMouseEvent *e)
{
qDebug() << "Chart double clicked" << e;
//双击生成一个标
QChartView::mouseDoubleClickEvent(e);
}
void Chart::wheelEvent(QWheelEvent *e)
{
//以鼠标坐标为中心进行缩放
QPointF curVal = chart()->mapToValue(QPointF(e->pos()));
//缩放比例
const double factor = 1.5;
switch(e->modifiers())
{
case Qt::ControlModifier://垂直缩放
{
QValueAxis *axis = dynamic_cast<QValueAxis*>(chart()->axisY());
const double Min = axis->min();
const double Max = axis->max();
const double Central = curVal.y();
double bottomOffset;
double topOffset;
if (e->delta() > 0)
{//放大
bottomOffset = 1.0 / factor * (Central - Min);
topOffset = 1.0 / factor * (Max - Central);
}
else
{//缩小
bottomOffset = 1.0 * factor * (Central - Min);
topOffset = 1.0 * factor * (Max - Central);
}
chart()->axisY()->setRange(Central - bottomOffset, Central + topOffset);
}break;
case Qt::ShiftModifier://水平缩放
{
QValueAxis *axis = dynamic_cast<QValueAxis*>(chart()->axisX());
const double Min = axis->min();
const double Max = axis->max();
const double Central = curVal.x();
double bottomOffset;
double topOffset;
if (e->delta() > 0)
{//放大
bottomOffset = 1.0 / factor * (Central - Min);
topOffset = 1.0 / factor * (Max - Central);
}
else
{//缩小
bottomOffset = 1.0 * factor * (Central - Min);
topOffset = 1.0 * factor * (Max - Central);
}
chart()->axisX()->setRange(Central - bottomOffset, Central + topOffset);
}break;
default://水平移动
{
QValueAxis *axis = dynamic_cast<QValueAxis*>(chart()->axisX());
qreal dwidth = chart()->plotArea().width()/(axis->tickCount()*2);
if(e->delta() > 0)
{
chart()->scroll(-dwidth,0);
}
else if(e->delta() < 0)
{
chart()->scroll(dwidth,0);
}
}
}
QChartView::wheelEvent(e);
}
void Chart::resizeEvent(QResizeEvent *e)
{
chart()->setPos(0,0);
chart()->setGeometry(this->geometry());
//chart()->setPlotArea(this->geometry());
}
void Chart::timeout(void)//10Hz
{
//timeseries += 0.1;
//chartUpdate();
}
void Chart::chartUpdate(void)
{
//读取新数据,如果没有,那就保持
//当到达最大时(0.95),开始滚动
if(isScroll() == true)
{
QValueAxis *axis = dynamic_cast<QValueAxis*>(chart()->axisX());
const double Min = axis->min();
const double Max = axis->max();
if(timeseries > (Min + (Max - Min) * 0.95))
{
chart()->axisX()->setRange(Min + 0.01,Max + 0.01);
}
}
}
void Chart::setUseOpenGL(const bool &value)
{
isOpenGL= value;
}
bool Chart::addSeries(QString name = tr("new"))
{
//查找有没有这个名字的序列
bool isContain = false;
QList<QAbstractSeries *> slist = chart()->series();
for(QAbstractSeries *serie:slist)
{
if(serie->name() == name)
{
isContain = true;
}
}
if(isContain == false)
{
QLineSeries *s = new QLineSeries();
s->setColor(ColorMap::Color[ChannelIndex]);
s->setName(name);
//s->append(timeseries,0);
s->setUseOpenGL(isOpenGL);
chart()->addSeries(s);
chart()->setAxisX(chart()->axisX(),s);
chart()->setAxisY(chart()->axisY(),s);
ChannelIndex ++;
if(ChannelIndex >= 16)
{
ChannelIndex = 0;
}
}
else
{
qInfo() << "this chart has contain a serie name by :" << name;
}
return isContain;
}
bool Chart::addSeries(QString name = tr("new"), int index = 0)
{
if(index >= 16)
{
int a = index/16;
ChannelIndex = index - a*16;
}
//查找有没有这个名字的序列
bool isContain = false;
QList<QAbstractSeries *> slist = chart()->series();
for(QAbstractSeries *serie:slist)
{
if(serie->name() == name)
{
isContain = true;
}
}
if(isContain == false)
{
QLineSeries *s = new QLineSeries();
s->setColor(ColorMap::Color[ChannelIndex]);
s->setName(name);
//s->append(timeseries,0);
s->setUseOpenGL(isOpenGL);
chart()->addSeries(s);
chart()->setAxisX(chart()->axisX(),s);
chart()->setAxisY(chart()->axisY(),s);
ChannelIndex ++;
if(ChannelIndex >= 16)
{
ChannelIndex = 0;
}
}
else
{
qInfo() << "this chart has contain a serie name by :" << name;
}
return isContain;
}
bool Chart::addSeries(QString name = tr("new"),QColor color = QColor("#FFFFFF"))
{
//查找有没有这个名字的序列
bool isContain = false;
QList<QAbstractSeries *> slist = chart()->series();
for(QAbstractSeries *serie:slist)
{
if(serie->name() == name)
{
isContain = true;
}
}
if(isContain == false)
{
QLineSeries *s = new QLineSeries();
s->setColor(color);
s->setName(name);
//s->append(timeseries,0);
s->setUseOpenGL(isOpenGL);
chart()->addSeries(s);
chart()->setAxisX(chart()->axisX(),s);
chart()->setAxisY(chart()->axisY(),s);
ChannelIndex ++;
if(ChannelIndex >= 16)
{
ChannelIndex = 0;
}
}
else
{
qInfo() << "this chart has contain a serie name by :" << name;
}
return isContain;
}
void Chart::setSerieData(QString name,QVariant data)
{
timeseries++;
//qDebug() << timeseries << timeseries;
//出新了比以前更大或者更小的值,那么就设置一下量程
{
QValueAxis *axis = dynamic_cast<QValueAxis*>(chart()->axisY());
if(data.toDouble() > axis->max())
{
//设置最大值
const double Min = axis->min();
double FreeArea = (data.toDouble() - Min) * 0.1;
chart()->axisY()->setRange(Min, data.toDouble() + FreeArea);
}
else if(data.toDouble() < axis->min())
{
//设置最小值
const double Max = axis->max();
double FreeArea = (Max - data.toDouble()) * 0.1;
chart()->axisY()->setRange(data.toDouble() - FreeArea, Max);
}
}
//查找有没有这个名字的序列
bool isContain = false;
QList<QAbstractSeries *> slist = chart()->series();
for(QAbstractSeries *serie:slist)
{
QLineSeries *s = qobject_cast<QLineSeries *>(serie);
if(s->name() == name)
{
s->append(timeseries,data.toDouble());
isContain = true;
}
}
if(isContain == false)
{
addSeries(name,ChannelIndex);
ChannelIndex ++;
if(ChannelIndex >= 16)
{
ChannelIndex = 0;
}
QList<QAbstractSeries *> slist = chart()->series();
for(QAbstractSeries *serie:slist)
{
QLineSeries *s = qobject_cast<QLineSeries *>(serie);
if(s->name() == name)
{
s->append(timeseries,data.toDouble());
}
}
}
chartUpdate();
}
void Chart::removeSerie(QString name)
{
//找到,删除
QList<QAbstractSeries *> slist = chart()->series();
for(QAbstractSeries *serie:slist)
{
QLineSeries *s = qobject_cast<QLineSeries *>(serie);
if(s)
{
if(s->name() == name)
{
chart()->removeSeries(s);
s->clear();
s->deleteLater();
delete s;
}
}
}
}
void Chart::removeAllSerie(void)
{
//找到,删除
QList<QAbstractSeries *> slist = chart()->series();
for(QAbstractSeries *serie:slist)
{
QLineSeries *s = qobject_cast<QLineSeries *>(serie);
if(s)
{
chart()->removeSeries(s);
s->clear();
s->deleteLater();
delete s;
}
}
}