487 lines
11 KiB
C++
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;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|