2025-05-23T13:52:13

This commit is contained in:
yuntang 2025-05-23 13:52:14 +08:00
parent 14a507ad45
commit dd3d99a8a2
10 changed files with 230 additions and 131 deletions

Binary file not shown.

Binary file not shown.

View File

@ -3,7 +3,7 @@ QT += core gui serialport printsupport
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
CONFIG += console
#CONFIG += console
CONFIG+=precompile_header
PRECOMPILED_HEADER=stable.h

View File

@ -284,6 +284,7 @@ QPair<QPointF, QPointF> PointCalculate::calculateStartAndEndPoint()
{
QPair<QPointF,QPointF> leftMaxDiffPointPair = PointCalculate::calculateMaxDiffPointLeft();
QPair<QPointF,QPointF> rightMaxDiffPointPair = PointCalculate::calculateMaxDiffPointRight();
#if 0
logde<<"b1:"<<leftMaxDiffPointPair.first.x()<<","<<leftMaxDiffPointPair.first.y();
logde<<"b2:"<<leftMaxDiffPointPair.second.x()<<","<<leftMaxDiffPointPair.second.y();
@ -399,6 +400,8 @@ QPointF PointCalculate::getIntersection(const Line& line1, const Line& line2) {
// return {x, y};
return QPointF(x,y);
}
#if 1
QPointF PointCalculate::getClosestPointByX(const float targetX)
{
QPointF resultPointF;
@ -420,6 +423,31 @@ QPointF PointCalculate::getClosestPointByX(const float targetX)
return resultPointF;
}
#endif
Global::ExperimentData PointCalculate::getClosestDataByTemperature(const float temp)
{
ExperimentData resultData;
#if 0
if(temp < _dataVtr.first().sampleTemp ||
temp > _dataVtr.last().sampleTemp){
return resultData;
}
#endif
float minDiff = std::numeric_limits<float>::max();
for(Global::ExperimentData &ed:_dataVtr){
float diff = std::abs(ed.sampleTemp - temp);
if (diff < minDiff) {
minDiff = diff;
resultData = ed;
}
}
return resultData;
}
QString PointCalculate::textFormatNumbericalLabel(const QPointF point)
{
@ -466,7 +494,8 @@ QString PointCalculate::textFormatGlassTranstion(const float t1,const float tg,c
return QString("T1%1℃\n"
"Tg%2℃\n"
"T2%3℃"
).arg(QString::number(t1, 'f', 3))
)
.arg(QString::number(t1, 'f', 3))
.arg(QString::number(tg, 'f', 3))
.arg(QString::number(t2, 'f', 3));
}
@ -715,6 +744,16 @@ QPair<float, float> PointCalculate::getMinAndMaxOfSampleTemp()
return qMakePair<float,float>(sampleTempMin,sampleTempMax);
}
QPair<Global::ExperimentData, Global::ExperimentData> PointCalculate::calculateStartAndEndData()
{
QPair<QPointF,QPointF> leftAndRightPair = calculateStartAndEndPoint();
ExperimentData leftEd = getClosestDataByTemperature(leftAndRightPair.first.x());
ExperimentData rightEd = getClosestDataByTemperature(leftAndRightPair.second.x());
return qMakePair<Global::ExperimentData, Global::ExperimentData> (leftEd,rightEd);
}
QPair<float, float> PointCalculate::getMinAndMaxOfRunTime()
{
float runTimeMax = std::numeric_limits<float>::min();
@ -749,4 +788,35 @@ QPair<float, float> PointCalculate::getMinAndMaxOfDSC()
return qMakePair<float,float>(dscMin,dscMax);
}
QString PointCalculate::textFormatNumbericalLabelWithTime(const QPointF point)
{
return QString("数值:\n"
"%1 min,%2"
).arg(QString::number(point.x(), 'f', 3))
.arg(QString::number(point.y(), 'f', 3));
}
QString PointCalculate::textFormatStartPointWithTime(const QPointF point)
{
return QString("外推起始点:\n"
"%1 min"
).arg(QString::number(point.x(), 'f', 3));
}
QString PointCalculate::textFormatEndPointWithTime(const QPointF point)
{
return QString("外推终止点:\n"
"%1 min"
).arg(QString::number(point.x(), 'f', 3));
}
QString PointCalculate::textFormatGlassTranstionWithTime(const float t1, const float tg, const float t2)
{
return QString("T1%1 min\n"
"Tg%2 min\n"
"T2%3 min"
)
.arg(QString::number(t1, 'f', 3))
.arg(QString::number(tg, 'f', 3))
.arg(QString::number(t2, 'f', 3));
}

View File

@ -7,6 +7,8 @@
#include "global.h"
namespace PointCalculate{
using namespace Global;
void setAnalysisData(const QVector<Global::ExperimentData>&);
//QPair<QPointF,QPointF> getStartAndEndPoint();
@ -21,6 +23,7 @@ QVector<QPointF> getPointVtrInXRange(const float, const float);
void setRegionPointX(const float,const float);
ExperimentData getClosestDataByTemperature(const float);
QPointF getClosestPointByX(const float);
QVector<QPointF> getNearbyPointGroupByX(const float);
@ -33,6 +36,8 @@ QPair<float, float> getTheMaximumAndMinimumValuesOfTime(
const double min,const double max);
QPair<QPointF,QPointF> calculateStartAndEndPoint();
QPair<ExperimentData,ExperimentData> calculateStartAndEndData();
float calculateArea();
double obtainTimeValueBasedOnTemperatureValue(const double sampleTemp);
@ -45,10 +50,18 @@ QString textFormatPeakPointWithTime(const float enthalpyValue,
const float peakValue,
const float startPoint,
const float endPoint);
QString textFormatNumbericalLabel(const QPointF);
QString textFormatNumbericalLabelWithTime(const QPointF);
QString textFormatStartPoint(const QPointF);
QString textFormatStartPointWithTime(const QPointF);
QString textFormatEndPoint(const QPointF);
QString textFormatEndPointWithTime(const QPointF);
QString textFormatGlassTranstion(const float t1,const float tg,const float t2);
QString textFormatGlassTranstionWithTime(const float t1,const float tg,const float t2);
// glass transition
QPair<float,float> getCurveInflectionPointTangent(const float,const float);

View File

@ -79,13 +79,11 @@ int XlsxHandler::readFile(const QString filePath, Global::CurveFileData &cfd)
phaseTotalVtr.push_back(phaseTotal);
// print
logde<<"index:"<<i<<",phase cut off temp:"<<phaseTotal.phase.cutoff_temp;
// logde<<"index:"<<i<<",phase cut off temp:"<<phaseTotal.phase.cutoff_temp;
}
logde<<"index:"<<cfd.phaseTotalVtr.first().phaseIndex
<<",phase cut off temp:"<<cfd.phaseTotalVtr.first().phase.cutoff_temp;
logde<<"dataIndex:"<<dataIndex;
// logde<<"index:"<<cfd.phaseTotalVtr.first().phaseIndex
// <<",phase cut off temp:"<<cfd.phaseTotalVtr.first().phase.cutoff_temp;
readAnalysisOperation(workSheet,dataIndex,cfd);
@ -117,8 +115,11 @@ void XlsxHandler::readPhaseData(QXlsx::Worksheet *workSheet, int &startLineIndex
data.runTime = workSheet->cellAt(startLineIndex, 2)->value().toDouble();
data.sampleTemp = workSheet->cellAt(startLineIndex, 3)->value().toDouble();
data.dsc = workSheet->cellAt(startLineIndex, 4)->value().toDouble();
data.constantTempTime = workSheet->cellAt(startLineIndex, 5)->value().toDouble();
phaseTotal.dataVtr.push_back(data);
if(data.runTime != 0){
phaseTotal.dataVtr.push_back(data);
}
startLineIndex++;
}

View File

@ -130,6 +130,10 @@ void clearExperimentData()
_currentPhase = -1;
}
bool isZero(double value, double epsilon) {
return std::abs(value) < epsilon;
}
}
#if 0

View File

@ -115,7 +115,7 @@ extern bool _displayTimeValue;
QString converDoubleToStr(const double);
void quadraticLeastSquaresFit(double x[], double y[], int n, double coeff[]);
double findNegativeStartPoint(double m, double b, double start, double end);
bool isZero(double value, double epsilon = 1e-9);
};
#endif // GLOBAL_H

View File

@ -104,75 +104,19 @@ CentralWidget::~CentralWidget()
void CentralWidget::switchAxisMode()
{
if(Global::_mode != Global::Mode::Analysis){
return;
}
if(_axisMode == AxisMode::SingleY){
_axisMode = AxisMode::DoubleY;
clearData(ClearDataMode::All);
#if 0
_customPlot->yAxis2->setVisible(true);
_customPlot->yAxis2->setLabel("Time/min");
for(Global::CurveFileData& cfd:Global::_curveFileDataVtr){
for(Global::PhaseTotalInfo& pti:cfd.phaseTotalVtr){
QVector<Global::ExperimentData> dataVtr;
QVector<double> tVtr,xVtr, yVtr;
int index = 0;
for (Global::ExperimentData &ed : pti.dataVtr)
{
tVtr.push_back(index++);
xVtr.push_back(ed.sampleTemp);
yVtr.push_back(ed.runTime);
}
double yMin = yVtr.first();
double yMax = yVtr.last();
double tick = (yMax - yMin) / 4;
double axisMin = yMin - tick;
double axisMax = yMax + tick;
_customPlot->yAxis2->setRange(axisMin,axisMax);
QCPCurve* curve = new QCPCurve(_customPlot->xAxis, _customPlot->yAxis2);
curve->setData(tVtr, xVtr, yVtr);
curve->setPen(QPen(QColor(Qt::red)));
curve->setObjectName(Global::CurveOfTimeTypeObjectName);
// logde<<"plottableCount count:"<<_customPlot->plottableCount();
}
}
#endif
}else{
logde<<"_axisMode == AxisMode::DoubleY ...";
_axisMode = AxisMode::SingleY;
clearData(ClearDataMode::All);
#if 0
_customPlot->yAxis2->setVisible(false);
_customPlot->xAxis->setLabel(AxisTemperature);
for (int i = _customPlot->plottableCount() - 1; i >= 0; --i) {
QCPAbstractPlottable* plottable = _customPlot->plottable(i);
if (auto curve = dynamic_cast<QCPCurve*>(plottable)) {
if(curve && curve->objectName() == Global::CurveOfTimeTypeObjectName){
_customPlot->removePlottable(curve);
}
}
}
#endif
}
uiLoadXlsxFileData();
clearData(ClearDataMode::JustUi);
uiLoadXlsxFileData();
}
void CentralWidget::setAnalysisMode(const AnalysisMode mode)
@ -571,7 +515,6 @@ void CentralWidget::uiLoadXlsxFileData()
PointCalculate::setAnalysisData(pti.dataVtr);
// Load data.
QVector<Global::ExperimentData> dataVtr;
QVector<double> tVtr,xVtr, yVtr;
@ -808,6 +751,21 @@ void CentralWidget::glassTransitionHandle(const double x1,const double x2,const
QString str = PointCalculate::textFormatGlassTranstion(intersection1.x(),
averagePoint.x(),
intersection2.x());
if(_axisMode == AxisMode::DoubleY){
Global::ExperimentData intersection1Ed =
PointCalculate::getClosestDataByTemperature(intersection1.x());
Global::ExperimentData averageEd =
PointCalculate::getClosestDataByTemperature(averagePoint.x());
Global::ExperimentData intersection2Ed =
PointCalculate::getClosestDataByTemperature(intersection2.x());
averagePoint = QPointF(averageEd.runTime,averageEd.dsc);
str = PointCalculate::textFormatGlassTranstionWithTime(
intersection1Ed.runTime,
averageEd.runTime,
intersection2Ed.runTime);
}
drawText(averagePoint,str);
@ -988,6 +946,7 @@ void CentralWidget::drawText(const QPointF point, const QString text,const QStri
void CentralWidget::fillGraph(const double x1, const double x2,const QString objectName)
{
#if 0
double y1 = PointCalculate::getClosestPointByX(x1).y();
double y2 = PointCalculate::getClosestPointByX(x2).y();
@ -997,11 +956,29 @@ void CentralWidget::fillGraph(const double x1, const double x2,const QString obj
yVtr.push_back(y1);
yVtr.push_back(y2);
#endif
Global::ExperimentData x1Ed = PointCalculate::getClosestDataByTemperature(x1);
Global::ExperimentData x2Ed = PointCalculate::getClosestDataByTemperature(x2);
QVector<double> xVtr,yVtr;
xVtr.push_back(x1Ed.sampleTemp);
xVtr.push_back(x2Ed.sampleTemp);
yVtr.push_back(x1Ed.dsc);
yVtr.push_back(x2Ed.dsc);
if(_axisMode == AxisMode::DoubleY){
xVtr.clear();
xVtr.push_back(x1Ed.runTime);
xVtr.push_back(x2Ed.runTime);
}
QCPGraph *mainGraph = _customPlot->addGraph();
mainGraph->setData(xVtr, yVtr);
mainGraph->setPen(QPen(Qt::red, 1));
//
QVector<Global::ExperimentData> curveDataVtr =
PointCalculate::getDataInXRange(x1,x2);
@ -1010,7 +987,11 @@ void CentralWidget::fillGraph(const double x1, const double x2,const QString obj
for(int i = 0;i < curveDataVtr.size();i++){
Global::ExperimentData &ed = curveDataVtr[i];
fillX<<ed.sampleTemp;
if(_axisMode == AxisMode::DoubleY){
fillX<<ed.runTime;
}else{
fillX<<ed.sampleTemp;
}
fillY<<ed.dsc;
}
@ -1029,18 +1010,6 @@ void CentralWidget::clearData(const CentralWidget::ClearDataMode mode)
{
switch (mode) {
case ClearDataMode::All:
break;
case ClearDataMode::JustUi:
break;
case ClearDataMode::Undo:
break;
default:break;
}
if(mode == ClearDataMode::All){
}else if(mode == ClearDataMode::All){
//
_analysisFilePathVtr.clear();
// Clear data.
logde<<"clearExperimentData...";
@ -1053,42 +1022,12 @@ void CentralWidget::clearData(const CentralWidget::ClearDataMode mode)
_line2->setVisible(false);
_currentCurve = nullptr;
case ClearDataMode::JustUi:
//ui
// Clear the data of graph.
for (int i = _customPlot->plottableCount() - 1; i >= 0; --i) {
QCPAbstractPlottable* plottable = _customPlot->plottable(i);
if (auto curve = dynamic_cast<QCPCurve*>(plottable)) {
_customPlot->removePlottable(curve);
ItemManager::removeItem(curve);
}
}
// Clear graph on plot.
for (int i = _customPlot->graphCount() - 1; i >= 0; --i) {
QCPGraph *graph = _customPlot->graph(i);
_customPlot->removeGraph(graph);
ItemManager::removeItem(graph);
}
// Delete items.
QList<QCPAbstractItem *> itemsToKeep;
itemsToKeep << _line1 << _line2;
for (int i = _customPlot->itemCount() - 1; i >= 0; --i) {
QCPAbstractItem *item = _customPlot->item(i);
if (!itemsToKeep.contains(item)) {
_customPlot->removeItem(item);
ItemManager::removeItem(item);
}
}
//
AnalysisOperationRecorder::_analysisOperationVtr.clear();
}else if(mode == ClearDataMode::Undo){
clearAllUiData();
break;
case ClearDataMode::Undo:
{
// Clear the data of graph.
for (int i = _customPlot->plottableCount() - 1; i >= 0; --i) {
QCPAbstractPlottable* plottable = _customPlot->plottable(i);
@ -1130,11 +1069,48 @@ void CentralWidget::clearData(const CentralWidget::ClearDataMode mode)
//
AnalysisOperationRecorder::removeTheLastAnalysisOperation();
}
break;
default:break;
}
_customPlot->replot();
}
void CentralWidget::clearAllUiData()
{
// Clear the data of graph.
for (int i = _customPlot->plottableCount() - 1; i >= 0; --i) {
QCPAbstractPlottable* plottable = _customPlot->plottable(i);
if (auto curve = dynamic_cast<QCPCurve*>(plottable)) {
_customPlot->removePlottable(curve);
ItemManager::removeItem(curve);
}
}
// Clear graph on plot.
for (int i = _customPlot->graphCount() - 1; i >= 0; --i) {
QCPGraph *graph = _customPlot->graph(i);
_customPlot->removeGraph(graph);
ItemManager::removeItem(graph);
}
// Delete items.
QList<QCPAbstractItem *> itemsToKeep;
itemsToKeep << _line1 << _line2;
for (int i = _customPlot->itemCount() - 1; i >= 0; --i) {
QCPAbstractItem *item = _customPlot->item(i);
if (!itemsToKeep.contains(item)) {
_customPlot->removeItem(item);
ItemManager::removeItem(item);
}
}
}
void CentralWidget::deleteCurve(const QString objectName)
{
for (int i = _analysisFilePathVtr.size() - 1; i >= 0; --i) {
@ -1195,16 +1171,21 @@ void CentralWidget::loadAnalysisData(
switch (mode) {
case AnalysisMode::NumericalLabel:
{
QPointF selectPoint = PointCalculate::getClosestPointByX(x1);
// QPointF selectPoint = PointCalculate::getClosestPointByX(x1);
// logde<<"lin1 x:"<<x1;
Global::ExperimentData ed = PointCalculate::getClosestDataByTemperature(x1);
if(selectPoint.isNull()){
if(Global::isZero(ed.dsc)){
QMessageBox::warning((QWidget*)this->parent(), "warnning", "曲线选择错误.");
return;
}
QPointF selectPoint(ed.sampleTemp,ed.dsc);
QString str = PointCalculate::textFormatNumbericalLabel(selectPoint);
if(_axisMode == AxisMode::DoubleY){
selectPoint.setX(ed.runTime);
str = PointCalculate::textFormatNumbericalLabelWithTime(selectPoint);
}
drawText(selectPoint,str,objectName);
@ -1214,19 +1195,32 @@ void CentralWidget::loadAnalysisData(
case AnalysisMode::StopPoint:{
PointCalculate::setRegionPointX(x1,x2);
QPair<QPointF, QPointF> startEndPointPair =
PointCalculate::calculateStartAndEndPoint();
// QPair<QPointF, QPointF> startEndPointPair =
// PointCalculate::calculateStartAndEndPoint();
QPair<Global::ExperimentData,Global::ExperimentData>
startEndDataPair = PointCalculate::calculateStartAndEndData();
//
QPointF point;
QString str;
AnaOpRecorder::AnalysisOperation ao;
if(mode == AnalysisMode::StartPoint){
point = startEndPointPair.first;
str = PointCalculate::textFormatStartPoint(point);
if(_axisMode == AxisMode::SingleY){
point = QPointF(startEndDataPair.first.sampleTemp,startEndDataPair.first.dsc);
str = PointCalculate::textFormatStartPoint(point);
}else{
point = QPointF(startEndDataPair.first.runTime,startEndDataPair.first.dsc);
str = PointCalculate::textFormatStartPointWithTime(point);
}
}else{
point = startEndPointPair.second;
str = PointCalculate::textFormatEndPoint(point);
if(_axisMode == AxisMode::SingleY){
point = QPointF(startEndDataPair.second.sampleTemp,startEndDataPair.second.dsc);
str = PointCalculate::textFormatEndPoint(point);
}else{
point = QPointF(startEndDataPair.second.runTime,startEndDataPair.second.dsc);
str = PointCalculate::textFormatEndPointWithTime(point);
}
}
drawText(point,str,objectName);
@ -1241,7 +1235,7 @@ void CentralWidget::loadAnalysisData(
PointCalculate::setRegionPointX(x1,x2);
//enthalpy
double sampleWeight = 0.0f;
double sampleWeight = 1.0f;
for(Global::CurveFileData& cfd:Global::_curveFileDataVtr){
for(Global::PhaseTotalInfo& pti:cfd.phaseTotalVtr){
@ -1281,7 +1275,25 @@ void CentralWidget::loadAnalysisData(
<<startEndPointPair.second.x();
QString str;
if(Global::_displayTimeValue){
if(_axisMode == AxisMode::DoubleY){
double peakPointTime = PointCalculate::obtainTimeValueBasedOnTemperatureValue(peakPoint.x());
double startPointTime = PointCalculate::obtainTimeValueBasedOnTemperatureValue(startEndPointPair.first.x());
double endPointTime = PointCalculate::obtainTimeValueBasedOnTemperatureValue(startEndPointPair.second.x());
str = PointCalculate::textFormatPeakPointWithTime(
enthalpyValue,
peakPointTime,
startPointTime,
endPointTime);
Global::ExperimentData peakPointEd =
PointCalculate::getClosestDataByTemperature(peakPoint.x());
peakPoint = QPointF(peakPointEd.runTime,peakPointEd.dsc);
drawText(peakPoint,str,objectName);
}
else if(Global::_displayTimeValue){
double peakPointTime = PointCalculate::obtainTimeValueBasedOnTemperatureValue(peakPoint.x());
double startPointTime = PointCalculate::obtainTimeValueBasedOnTemperatureValue(startEndPointPair.first.x());
double endPointTime = PointCalculate::obtainTimeValueBasedOnTemperatureValue(startEndPointPair.second.x());
@ -1334,8 +1346,6 @@ void CentralWidget::loadAnalysisData(
}
}
void CentralWidget::clearAllData()
{
clearData(ClearDataMode::All);
@ -1348,7 +1358,6 @@ QPixmap CentralWidget::getPixMap()
return _customPlot->toPixmap();
}
void CentralWidget::slotAxisModify(const float temp)
{
_customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);

View File

@ -99,6 +99,8 @@ private:
JustUi
};
void clearData(const ClearDataMode);
void clearAllUiData();
void deleteCurve(const QString);
void loadAnalysisData(const AnalysisMode mode,const double x1,const double x2,const QString objectName);