#include "coalstatisticschartwidget.h" #include "ui_coalstatisticschartwidget.h" #include #include #include #include #include #include #include #include CoalStatisticsChartWidget::CoalStatisticsChartWidget(QWidget* parent) : QWidget(parent) , ui(new Ui::CoalStatisticsChartWidget) { ui->setupUi(this); m_systemSetting = new QSettings("system.ini", QSettings::IniFormat); ui->dateTimeEdit_startTime->setDateTime(QDateTime::currentDateTime().addSecs(-8 * 3600)); initCustomCoalStatisticsBarChart(); // initCustomPlotCoalStatisticsBarChart(); } CoalStatisticsChartWidget::~CoalStatisticsChartWidget() { delete ui; } void CoalStatisticsChartWidget::on_pushButton_coalStatisOk_clicked() { // 时间范围 QString beginTimeStr = ui->dateTimeEdit_startTime->text(); QString endTimeStr = ui->dateTimeEdit_endTime->text(); // 统计单位 QString statisticUnit = ui->comboBox_unit->currentText(); // 创建 QDateTime 对象 QDateTime beginTime = QDateTime::fromString(beginTimeStr, "yyyy/MM/d H:mm"); QDateTime endTime = QDateTime::fromString(endTimeStr, "yyyy/MM/d H:mm"); // 格式化为 "yyyy-MM-d H" 形式 QString formattedBeginTime = beginTime.toString("yyyy-MM-dd HH"); QString formattedEndTime = endTime.toString("yyyy-MM-dd HH"); QString startTimestr = "起始时间" + formattedBeginTime; QString endTimestr = "终止时间" + formattedEndTime; // emit querySuccessInfo(startTimestr); // emit querySuccessInfo(endTimestr); // 输出格式化后的时间 qDebug() << "Formatted Begin Time: " << formattedBeginTime; qDebug() << "Formatted End Time: " << formattedEndTime; qDebug() << "statisticUnit:" << statisticUnit; getCoalStatisInfoByHttpRequest(formattedBeginTime, formattedEndTime, statisticUnit); } void CoalStatisticsChartWidget::initCoalStatisticsBarChart() { // 创建图表 m_chart = new QChart(); m_chart->setBackgroundBrush(Qt::transparent); m_chart->setMargins(QMargins(0, 0, 0, 0)); m_chart->legend()->hide(); // 创建图表视图 m_chartView = new QChartView(m_chart); m_chartView->setBackgroundBrush(Qt::transparent); m_chartView->setRenderHint(QPainter::Antialiasing); m_chartView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); // 创建柱状图数据集 m_series = new QBarSeries(); m_chart->addSeries(m_series); // // 初始化 QDateTimeAxis 作为 X 轴 // m_axisX = new QDateTimeAxis(); // m_axisX->setFormat("yyyy-MM-dd HH"); // 设置时间格式 // // m_axisX->setTitleText("时间"); // m_axisX->setLabelsColor(Qt::gray); // // 设置 X 轴范围为最近6小时 // QDateTime currentTime = QDateTime::currentDateTime(); // QDateTime startTime = currentTime.addSecs(-6 * 3600); // 当前时间前6小时 // m_axisX->setRange(startTime, currentTime); // m_chart->addAxis(m_axisX, Qt::AlignBottom); // m_series->attachAxis(m_axisX); // 设置Y轴 m_axisY = new QValueAxis; m_axisY->setTitleText("吨"); m_axisY->setLabelsColor(Qt::gray); m_axisY->setRange(0, 100); m_chart->addAxis(m_axisY, Qt::AlignLeft); m_series->attachAxis(m_axisY); // 布局设置 QVBoxLayout* layout = static_cast(ui->widget_coalChart->layout()); if (!layout) { layout = new QVBoxLayout(ui->widget_coalChart); ui->widget_coalChart->setLayout(layout); } layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); if (layout->indexOf(m_chartView) == -1) { layout->addWidget(m_chartView); } } void CoalStatisticsChartWidget::formatTimeRange(const QString& beginTimeStr, const QString& endTimeStr, QString& formattedBeginTime, QString& formattedEndTime) { // 创建 QDateTime 对象 QDateTime beginTime = QDateTime::fromString(beginTimeStr, "yyyy/MM/d HH:mm"); QDateTime endTime = QDateTime::fromString(endTimeStr, "yyyy/MM/d HH:mm"); // 判断转换是否成功 // if (!beginTime.isValid() || !endTime.isValid()) { // qWarning() << "Invalid time format!"; // return; // } // 格式化为 "yyyy-MM-dd HH" 形式 formattedBeginTime = beginTime.toString("yyyy-MM-dd HH"); formattedEndTime = endTime.toString("yyyy-MM-dd HH"); } QList CoalStatisticsChartWidget::getLastSixFullHours(const QDateTime& currentTime) { // 将当前时间设置为整点 QDateTime roundedTime = currentTime; roundedTime.setTime(QTime(currentTime.time().hour(), 0)); // 设置时间到整点 bool insertTime = false; // 用于控制每隔一个插入时间,其他插入0 // 计算距当前整点数的前六个小时 QList timeList; for (int i = 6; i >= 1; --i) { QDateTime prevHour = roundedTime.addSecs(-i * 3600); // 向前推算每个整点 timeList.append(prevHour.toString("H")); } return timeList; } void CoalStatisticsChartWidget::initCustomCoalStatisticsBarChart() { // 创建图表 m_chart = new QChart(); m_chart->setBackgroundBrush(Qt::transparent); m_chart->setMargins(QMargins(0, 0, 0, 0)); m_chart->legend()->hide(); // 创建图表视图 m_chartView = new QChartView(m_chart); m_chartView->setBackgroundBrush(Qt::transparent); m_chartView->setRenderHint(QPainter::Antialiasing); m_chartView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); // 创建柱状图数据集 m_series = new QBarSeries(); m_chart->addSeries(m_series); // 创建X轴 m_axisX = new QBarCategoryAxis(); m_axisX->setLabelsColor(Qt::gray); m_axisX->setLineVisible(true); QDateTime currentTime = QDateTime::currentDateTime(); QList timeList = getLastSixFullHours(currentTime); m_axisX->append(timeList); m_chart->addAxis(m_axisX, Qt::AlignBottom); // 添加X轴到图表 m_series->attachAxis(m_axisX); // 将X轴与柱状图数据集关联 // 设置Y轴 m_axisY = new QValueAxis; m_axisY->setTitleText("吨"); m_axisY->setLabelsColor(Qt::gray); m_axisY->setRange(0, 100); m_chart->addAxis(m_axisY, Qt::AlignLeft); m_series->attachAxis(m_axisY); // 布局设置 QVBoxLayout* layout = static_cast(ui->widget_coalChart->layout()); if (!layout) { layout = new QVBoxLayout(ui->widget_coalChart); ui->widget_coalChart->setLayout(layout); } layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); if (layout->indexOf(m_chartView) == -1) { layout->addWidget(m_chartView); } } void CoalStatisticsChartWidget::initCustomPlotCoalStatisticsBarChart() { // 创建 QCustomPlot 图表 m_customPlot = new QCustomPlot(ui->widget_coalChart); m_customPlot->setBackground(Qt::transparent); // 设置背景透明 // 设置布局 QVBoxLayout* layout = static_cast(ui->widget_coalChart->layout()); if (!layout) { layout = new QVBoxLayout(ui->widget_coalChart); ui->widget_coalChart->setLayout(layout); } layout->setContentsMargins(0, 0, 0, 0); // 设置布局的边距 layout->setSpacing(0); // 设置布局的间距 if (layout->indexOf(m_customPlot) == -1) { layout->addWidget(m_customPlot); // 将 QCustomPlot 添加到布局中 } // 设置 X 轴 m_customPlot->xAxis->setLabel("时间"); m_customPlot->xAxis->setBasePen(QPen(Qt::gray)); // 设置轴线颜色 m_customPlot->xAxis->setTickPen(QPen(Qt::gray)); // 设置刻度线颜色 m_customPlot->xAxis->setSubTickPen(QPen(Qt::gray)); // 设置子刻度线颜色 m_customPlot->xAxis->setTickLabelColor(Qt::gray); // 设置刻度标签颜色 m_customPlot->xAxis->setTickLabelRotation(60); // 设置刻度标签的旋转角度,避免重叠 // 设置 Y 轴 m_customPlot->yAxis->setLabel("吨"); m_customPlot->yAxis->setBasePen(QPen(Qt::gray)); m_customPlot->yAxis->setTickPen(QPen(Qt::gray)); m_customPlot->yAxis->setSubTickPen(QPen(Qt::gray)); m_customPlot->yAxis->setTickLabelColor(Qt::gray); m_customPlot->yAxis->setRange(0, 100); // 设置 Y 轴的范围 // 创建柱状图 m_barGraph = new QCPBars(m_customPlot->xAxis, m_customPlot->yAxis); // 创建柱状图对象 m_barGraph->setWidth(0.2); // 设置柱子的宽度 m_barGraph->setPen(QPen(Qt::transparent)); // 设置柱子没有边框 m_barGraph->setBrush(QColor(0, 120, 255)); // 设置柱子的颜色 // 获取时间列表并设置到 X 轴 QDateTime currentTime = QDateTime::currentDateTime(); QList timeList = getLastSixFullHours(currentTime); QVector ticks; QVector labels; for (int i = 0; i < timeList.size(); ++i) { ticks.append(timeList[i]); // 设置刻度的位置 // labels.append(timeList[i]); // 设置刻度标签(时间) // m_customPlot->xAxis->setLabel(timeList[i]); } m_customPlot->xAxis->setTicks(true); // 设置 X 轴刻度的位置 m_customPlot->xAxis->setTickLabels(true); // 设置刻度标签 // 设置 Y 轴的数据,这里用随机数作为示例 QVector data; // Y 轴的数据 for (int i = 0; i < timeList.size(); ++i) { data.append(rand() % 100); // 使用随机数填充数据,实际应用中应替换为真实数据 } // m_barGraph->setData(ticks, data); // 设置柱状图的数据 // 重新绘制图表 m_customPlot->replot(); } void CoalStatisticsChartWidget::getCoalStatisInfoByHttpRequest( const QString& beginTime, const QString& endTime, const QString& statisticUnit) { // 使用类成员变量 QNetworkAccessManager QNetworkAccessManager* manager = new QNetworkAccessManager(this); QString coalStaticUrl = m_systemSetting->value("coalStaticInterface/url").toString(); // URL QUrl url(coalStaticUrl); QNetworkRequest request(url); // Form data QHttpMultiPart* multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); // begin_time 参数 QHttpPart beginTimePart; beginTimePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"begin_time\"")); beginTimePart.setBody(beginTime.toUtf8()); // end_time 参数 QHttpPart endTimePart; endTimePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"end_time\"")); endTimePart.setBody(endTime.toUtf8()); // 统计单位参数 QHttpPart statisticUnitPart; statisticUnitPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"statistic_unit\"")); statisticUnitPart.setBody(statisticUnit.toUtf8()); // 将表单字段附加到 multipart 请求体中 multiPart->append(beginTimePart); multiPart->append(endTimePart); multiPart->append(statisticUnitPart); // 发送 POST 请求 QNetworkReply* reply = manager->post(request, multiPart); // 连接信号和槽 QObject::connect(reply, &QNetworkReply::finished, [this, reply, multiPart]() { if (reply->error() == QNetworkReply::NoError) { // 处理成功的响应 QByteArray responseData = reply->readAll(); QJsonDocument jsonResponse = QJsonDocument::fromJson(responseData); QJsonObject jsonObj = jsonResponse.object(); int code = jsonObj["code"].toInt(); QString message = jsonObj["message"].toString(); QJsonObject data = jsonObj["data"].toObject(); m_toalValue = data["total_volum"].toDouble(); QJsonObject statisticUnitVolum = data["statistic_unit_volum"].toObject(); int statisticUnitVolumSize = statisticUnitVolum.count(); // QString statisticUnitVolumSizeString = "查询结果数" + QString::number(statisticUnitVolumSize); // emit querySuccessInfo(statisticUnitVolumSizeString); // QString totalVolumeString = "总吨数" + QString::number(m_toalValue); // emit querySuccessInfo(totalVolumeString); ui->label_totalVolume->clear(); ui->label_totalVolume->setText(QString("煤量总计:%1吨").arg(m_toalValue * m_systemSetting->value("system/different").toDouble())); m_volumeDataMap.clear(); // 计算整体需要减少的总量 double reduction = m_toalValue * 0.5; // 减去50% // 计算每个值应该减少的比例 double currentReduction = 0; // 遍历 statistic_unit_volum 中的键值对并存入 volumeDataMap for (const QString& key : statisticUnitVolum.keys()) { double value = statisticUnitVolum.value(key).toDouble(); // 计算每个值所减少的比例 double proportionalReduction = (value / m_toalValue) * reduction; m_volumeDataMap.insert(key, value - proportionalReduction); currentReduction += proportionalReduction; } // 更新查询的数据至图表 if (!m_volumeDataMap.isEmpty()) { updateCoalStatisticsChart(m_volumeDataMap); } } else { // 处理错误 QString errorString = reply->errorString(); emit querySuccessInfo(errorString); qDebug() << "Error:" << errorString; } // 清理资源 reply->deleteLater(); multiPart->deleteLater(); }); } void CoalStatisticsChartWidget::updateCoalStatisticsChart(const QMap& volumeDataMap) { // 清除旧数据 m_series->clear(); // 创建新的数据集 QBarSet* set = new QBarSet("煤量"); // 用于存储时间标签 QList categories; // 将字符串格式的时间转换为 QDateTime,并准备时间标签 for (auto it = volumeDataMap.begin(); it != volumeDataMap.end(); ++it) { // 将时间字符串转换为 QDateTime 对象 QDateTime time = QDateTime::fromString(it.key(), "yyyy-MM-dd HH"); // 如果转换失败,跳过这个数据项 if (!time.isValid()) { continue; } *set << it.value(); // 将数据量加入到数据集 // 根据选择的时间单位,格式化时间标签 QString label; if (ui->comboBox_unit->currentText() == QStringLiteral("时")) { label = time.toString("H"); } else if (ui->comboBox_unit->currentText() == QStringLiteral("日")) { label = time.toString("dd"); // 使用 'dd' 来格式化日期 } else if (ui->comboBox_unit->currentText() == QStringLiteral("月")) { label = time.toString("MM"); // 使用 'MM' 来格式化月份 } else if (ui->comboBox_unit->currentText() == QStringLiteral("年")) { label = time.toString("yyyy"); // 使用 'yyyy' 来格式化年份 } categories.append(label); // 将时间标签添加到列表 } // 将数据集添加到 series m_series->append(set); // 使用 QCategoryAxis 设置 X 轴为字符串格式的时间标签 m_axisX->clear(); // 清除之前的标签 m_axisX->append(categories); // 将新的时间标签添加到 X 轴 // 将 X 轴绑定到 series // m_chart->addAxis(m_axisX, Qt::AlignBottom); // m_series->attachAxis(m_axisX); // 更新 Y 轴范围 double maxValue = *std::max_element(volumeDataMap.begin(), volumeDataMap.end()); m_axisY->setRange(0, maxValue + 10); // 设置为最大值并留出余量 }