qcustomplot动态绘图(直接操作数据存放区)

qcustomplot

QCustomPlot是Qt的一个小型第三方图表库,支持静态/动态曲线、柱状图、蜡烛图、频谱图等,使用起来也是非常的方便,这里也不过多的进行介绍了。

效果图

在这里插入图片描述

功能介绍

默认的绘图方式虽然方便,但长时间的执行会有较大的内存压力。为了避免这一问题采用操作缓存区的方式来存放数据,同时能让x,y轴动态调整保证线条的动态居中。

分配缓存区

	while (m_draw->removeGraph(0));
	m_bufferSize = size;
	QSharedPointer<QCPGraphDataContainer> dataContainer = m_draw->addGraph()->data();
	QVector<QCPGraphData> plotData(m_bufferSize);
	for (size_t j = 0; j < m_bufferSize; j++)
	{
		plotData[j].key = j;
		plotData[j].value = initialValue;
	}
	dataContainer->set(plotData, true);
	m_draw->xAxis->setRange(0, m_bufferSize);
	m_dataQueue.clear();
	m_drawBuffer = m_draw->graph()->data().data();

增加数据

将数据存放入队列中

if (m_dataQueue.size() >= m_bufferSize)
		m_dataQueue.dequeue();
	m_dataQueue.enqueue(data);

开始绘图

if (m_lineTimer.isActive())
		m_lineTimer.stop();
	if (m_axisTimer.isActive())
		m_axisTimer.stop();
	m_lineTimer.start(lineRefreshTime);
	m_axisTimer.start(axisRefreshTime);

绘图的定时器

size_t size = m_dataQueue.size();
	for (size_t j = size - 1; j; --j)
	{
		QCPGraphData* buff = (QCPGraphData*)m_drawBuffer->at(j);
		buff->value = m_dataQueue.at(j);
	}
	m_draw->replot(QCustomPlot::rpQueuedReplot);

动态改变Y轴

	m_max = *std::max_element(m_dataQueue.begin(), m_dataQueue.end());
	m_min = *std::min_element(m_dataQueue.begin(), m_dataQueue.end());
	m_draw->xAxis->setRange(0, m_bufferSize);
	if (m_max < 0)
		m_draw->yAxis->setRange(m_min + m_min * m_magnification, m_max - m_max * m_magnification);
	else
	{
		if (m_min > 0)
			m_draw->yAxis->setRange(m_min - m_min * m_magnification, m_max + m_max * m_magnification);
		else
			m_draw->yAxis->setRange(m_min + m_min * m_magnification, m_max + m_max * m_magnification);
	}

放大图层缩小图层

放大

if (m_magnification > 0.1)
		m_magnification -= 0.1;

缩小

if (m_magnification < 5)
		m_magnification += 0.1;

#全部代码

#pragma once

#include <QObject>
#include"qcustomplot.h"
#include<QTimer>
#include<QQueue>
class DynamicDraw : public QObject
{
	Q_OBJECT

public:
	DynamicDraw(QCustomPlot* customPlot, QObject* parent = nullptr);
	~DynamicDraw();
	void allotBuffer(u_short size, float initialValue = 0);
	void addData(float data);
	void startDraw(u_short lineRefreshTime = 30, u_short axisRefreshTime = 100);
	void magnify();
	void shrink();
private slots:
	void on_refreshLine_timeOut();
	void on_refreshAxis_timeOut();
private:
	QCustomPlot* m_draw;
	QTimer m_lineTimer;
	QTimer m_axisTimer;
	QQueue<float> m_dataQueue;
	u_short m_bufferSize;
	int m_max;
	int m_min;
	float m_magnification;
	QCPGraphDataContainer* m_drawBuffer;
};

#include "DynamicDraw.h"

DynamicDraw::DynamicDraw(QCustomPlot* customPlot,QObject *parent)
	: QObject(parent),m_draw(customPlot),m_bufferSize(0),m_magnification(1),m_max(0),m_min(0),m_drawBuffer(NULL)
{
	connect(&m_lineTimer, &QTimer::timeout, this, &DynamicDraw::on_refreshLine_timeOut);
	connect(&m_axisTimer, &QTimer::timeout, this, &DynamicDraw::on_refreshAxis_timeOut);
}

DynamicDraw::~DynamicDraw()
{

}

void DynamicDraw::allotBuffer(u_short size, float initialValue)
{
	while (m_draw->removeGraph(0));
	m_bufferSize = size;
	QSharedPointer<QCPGraphDataContainer> dataContainer = m_draw->addGraph()->data();
	QVector<QCPGraphData> plotData(m_bufferSize);
	for (size_t j = 0; j < m_bufferSize; j++)
	{
		plotData[j].key = j;
		plotData[j].value = initialValue;
	}
	dataContainer->set(plotData, true);
	m_draw->xAxis->setRange(0, m_bufferSize);
	m_dataQueue.clear();
	m_drawBuffer = m_draw->graph()->data().data();
}

void DynamicDraw::addData(float data)
{
	if (m_dataQueue.size() >= m_bufferSize)
		m_dataQueue.dequeue();
	m_dataQueue.enqueue(data);
}

void DynamicDraw::startDraw(u_short lineRefreshTime, u_short axisRefreshTime)
{
	if (m_lineTimer.isActive())
		m_lineTimer.stop();
	if (m_axisTimer.isActive())
		m_axisTimer.stop();
	m_lineTimer.start(lineRefreshTime);
	m_axisTimer.start(axisRefreshTime);
}

void DynamicDraw::magnify()
{
	if (m_magnification > 0.1)
		m_magnification -= 0.1;
}

void DynamicDraw::shrink()
{
	if (m_magnification < 5)
		m_magnification += 0.1;
}

void DynamicDraw::on_refreshLine_timeOut()
{
	size_t size = m_dataQueue.size();
	for (size_t j = size - 1; j; --j)
	{
		QCPGraphData* buff = (QCPGraphData*)m_drawBuffer->at(j);
		buff->value = m_dataQueue.at(j);
	}
	m_draw->replot(QCustomPlot::rpQueuedReplot);
}

void DynamicDraw::on_refreshAxis_timeOut()
{
	m_max = *std::max_element(m_dataQueue.begin(), m_dataQueue.end());
	m_min = *std::min_element(m_dataQueue.begin(), m_dataQueue.end());
	m_draw->xAxis->setRange(0, m_bufferSize);
	if (m_max < 0)
		m_draw->yAxis->setRange(m_min + m_min * m_magnification, m_max - m_max * m_magnification);
	else
	{
		if (m_min > 0)
			m_draw->yAxis->setRange(m_min - m_min * m_magnification, m_max + m_max * m_magnification);
		else
			m_draw->yAxis->setRange(m_min + m_min * m_magnification, m_max + m_max * m_magnification);
	}
}

有更好的思路请在评论区指出

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Pointer=NULL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值