#include "mychart.h"
mychart::mychart(QWidget *parent) : QWidget(parent)
{
this->setStyleSheet("QWidget{background:white}");
m_ptStartPos.setX(30);
m_ptStartPos.setY(30);
title_font = new QFont("SimSun", 20, 50); // 默认字体
text_font = new QFont("SimSun", 14, 50); // 默认字体
scale_value = 5; // 刻度默认长度5
axis_x_count = 5; // 默认刻度数量为5
axis_y_count = 5; // 默认刻度数量为5
/* X轴范围 */
axis_x_range.setX(0);
axis_x_range.setY(1000);
/* Y轴范围 */
axis_y_range.setX(0);
axis_y_range.setY(10);
x_scale_list.clear();
y_scale_list.clear();
x_scale_string_list.clear();
y_scale_string_list.clear();
x_unit_string.clear();
y_unit_string.clear();
coordinate_dir = false; // 坐标轴方向 false:向下 / true:向上
paint_point_list.clear();
is_enable_move = false; // 默认可以拖动数据点
move_type = Move_Dir::Vertical; // 默认竖直方向拖动
is_press = false;
is_move = false;
}
/* 清除所有数据 */
void mychart::remove_all_point()
{
paint_point_list.clear();
}
// 设置坐标系方向
void mychart::set_coordinate_dir(bool state)
{
coordinate_dir = state;
}
void mychart::SetMathCoordinate(QPainter* painter)
{
/*
* @brief 转换为数学坐标系,原点在左下角
*/
painter->setWindow(0,height(),width(),-height());
}
void mychart::ResetDefaultCoordinate(QPainter* painter)
{
/*
* @brief 恢复默认坐标系,原点在左上角
*/
painter->setWindow(0, 0, this->width(), this->height());
}
/* 绘制标题 */
void mychart::paint_title(QPainter *painter)
{
if(title_string.isEmpty())
{
title_height = 0;
return;
}
ResetDefaultCoordinate(painter);
painter->setFont(*title_font);
int width = this->width() / 2;
// int height = this->height();
QFontMetrics fm(*title_font);
int axis_x_string_width = fm.width(title_string);
int axis_x_string_heigh = fm.height(); // X轴字符的高度
int rect_y = 0 + 5;
title_height = rect_y + axis_x_string_heigh + 5;
if(coordinate_dir)
{
rect_y = 0;
title_height = 0;
}
QRectF rect(width - axis_x_string_width / 2,
rect_y,
axis_x_string_width,
axis_x_string_heigh);
painter->drawText(rect,title_string);
title_height = rect_y + axis_x_string_heigh + 5;
}
/* 绘制坐标轴 */
void mychart::paint_coordinate_axis(QPainter *painter)
{
if(coordinate_dir)
SetMathCoordinate(painter);
else
ResetDefaultCoordinate(painter); // 左上角
painter->setFont(*text_font);
int width = this->width();
int height = this->height();
scale_value = ((width + height) / 75 > 10)?10:(width + height) / 75;
/* 确定字符的长宽 */
QFontMetrics fm(*text_font);
int axis_x_string_width = fm.width("0");
int axis_x_string_heigh = fm.height(); // X轴字符的高度
for(int i = 0;i < axis_y_count;i++)
{
/* 确定Y轴上的字符最大宽度 */
QString y_string = (y_scale_string_list.isEmpty())?
QString::number((axis_y_range.y() - axis_y_range.x()) / (axis_y_count - 1) * i,'f',2):
y_scale_string_list.at(i);
int string_width = fm.width(y_string);
axis_x_string_width = (string_width > axis_x_string_width)?string_width:axis_x_string_width;
}
int axis_x_len = scale_value + axis_x_string_heigh; // X刻度长度 + 字符高度
int axis_y_len = scale_value + axis_x_string_width; // Y刻度长度 + 字符高度
m_ptStartPos.setX(axis_y_len); // 坐标原点
m_ptStartPos.setY(axis_x_len + title_height);
m_axisWidth = width - m_ptStartPos.x() * 2; // 坐标有效期长度
m_axisHeight = height - m_ptStartPos.y() * 2; // 坐标有效高
QPen pen;
pen.setWidth(1);
pen.setColor(Qt::black);
painter->setPen(pen);
/* 画X坐标轴上的箭头 */
QPointF points[3];
points[0].setX(m_ptStartPos.x() + m_axisWidth + m_ptStartPos.x() / 2);
points[0].setY(m_ptStartPos.y() - m_ptStartPos.x() / 10);
points[1].setX(m_ptStartPos.x() + m_axisWidth + m_ptStartPos.x() / 2);
points[1].setY(m_ptStartPos.y() + m_ptStartPos.x() / 10);
points[2].setX(m_ptStartPos.x() + m_axisWidth + m_ptStartPos.x());
points[2].setY(m_ptStartPos.y());
painter->setBrush(Qt::black);
painter->drawPolygon(points,3); //画三角形
/* 画Y坐标轴上的箭头 */
points[0].setX(m_ptStartPos.x() + m_axisHeight / 60);
points[0].setY(m_ptStartPos.y() + m_axisHeight + m_ptStartPos.y() / 2);
points[1].setX(m_ptStartPos.x() - m_axisHeight / 60);
points[1].setY(m_ptStartPos.y() + m_axisHeight + m_ptStartPos.y() / 2);
points[2].setX(m_ptStartPos.x());
points[2].setY(m_ptStartPos.y() + m_axisHeight + m_ptStartPos.y());
painter->drawPolygon(points,3); //画三角形
QPoint axisStartPoint;
QPoint axisXEndPoint; // x 轴终点
QPoint axisYEndPoint; // y 轴终点
/* XY轴线 */
axisStartPoint.setX(m_ptStartPos.x());
axisStartPoint.setY(m_ptStartPos.y());
axisXEndPoint.setX(m_ptStartPos.x() + m_axisWidth + m_ptStartPos.x() / 2);
axisXEndPoint.setY(m_ptStartPos.y());
axisYEndPoint.setX(m_ptStartPos.x());
axisYEndPoint.setY(m_ptStartPos.y() + m_axisHeight + m_ptStartPos.y() / 2);
painter->drawLine(axisStartPoint, axisXEndPoint); // X轴线
painter->drawLine(axisStartPoint, axisYEndPoint); // Y轴线
/* 画X轴刻度线和刻度标识 */
int count = (!x_scale_list.isEmpty())?x_scale_list.length():axis_x_count;
for(int i = 1;i < count;i++)
{
qreal x = m_ptStartPos.x() + m_axisWidth / (axis_x_count - 1) * i;
if(!x_scale_list.isEmpty())
x = m_ptStartPos.x() + (x_scale_list.at(i) - x_scale_list.at(0)) * m_axisWidth / (x_scale_list.last() - x_scale_list.at(0));
axisStartPoint.setX(x);
axisStartPoint.setY(m_ptStartPos.y());
axisXEndPoint.setX(axisStartPoint.x());
axisXEndPoint.setY(axisStartPoint.y() - scale_value);
painter->drawLine(axisStartPoint, axisXEndPoint); // 画刻度线
}
/* 画Y轴刻度线和刻度标识 */
for(int i = 1;i < axis_y_count;i++)
{
qreal y = m_ptStartPos.y() + m_axisHeight / (axis_y_count - 1) * i;
if(!y_scale_list.isEmpty())
y = m_ptStartPos.y() + (y_scale_list.at(i) - y_scale_list.at(0)) * m_axisHeight / (y_scale_list.last() - y_scale_list.at(0));
axisStartPoint.setX(m_ptStartPos.x());
axisStartPoint.setY(y);
axisXEndPoint.setX(axisStartPoint.x() - scale_value);
axisXEndPoint.setY(axisStartPoint.y());
painter->drawLine(axisStartPoint, axisXEndPoint); // 画刻度线
}
}
/* 绘制刻度文本 */
void mychart::paint_coordinate_scale_text(QPainter *painter)
{
ResetDefaultCoordinate(painter);
painter->setFont(*text_font);
/* 确定字符的长宽 */
QFontMetrics fm(*text_font);
int axis_x_string_width = fm.width("0");
int axis_x_string_heigh = fm.height(); // X轴字符的高度
for(int i = 0;i < axis_y_count;i++)
{
/* 确定Y轴上的字符最大宽度 */
QString y_string = (y_scale_string_list.isEmpty())?
QString::number((axis_y_range.y() - axis_y_range.x()) / (axis_y_count - 1) * i,'f',2):
y_scale_string_list.at(i);
int string_width = fm.width(y_string);
axis_x_string_width = (string_width > axis_x_string_width)?string_width:axis_x_string_width;
}
QPoint axis