MyChartView.h
#ifndef MYCHARTVIEW_H
#define MYCHARTVIEW_H
#include <QtWidgets/QGraphicsView>
#include <QtCharts/QChartGlobal>
#include"QScatterSeries"
#include "QPointF"
#include "QLineSeries"
#include "QChartView"
#include "QValueAxis"
#include"qdatetimeaxis.h"
#include"QDebug"
#include"qdatetime.h"
#include"qdialog.h"
#include"common.h"
QT_BEGIN_NAMESPACE
class QGraphicsScene;
class QMouseEvent;
class QResizeEvent;
QT_END_NAMESPACE
QT_CHARTS_BEGIN_NAMESPACE
class QChart;
QT_CHARTS_END_NAMESPACE
class Callout;
QT_CHARTS_USE_NAMESPACE
class MyChartView: public QGraphicsView
{
Q_OBJECT
public:
MyChartView(ChartViewParam *cvp, QWidget *parent = 0);
void clearChart();
bool setWarnLine();
void setXFormat(QString str);
public:
QChart *m_chart;
QDateTimeAxis *m_axisX;
QValueAxis *m_axisY;
QLineSeries *m_series;
QScatterSeries *m_scatseries0;
QScatterSeries *m_scatseries1;
QLineSeries* m_series0 ;
QLineSeries* m_series1 ;
QLineSeries *m_warnLine;
int m_lineSize;//两点间实际间隔长度,为10分钟
int m_lineNum;//点数
int m_tooltiptype;
protected:
void resizeEvent(QResizeEvent *event);
void mouseMoveEvent(QMouseEvent *event);
public slots:
void keepCallout();
void tooltip(QPointF point, bool state);
private:
QGraphicsSimpleTextItem *m_coordX;
QGraphicsSimpleTextItem *m_coordY;
Callout *m_tooltip;
QList<Callout *> m_callouts;
};
#endif
#include "mychartview.h"
#include <QtGui/QResizeEvent>
#include <QtWidgets/QGraphicsScene>
#include <QtCharts/QChart>
#include <QtCharts/QLineSeries>
#include <QtCharts/QSplineSeries>
#include <QtWidgets/QGraphicsTextItem>
#include "callout.h"
#include <QtGui/QMouseEvent>
#include"QDebug"
MyChartView::MyChartView(ChartViewParam *cvp,QWidget *parent)
: QGraphicsView(new QGraphicsScene, parent),
m_coordX(0),
m_coordY(0),
m_chart(0),
m_tooltip(0)
{
setDragMode(QGraphicsView::NoDrag);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_lineNum=cvp->lineName.size();
int wide=1;
int pointsize=4;
m_lineSize=cvp->m_xMax.toTime_t()-cvp->m_xMin.toTime_t();
m_lineSize=m_lineSize/600;
QPen p0,p1,p2,p3;
p0.setStyle(Qt::SolidLine);
p0.setWidth(wide);
p0.setColor(Qt::blue);
//p0.setBrush(Qt::blue);
p0.setCapStyle(Qt::RoundCap);
p0.setJoinStyle(Qt::RoundJoin);
p1.setStyle(Qt::SolidLine);
p1.setWidth(wide);
p1.setColor(Qt::red);
//p1.setBrush(Qt::red);
p1.setCapStyle(Qt::RoundCap);
p1.setJoinStyle(Qt::RoundJoin);
//p1.setBrush(Qt::red);
p2.setWidth(wide);
p2.setColor(Qt::green);
p2.setBrush(Qt::green);
p3.setWidth(wide);
p3.setColor(Qt::yellow);
p3.setBrush(Qt::yellow);
//QScatterSeries类的点,为了突出每个点的位置,Qcharts画的出的线每个点的痕迹几乎看不到
m_scatseries0 = new QScatterSeries(this);
m_scatseries0->setMarkerShape(QScatterSeries::MarkerShapeCircle);//设置点的类型
m_scatseries0->setMarkerSize(pointsize); //设置点的大小
m_scatseries0->setPen(p2);
m_scatseries1 = new QScatterSeries(this);
m_scatseries1->setMarkerShape(QScatterSeries::MarkerShapeCircle);
m_scatseries1->setMarkerSize(pointsize);
m_scatseries1->setPen(p3);
m_series0 = new QLineSeries(this); //线条0
m_series0->setPen(p0);
m_series1 = new QLineSeries(this); //线条1
m_series1->setPen(p1);
/********************************/
/*设置画笔和画布*/
m_chart = new QChart;
m_series = new QLineSeries;
m_axisX = new QDateTimeAxis(this);
m_axisX->setTitleText(cvp->m_xNm);
m_axisX->setTickCount(10);
m_axisX->setFormat("hh:mm:ss");
m_axisX->setRange(cvp->m_xMin,cvp->m_xMax);
//axisX->setTitleFont("front:12px;color:green;");
m_axisY = new QValueAxis;
m_axisY->setRange(cvp->m_yMin,cvp->m_yMax);
m_axisY->setMinorTickCount(10);
m_axisY->setTitleText(cvp->m_yNm);
//m_axisY->setTitleFont("front:12px;color:green;");
if(m_lineNum==1)
{
m_chart->addSeries(m_scatseries0); //把各个线条添加到chart中
m_chart->addSeries(m_series0);
}
else if(m_lineNum==2)
{
m_chart->addSeries(m_scatseries0); //把各个线条添加到chart中
m_chart->addSeries(m_scatseries1);
m_chart->addSeries(m_series0);
m_chart->addSeries(m_series1);
}
m_chart->addAxis(m_axisX, Qt::AlignBottom); //并且XY轴的位置是下和左
m_chart->addAxis(m_axisY, Qt::AlignLeft);
//m_chart->legend()->hide();
m_chart->setTitle(cvp->m_title);
m_scatseries0->attachAxis(m_axisX);
m_scatseries0->attachAxis(m_axisY);
m_chart->setTitleFont(QFont("宋体",12,QFont::Bold));
m_scatseries1->attachAxis(m_axisX);
m_scatseries1->attachAxis(m_axisY);
m_series0->attachAxis(m_axisX);
m_series0->attachAxis(m_axisY);
m_series1->attachAxis(m_axisX);
m_series1->attachAxis(m_axisY);
m_series0->setName(cvp->lineName[0]);
m_scatseries0->setName(cvp->lineName[0]+"点");
if(m_lineNum==2)
{
m_series1->setName(cvp->lineName[1]);
m_scatseries1->setName(cvp->lineName[1]+"点");
qDebug()<<cvp->lineName[0]<<" "<<cvp->lineName[1];
}else
m_chart->legend()->hide();
m_chart->setAcceptHoverEvents(true);
setRenderHint(QPainter::Antialiasing);
scene()->addItem(m_chart);
m_coordX = new QGraphicsSimpleTextItem(m_chart);
//m_coordX->setPos(m_chart->size().width()/2 - 50, m_chart->size().height());
//m_coordX->setText("X1: ");
m_coordY = new QGraphicsSimpleTextItem(m_chart);
// m_coordY->setPos(m_chart->size().width()/2 + 50, m_chart->size().height());
//m_coordY->setText("Y1: ");
connect(m_series0, SIGNAL(clicked(QPointF)), this, SLOT(keepCallout()));
connect(m_series0, SIGNAL(hovered(QPointF, bool)), this, SLOT(tooltip(QPointF,bool)));
connect(m_series1, SIGNAL(clicked(QPointF)), this, SLOT(keepCallout()));
connect(m_series1, SIGNAL(hovered(QPointF, bool)), this, SLOT(tooltip(QPointF,bool)));
this->setMouseTracking(true);
m_tooltiptype=0;
}
void MyChartView::setXFormat(QString str)
{
m_axisX->setFormat(str);
}
bool MyChartView::setWarnLine()
{
QPen p0;
p0.setStyle(Qt::SolidLine);
p0.setWidth(1);
p0.setColor(Qt::blue);
//p0.setBrush(Qt::blue);
p0.setCapStyle(Qt::RoundCap);
p0.setJoinStyle(Qt::RoundJoin);
m_warnLine = new QLineSeries(this); //线条0
m_warnLine->setPen(p0);
m_warnLine->attachAxis(m_axisX);
m_warnLine->attachAxis(m_axisY);
m_chart->addSeries(m_warnLine);
}
void MyChartView::resizeEvent(QResizeEvent *event)
{
if (scene()) {
scene()->setSceneRect(QRect(QPoint(0, 0), event->size()));
m_chart->resize(event->size());
//m_coordX->setPos(m_chart->size().width()/2 - 50, m_chart->size().height() - 20);
//m_coordY->setPos(m_chart->size().width()/2 + 50, m_chart->size().height() - 20);
foreach (Callout *callout, m_callouts)
callout->updateGeometry();
}
QGraphicsView::resizeEvent(event);
}
void MyChartView::mouseMoveEvent(QMouseEvent *event)
{
QString str;
str = QString("%1").arg(m_chart->mapToValue(event->pos()).x(), 0, 'E',9);
str.replace(QString("E+12"), QString(""));
str.replace(QString("."), QString(""));
//qDebug() <<str;
int val=str.toInt();
QDateTime time = QDateTime::fromTime_t(val);
QString strBuffer = time.toString("hh:mm:ss");
//m_coordX->setText(QString("X1: %1").arg( strBuffer));
//m_coordY->setText(QString("Y1: %1").arg(m_chart->mapToValue(event->pos()).y()));
QGraphicsView::mouseMoveEvent(event);
}
void MyChartView::keepCallout()
{
m_callouts.append(m_tooltip);
m_tooltip = new Callout(m_chart);
}
void MyChartView::clearChart()
{
QVector<QPointF> Points0;
//qDebug()<<"m_series0 Points2:"<<Points0.size();
if(m_lineNum==2)
{
m_series1->clear();
m_scatseries1->clear();
m_series1->points().clear();
m_scatseries1->points().clear();
}
m_series0->clear();
m_scatseries0->clear();
m_series0->points().clear();
m_scatseries0->points().clear();
//qDebug()<<" clear m_series0 Points2:"<<Points0.size();
}
void MyChartView::tooltip(QPointF point, bool state)
{
if (m_tooltip == 0)
m_tooltip = new Callout(m_chart);
if (state) {
QString str;
str = QString("%1").arg(point.x(), 0, 'E',9);
str.replace(QString("E+12"), QString(""));
str.replace(QString("."), QString(""));
//qDebug() <<str;
int val=str.toInt();
QDateTime time ;
QString strBuffer;
if(m_tooltiptype==1)
{
time = QDateTime::fromTime_t(val);
strBuffer = time.toString("yyyy/MM/dd");
}
else
{
time = QDateTime::fromTime_t(val);
strBuffer = time.toString("hh:mm:ss");
}
m_tooltip->setText(QString("时间: %1 \n人数: %2 ").arg(strBuffer).arg(qRound(point.y())));
m_tooltip->setAnchor(point);
m_tooltip->setZValue(11);
m_tooltip->updateGeometry();
m_tooltip->show();
} else {
m_tooltip->hide();
}
}
mian.cpp
typedef struct ChartViewParam
{
int m_yMin;
int m_yMax;
QDateTime m_xMin;
QDateTime m_xMax;
QString m_title;
QString m_xNm;
QString m_yNm;
QVector<QString> lineName;
}ChartViewParam;
void MainWindow::initChart()
{
ChartViewParam *cvp1=new ChartViewParam;
ChartViewParam *cvp2=new ChartViewParam;
ChartViewParam *cvp3=new ChartViewParam;
ChartViewParam *cvp4=new ChartViewParam;
QString strBuffer;
QDateTime time;
time = QDateTime::currentDateTime();
strBuffer = time.toString("yyyy-MM-dd")+" 05:00:00";
time = QDateTime::fromString(strBuffer, "yyyy-MM-dd hh:mm:ss");
cvp1->m_title="当前客流";
cvp1->m_xMin=time;
cvp1->m_xMax=time.addSecs(24000);
cvp1->m_xNm="时间";
cvp1->m_yMax=3600;
cvp1->m_yMin=0;
cvp1->m_yNm="客流量/人";
cvp1->lineName.append("当前客流");
cvp1->lineName.append("预测客流");
cvp2->m_title="历史客流";
cvp2->m_xMin=QDateTime::currentDateTime();
cvp2->m_xMax=QDateTime::currentDateTime().addSecs(36000);
cvp2->m_xNm="时间";
cvp2->m_yMax=3600;
cvp2->m_yMin=0;
cvp2->m_yNm="客流量/人";
cvp2->lineName.append("实际客流");
cvp2->lineName.append("预测客流");
cvp3->m_title="换乘客流预测偏差分析";
cvp3->m_xMin=time;
cvp3->m_xMax=time.addSecs(24000);
cvp3->m_xNm="时间";
cvp3->m_yMax=20;
cvp3->m_yMin=0;
cvp3->m_yNm="偏差率/%";
cvp3->lineName.append("实时客流");
cvp4->m_title="进出站客流预测偏差分析";
cvp4->m_xMin=time;
cvp4->m_xMax=time.addSecs(24000);
cvp4->m_xNm="时间";
cvp4->m_yMax=400;
cvp4->m_yMin=-400;
cvp4->m_yNm="客流偏差值/人";
cvp4->lineName.append("偏差值");
m_curPass1 = new MyChartView(cvp1);
m_historyPass = new MyChartView(cvp2);
m_perfomance1 = new MyChartView(cvp3);
m_perfomance2 = new MyChartView(cvp4);
QVBoxLayout *layout = ui->passChart;
layout->addWidget(m_curPass1);
m_menCurIndex=0;
//layout->addStretch();//添加可伸缩控件,我感觉就是占地方的那种
layout->setAlignment(Qt::AlignHCenter);//布局内控件水平居中
m_perfomance1->setStyleSheet("QGraphicsView{padding: 0px;color:red;background:white;border: 2px solid gray;border-radius: 5px;}");
m_curPass1->setStyleSheet("QGraphicsView{padding: 0px;color:red;background:white;border: 2px solid gray;border-radius: 5px;}");
m_perfomance2->setStyleSheet("QGraphicsView{padding: 0px;color:red;background:white;border: 2px solid gray;border-radius: 5px;}");
m_historyPass->setStyleSheet("QGraphicsView{padding: 0px;color:red;background:white;border: 2px solid gray;border-radius: 5px;}");
m_perfomance1->installEventFilter(this);
m_curPass1->installEventFilter(this);
legendEvent(m_curPass1);
legendEvent(m_perfomance1);
legendEvent(m_perfomance2);
legendEvent(m_historyPass);
m_perfomance1->m_tooltiptype=1;
}
大体的在这里了,实例化这个对象后,往你界面布局中添加这个view就可以,QVBoxLayout *layout = ui->passChart;
部分东西可以删除。
560





