QCustomPlot之简单动态图(六)

本章节是仿照echart的动态图:地址

最终效果图

一、设置布局

首先新增一行一列用于放置标题和图例,这里将图例放置在一个空的轴矩形当中--QCustomPlot之层和布局(四)

// setupDynamicData(QCustomPlot *customPlot) 函数中
customPlot->plotLayout()->insertRow(0);
customPlot->plotLayout()->insertColumn(0);

QCPAxisRect *legendRect = new QCPAxisRect(customPlot, false);  // 不需要配置轴,因为我们只是把图例放在这里
legendRect->setAutoMargins(QCP::msNone); // 不计算边距
legendRect->insetLayout()->addElement(customPlot->legend, Qt::AlignCenter);  // 放置图例
customPlot->legend->setVisible(true);
customPlot->legend->setFillOrder(QCPLayoutGrid::foColumnsFirst); // 横向图例

customPlot->axisRect()->setAutoMargins(QCP::msBottom | QCP::msRight); // 只计算下边距和右边距
customPlot->plotLayout()->addElement(0, 0, new QCPTextElement(customPlot, "动态数据", QFont("sans", 12, QFont::Bold)));
customPlot->plotLayout()->addElement(0, 1, legendRect);
customPlot->plotLayout()->setRowStretchFactor(0, 0.1);    // 让其尽可能小一点
customPlot->plotLayout()->setColumnStretchFactor(0, 0.1);

二、设置图表

其次添加一个柱状图和折线图,并且添加它们的数据,注意这里采用QCPAxisTickerText而不采用QCPAxisTickerTime或者QCPAxisTickerDateTime的原因,是因为我们不想要它们计算刻度线的位置,同时要注意让xAxis2保持与xAxis的联动,这里只需连接信号槽即可

// setupDynamicData(QCustomPlot *customPlot) 函数中
// 设置柱状图
QCPBars *bar = new QCPBars(customPlot->xAxis, customPlot->yAxis2);
bar->setName("预购队列");
bar->setPen(Qt::NoPen);
bar->setBrush(QColor(194, 53, 49));

// 设置折线图
QCPGraph *graph = customPlot->addGraph(customPlot->xAxis, customPlot->yAxis);
graph->setName("最新成交价");
graph->setPen(QPen(QColor(47, 69, 84), 2));
graph->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, QColor(47, 69, 84), QColor(Qt::white), 4));

customPlot->yAxis->setLabel("价格");
customPlot->yAxis->setRange(0, 30);
customPlot->yAxis->setSubTicks(false);   // 设置子刻度线不显示
customPlot->yAxis->setTickLength(0, 6);  // 设置刻度线内外的长度
customPlot->yAxis2->setLabel("预购量");
customPlot->yAxis2->setVisible(true);
customPlot->yAxis2->setRange(0, 1200);
customPlot->yAxis2->setSubTicks(false);
customPlot->yAxis2->setTickLength(0, 6);

// 这里之所以用 QCPAxisTickerText,而不用 QCPAxisTickerTime / QCPAxisTickerDateTime 是因为它们会自动计算刻度线的位置,这是我们不想要的
QSharedPointer<QCPAxisTickerText> timeTicker(new QCPAxisTickerText);
QSharedPointer<QCPAxisTickerText> indexTicker(new QCPAxisTickerText);
customPlot->xAxis->setTicker(timeTicker);
customPlot->xAxis->setSubTicks(false);
customPlot->xAxis2->setVisible(true);
customPlot->xAxis2->setSubTicks(false);
customPlot->xAxis2->setTicker(indexTicker);
connect(customPlot->xAxis, SIGNAL(rangeChanged(QCPRange)), customPlot->xAxis2, SLOT(setRange(QCPRange)));  // 重要:让xAxis2与xAxis保持联动

// 添加数据
QVector<double> datax, datay1, datay2;
QTime now = QTime::currentTime();
for (int i = 0; i < 8; ++i) {
    mLabels.insert(0, now.toString("hh:mm:ss"));  // mLabels == QVector<QString>
    datax.insert(0, now.msecsSinceStartOfDay() / 1000.0);  // 时间
    now = now.addMSecs(-2000);

    mIndexLabels.insert(0, QString::number(8 - i));
    datay1.insert(0, QRandomGenerator::global()->bounded(20) + 5);   // 产生随机数,Qt 5.10 以下用qrand() % 20
    datay2.insert(0, QRandomGenerator::global()->bounded(1000));
}

mIndex = 8;
mPositions = datax; // mPositions == QVector<double>

graph->setData(datax, datay1);
bar->setData(datax, datay2);

timeTicker->setTicks(mPositions, mLabels);   // 设置刻度线位置和刻度标签
indexTicker->setTicks(mPositions, mIndexLabels);

customPlot->xAxis->rescale();
customPlot->xAxis->scaleRange(1.1);  // 稍微缩放一下,以显示全部

三、连接计时信号槽

// setupDynamicData(QCustomPlot *customPlot) 函数中
connect(&dataTimer, SIGNAL(timeout()), this, SLOT(dynamicDataSlot()));
dataTimer.start(2000);  // 2秒刷新一次

四、设置数据刷新的槽函数

以下都是在dynamicDataSlot槽函数中

  • 去除之前的数据
QCPBars *bar = static_cast<QCPBars *>(ui->customPlot->plottable(0));

// 移除第一个数据
bar->data()->remove(mPositions.first());
ui->customPlot->graph(0)->data()->remove(mPositions.first());

mPositions.removeFirst();
mLabels.removeFirst();
mIndexLabels.removeFirst();
  • 添加新增数据
// 计算当前时间
double key = QTime::currentTime().msecsSinceStartOfDay() / 1000.0;
QString label = QTime::currentTime().toString("hh:mm:ss");

ui->customPlot->graph(0)->addData(key, QRandomGenerator::global()->bounded(20) + 5);
bar->addData(key, QRandomGenerator::global()->bounded(1000));

mPositions.push_back(key);
mLabels.push_back(label);
mIndexLabels.push_back(QString::number(++mIndex));
  • 重新设置轴并刷新图表
QCPAxisTickerText *timeTicker = static_cast<QCPAxisTickerText *>(ui->customPlot->xAxis->ticker().data());
timeTicker->setTicks(mPositions, mLabels);  // 重新设置x轴

QCPAxisTickerText *indexTicker = static_cast<QCPAxisTickerText *>(ui->customPlot->xAxis2->ticker().data());
indexTicker->setTicks(mPositions, mIndexLabels);

ui->customPlot->xAxis->rescale();
ui->customPlot->xAxis->scaleRange(1.1);

ui->customPlot->replot();
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,907评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,987评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,298评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,586评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,633评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,488评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,275评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,176评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,619评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,819评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,932评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,655评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,265评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,871评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,994评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,095评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,884评论 2 354

推荐阅读更多精彩内容

  • This chapter covers the basic setup for using this librar...
    ngugg阅读 1,000评论 0 1
  • 图表控件库 MPAndroidChart 的使用 使用方法 项目源码地址,包含了很多类型的图标 https://g...
    jinchuang阅读 819评论 0 0
  • 文章转载自:https://github.com/tuteng/MPAndroidCharthttps://git...
    no白菜阅读 5,139评论 0 8
  • 8. Setting Colors Since release v1.4.0, the ColorTemplate...
    ngugg阅读 705评论 0 0
  • 开始 ####安装 为了使用 LineChart, BarChart, ScatterChart, CandleS...
    帅气的猪猪阅读 8,461评论 0 1