当前客流Qchart

 

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;

部分东西可以删除。

评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值