From 8dc904524b2dbd0b221f6ec865f5a4fa2e84d343 Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Mon, 1 Sep 2025 15:46:38 -0600 Subject: [PATCH 1/7] First example compiling --- CMakeLists.txt | 17 +- src/openstudio_lib/CMakeLists.txt | 2 + src/openstudio_lib/HVACSystemsView.cpp | 229 +++++++++++++------------ 3 files changed, 132 insertions(+), 116 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a4f932bc..862e61b3c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -528,6 +528,8 @@ set(QT_VERSION "6.5.2" CACHE STRING "Qt target version, defaults to 6.5.2") # For AboutBox, but also validates that the version is valid string(TIMESTAMP CURRENT_YEAR "%Y") +string(REGEX MATCH "^([0-9]+)" + QT_VERSION_MAJOR ${QT_VERSION}) string(REGEX MATCH "^([0-9]+\\.[0-9]+)" QT_VERSION_MAJOR_MINOR ${QT_VERSION}) if(NOT QT_VERSION_MAJOR_MINOR) @@ -563,7 +565,6 @@ find_file(qweb_resources_200 NAMES qtwebengine_resources_200p.pak PATHS "${QT_IN # QT_WEB_LIBS are linked by OS App and openstudio_lib but not by openstudio_modeleditor.so or openstudio_modeleditor list(APPEND QT_WEB_LIBS Qt6::WebEngineCore) list(APPEND QT_WEB_LIBS Qt6::WebEngineWidgets) -list(APPEND QT_WEB_LIBS Qt6::Charts) set_target_properties(${QT_WEB_LIBS} PROPERTIES INTERFACE_LINK_LIBRARIES "") if(NOT APPLE) @@ -658,10 +659,20 @@ if(UNIX) list(APPEND QT_INCLUDES ${Qt6XcbQpa_INCLUDE_DIRS}) endif() -set(CMAKE_AUTOMOC OFF) - +# Make JKQTPlotter available after finding Qt include(FetchContent) +set(JKQtPlotter_BUILD_EXAMPLES OFF) + +FetchContent_Declare(JKQTPlotter + GIT_REPOSITORY https://github.com/jkriege2/JKQtPlotter.git + GIT_TAG v4.0.3) + +FetchContent_MakeAvailable(JKQTPlotter) + +set(CMAKE_AUTOMOC OFF) + +# Get the OpenStudio Coalition Measures repo FetchContent_Declare( openstudio-coalition-measures GIT_REPOSITORY https://github.com/openstudiocoalition/openstudio-coalition-measures.git diff --git a/src/openstudio_lib/CMakeLists.txt b/src/openstudio_lib/CMakeLists.txt index 917c074b2..820de4366 100644 --- a/src/openstudio_lib/CMakeLists.txt +++ b/src/openstudio_lib/CMakeLists.txt @@ -774,6 +774,8 @@ set(${target_name}_depends openstudio::openstudiolib ${QT_LIBS} ${QT_WEB_LIBS} + JKQTCommonSharedLib + JKQTPlotterSharedLib ) if(WIN32) list(APPEND ${target_name}_depends qtwinmigrate) diff --git a/src/openstudio_lib/HVACSystemsView.cpp b/src/openstudio_lib/HVACSystemsView.cpp index 2ff14535f..946b83140 100644 --- a/src/openstudio_lib/HVACSystemsView.cpp +++ b/src/openstudio_lib/HVACSystemsView.cpp @@ -35,10 +35,9 @@ #include #include -#include -#include -#include -#include +#include +#include + #include namespace openstudio { @@ -687,34 +686,38 @@ OAResetSPMView::OAResetSPMView(const model::SetpointManagerOutdoorAirReset& spm) auto* title = new QLabel(text); mainVLayout->addWidget(title); - auto* series = new QLineSeries; + // Create a JKQTPlotter widget + JKQTPlotter* plotter = new JKQTPlotter(); + JKQTPDatastore* ds = plotter->getDatastore(); + + // Generate the data for the plot + QVector x, y; const auto lowOATemp = spm.outdoorLowTemperature(); // 5 const auto highOATemp = spm.outdoorHighTemperature(); // 30 const auto lowVal = spm.setpointatOutdoorLowTemperature(); // 25 const auto highVal = spm.setpointatOutdoorHighTemperature(); // 18 - series->append(lowOATemp - 5, lowVal); - series->append(lowOATemp, lowVal); - series->append(highOATemp, highVal); - series->append(highOATemp + 5, highVal); - - auto* chart = new QChart; - chart->legend()->hide(); - chart->addSeries(series); - chart->createDefaultAxes(); - auto* xAxis = chart->axes(Qt::Horizontal)[0]; - xAxis->setTitleText("Outdoor Air Temperature [C]"); - auto* yAxis = chart->axes(Qt::Vertical)[0]; - yAxis->setTitleText("Setpoint Temperature [C]"); - yAxis->setRange(std::min(lowVal, highVal) - 2, std::max(lowVal, highVal) + 2); - - chart->setTitle("Setpoint Outdoor Air Temp Reset"); - chart->setAnimationOptions(QChart::SeriesAnimations); - - auto* m_defaultChartView = new QChartView(chart, this); - m_defaultChartView->setRenderHint(QPainter::Antialiasing); - m_defaultChartView->setMinimumSize(400, 400); - mainVLayout->addWidget(m_defaultChartView); + x.append(lowOATemp - 5); + y.append(lowVal); + x.append(lowOATemp); + y.append(lowVal); + x.append(highOATemp); + y.append(highVal); + x.append(highOATemp + 5); + y.append(highVal); + + // Add data to the datastore + size_t columnX = ds->addCopiedColumn(x, "x"); + size_t columnY = ds->addCopiedColumn(y, "y"); + + JKQTPXYLineGraph* graph = new JKQTPXYLineGraph(plotter); + graph->setXColumn(columnX); + graph->setYColumn(columnY); + graph->setTitle(QObject::tr("Setpoint Outdoor Air Temp Reset")); + plotter->getXAxis()->setAxisLabel("Outdoor Air Temperature [C]"); + plotter->getYAxis()->setAxisLabel("Setpoint Temperature [C]"); + plotter->setMinimumSize(400, 400); + mainVLayout->addWidget(plotter); mainVLayout->addStretch(); } @@ -735,34 +738,38 @@ SystemNodeResetSPMView::SystemNodeResetSPMView(const model::SetpointManagerSyste auto* title = new QLabel(text); mainVLayout->addWidget(title); - auto* series = new QLineSeries; + // Create a JKQTPlotter widget + JKQTPlotter* plotter = new JKQTPlotter(); + JKQTPDatastore* ds = plotter->getDatastore(); + + // Generate the data for the plot + QVector x, y; - const auto lowOATemp = spm.lowReferenceTemperature(); // 5 - const auto highOATemp = spm.highReferenceTemperature(); // 30 - const auto lowVal = spm.setpointatLowReferenceTemperature(); // 25 + const auto lowOATemp = spm.lowReferenceTemperature(); // 5 + const auto highOATemp = spm.highReferenceTemperature(); // 30 + const auto lowVal = spm.setpointatLowReferenceTemperature(); // 25 const auto highVal = spm.setpointatHighReferenceTemperature(); // 18 - series->append(lowOATemp - 5, lowVal); - series->append(lowOATemp, lowVal); - series->append(highOATemp, highVal); - series->append(highOATemp + 5, highVal); - - auto* chart = new QChart; - chart->legend()->hide(); - chart->addSeries(series); - chart->createDefaultAxes(); - auto* xAxis = chart->axes(Qt::Horizontal)[0]; - xAxis->setTitleText("System Node Temperature [C]"); - auto* yAxis = chart->axes(Qt::Vertical)[0]; - yAxis->setTitleText("Setpoint Temperature [C]"); - yAxis->setRange(std::min(lowVal, highVal) - 2, std::max(lowVal, highVal) + 2); - - chart->setTitle("Setpoint System Node Reset Temperature"); - chart->setAnimationOptions(QChart::SeriesAnimations); - - auto* m_defaultChartView = new QChartView(chart, this); - m_defaultChartView->setRenderHint(QPainter::Antialiasing); - m_defaultChartView->setMinimumSize(400, 400); - mainVLayout->addWidget(m_defaultChartView); + x.append(lowOATemp - 5); + y.append(lowVal); + x.append(lowOATemp); + y.append(lowVal); + x.append(highOATemp); + y.append(highVal); + x.append(highOATemp + 5); + y.append(highVal); + + // Add data to the datastore + size_t columnX = ds->addCopiedColumn(x, "x"); + size_t columnY = ds->addCopiedColumn(y, "y"); + + JKQTPXYLineGraph* graph = new JKQTPXYLineGraph(plotter); + graph->setXColumn(columnX); + graph->setYColumn(columnY); + graph->setTitle(QObject::tr("Setpoint System Node Reset Temperature")); + plotter->getXAxis()->setAxisLabel("System Node Temperature [C]"); + plotter->getYAxis()->setAxisLabel("Setpoint Temperature [C]"); + plotter->setMinimumSize(400, 400); + mainVLayout->addWidget(plotter); mainVLayout->addStretch(); } @@ -799,40 +806,38 @@ FollowOATempSPMView::FollowOATempSPMView(const model::SetpointManagerFollowOutdo new QLabel(QString("Supply temperature follows the %1 temperature with an offset of %2 C.").arg(refTempType, QString::number(offset))); mainVLayout->addWidget(followOATempSPMlabel); - auto* series = new QLineSeries; - series->setName("Setpoint Temperature"); - auto* seriesOA = new QLineSeries; - seriesOA->setName(refTempType); - QRgb color1 = qRgb(255, 0, 0); - QPen pen1(color1); - pen1.setStyle(Qt::DotLine); - pen1.setWidth(1); - seriesOA->setPen(pen1); + // Create a JKQTPlotter widget + JKQTPlotter* plotter = new JKQTPlotter(); + JKQTPDatastore* ds = plotter->getDatastore(); + + // Generate the data for the plot + QVector x, y, yOA; std::vector xVals{-20, -15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40}; - for (const auto& x : xVals) { - double y = std::clamp(x + offset, minVal, maxVal); - series->append(x, y); - seriesOA->append(x, x); + for (const auto& xVal : xVals) { + x.append(xVal); + y.append(std::clamp(xVal + offset, minVal, maxVal)); + yOA.append(xVal); } - auto* chart = new QChart; - chart->legend()->hide(); - chart->addSeries(series); - chart->addSeries(seriesOA); - chart->createDefaultAxes(); - auto* xAxis = chart->axes(Qt::Horizontal)[0]; - xAxis->setTitleText(QString("%1 Temperature [C]").arg(refTempType)); - auto* yAxis = chart->axes(Qt::Vertical)[0]; - yAxis->setTitleText("Setpoint Temperature [C]"); - - chart->setTitle("Setpoint Follow Outdoor Air Temperature"); - chart->setAnimationOptions(QChart::SeriesAnimations); - - auto* m_defaultChartView = new QChartView(chart, this); - m_defaultChartView->setRenderHint(QPainter::Antialiasing); - m_defaultChartView->setMinimumSize(400, 400); - mainVLayout->addWidget(m_defaultChartView); + // Add data to the datastore + size_t columnX = ds->addCopiedColumn(x, "x"); + size_t columnY = ds->addCopiedColumn(y, "y"); + size_t columnYOA = ds->addCopiedColumn(yOA, "yOA"); + + JKQTPXYLineGraph* graph1 = new JKQTPXYLineGraph(plotter); + graph1->setXColumn(columnX); + graph1->setYColumn(columnY); + graph1->setTitle(QObject::tr("Setpoint Follow Outdoor Air Temperature")); + JKQTPXYLineGraph* graph2 = new JKQTPXYLineGraph(plotter); + graph1->setXColumn(columnX); + graph1->setYColumn(columnYOA); + graph1->setTitle(QObject::tr("Setpoint Follow Outdoor Air Temperature")); + + plotter->getXAxis()->setAxisLabel(QString("%1 Temperature [C]").arg(refTempType)); + plotter->getYAxis()->setAxisLabel("Setpoint Temperature [C]"); + plotter->setMinimumSize(400, 400); + mainVLayout->addWidget(plotter); mainVLayout->addStretch(); } @@ -850,40 +855,38 @@ FollowGroundTempSPMView::FollowGroundTempSPMView(const model::SetpointManagerFol new QLabel(QString("Supply temperature follows the Ground Temperature with an offset of %2 C.").arg(QString::number(offset))); mainVLayout->addWidget(followTempSPMlabel); - auto* series = new QLineSeries; - series->setName("Setpoint Temperature"); - auto* seriesOA = new QLineSeries; - seriesOA->setName("Ground Temperature"); - QRgb color1 = qRgb(255, 0, 0); - QPen pen1(color1); - pen1.setStyle(Qt::DotLine); - pen1.setWidth(1); - seriesOA->setPen(pen1); + // Create a JKQTPlotter widget + JKQTPlotter* plotter = new JKQTPlotter(); + JKQTPDatastore* ds = plotter->getDatastore(); + + // Generate the data for the plot + QVector x, y, yGround; std::vector xVals{-20, -15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40}; - for (const auto& x : xVals) { - double y = std::clamp(x + offset, minVal, maxVal); - series->append(x, y); - seriesOA->append(x, x); + for (const auto& xVal : xVals) { + x.append(xVal); + y.append(std::clamp(xVal + offset, minVal, maxVal)); + yGround.append(xVal); } - auto* chart = new QChart; - chart->legend()->hide(); - chart->addSeries(series); - chart->addSeries(seriesOA); - chart->createDefaultAxes(); - auto* xAxis = chart->axes(Qt::Horizontal)[0]; - xAxis->setTitleText("Ground Temperature [C]"); - auto* yAxis = chart->axes(Qt::Vertical)[0]; - yAxis->setTitleText("Setpoint Temperature [C]"); - - chart->setTitle("Setpoint Follow Ground Temperature"); - chart->setAnimationOptions(QChart::SeriesAnimations); - - auto* m_defaultChartView = new QChartView(chart, this); - m_defaultChartView->setRenderHint(QPainter::Antialiasing); - m_defaultChartView->setMinimumSize(400, 400); - mainVLayout->addWidget(m_defaultChartView); + // Add data to the datastore + size_t columnX = ds->addCopiedColumn(x, "x"); + size_t columnY = ds->addCopiedColumn(y, "y"); + size_t columnYGround = ds->addCopiedColumn(yGround, "yGround"); + + JKQTPXYLineGraph* graph1 = new JKQTPXYLineGraph(plotter); + graph1->setXColumn(columnX); + graph1->setYColumn(columnY); + graph1->setTitle(QObject::tr("Setpoint Follow Ground Temperature")); + JKQTPXYLineGraph* graph2 = new JKQTPXYLineGraph(plotter); + graph1->setXColumn(columnX); + graph1->setYColumn(columnYGround); + graph1->setTitle(QObject::tr("Setpoint Follow Ground Temperature")); + + plotter->getXAxis()->setAxisLabel("Ground Temperature [C]"); + plotter->getYAxis()->setAxisLabel("Setpoint Temperature [C]"); + plotter->setMinimumSize(400, 400); + mainVLayout->addWidget(plotter); mainVLayout->addStretch(); } From f65c6b5924fac09fa4f6468e2b37182eb2c81d17 Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Mon, 1 Sep 2025 15:57:15 -0600 Subject: [PATCH 2/7] Remove QtCharts from find_package --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 862e61b3c..efdb5ddb2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -546,7 +546,7 @@ message(STATUS "QT_INSTALL_DIR=${QT_INSTALL_DIR}") find_package(Qt6 ${QT_VERSION} COMPONENTS CoreTools GuiTools WidgetsTools QmlTools WebEngineCoreTools REQUIRED PATHS ${QT_INSTALL_DIR} NO_DEFAULT_PATH) -find_package(Qt6 ${QT_VERSION} COMPONENTS Core Core5Compat Gui Widgets Sql Svg Network Xml Concurrent PrintSupport Quick QuickWidgets Qml WebChannel Positioning WebEngineCore WebEngineWidgets Charts REQUIRED PATHS ${QT_INSTALL_DIR} NO_DEFAULT_PATH) +find_package(Qt6 ${QT_VERSION} COMPONENTS Core Core5Compat Gui Widgets Sql Svg Network Xml Concurrent PrintSupport Quick QuickWidgets Qml WebChannel Positioning WebEngineCore WebEngineWidgets REQUIRED PATHS ${QT_INSTALL_DIR} NO_DEFAULT_PATH) find_package(Qt6LinguistTools ${QT_VERSION} REQUIRED PATHS ${QT_INSTALL_DIR} NO_DEFAULT_PATH) From 5d4b4be73b5937c7ac298c48807b383c0967a649 Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Mon, 1 Sep 2025 16:18:47 -0600 Subject: [PATCH 3/7] Let's see if this will compile on CI --- CMakeLists.txt | 5 ++++- src/openstudio_app/CMakeLists.txt | 6 +++--- src/openstudio_lib/CMakeLists.txt | 3 +-- src/openstudio_lib/HVACSystemsView.cpp | 26 +++++++++++++------------- 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index efdb5ddb2..26f111bd4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -546,7 +546,7 @@ message(STATUS "QT_INSTALL_DIR=${QT_INSTALL_DIR}") find_package(Qt6 ${QT_VERSION} COMPONENTS CoreTools GuiTools WidgetsTools QmlTools WebEngineCoreTools REQUIRED PATHS ${QT_INSTALL_DIR} NO_DEFAULT_PATH) -find_package(Qt6 ${QT_VERSION} COMPONENTS Core Core5Compat Gui Widgets Sql Svg Network Xml Concurrent PrintSupport Quick QuickWidgets Qml WebChannel Positioning WebEngineCore WebEngineWidgets REQUIRED PATHS ${QT_INSTALL_DIR} NO_DEFAULT_PATH) +find_package(Qt6 ${QT_VERSION} COMPONENTS Core Core5Compat Gui Widgets Sql Svg Network Xml Concurrent OpenGL OpenGLWidgets Positioning PrintSupport Quick QuickWidgets Qml WebChannel WebEngineCore WebEngineWidgets REQUIRED PATHS ${QT_INSTALL_DIR} NO_DEFAULT_PATH) find_package(Qt6LinguistTools ${QT_VERSION} REQUIRED PATHS ${QT_INSTALL_DIR} NO_DEFAULT_PATH) @@ -670,6 +670,9 @@ FetchContent_Declare(JKQTPlotter FetchContent_MakeAvailable(JKQTPlotter) +list(APPEND JKQT_LIBS Qt6::WebEngineCore) +list(APPEND JKQT_LIBS Qt6::WebEngineWidgets) + set(CMAKE_AUTOMOC OFF) # Get the OpenStudio Coalition Measures repo diff --git a/src/openstudio_app/CMakeLists.txt b/src/openstudio_app/CMakeLists.txt index 5436c49bd..1c999dc0a 100644 --- a/src/openstudio_app/CMakeLists.txt +++ b/src/openstudio_app/CMakeLists.txt @@ -188,7 +188,7 @@ if( APPLE ) elseif( UNIX ) - foreach(LIB ${QT_LIBS} ${QT_WEB_LIBS}) + foreach(LIB ${QT_LIBS} ${QT_WEB_LIBS} ${JKQT_LIBS}) get_property(LIB_LOCATION TARGET ${LIB} PROPERTY LOCATION) list(APPEND QT_LIB_LOCATIONS "${LIB_LOCATION}") endforeach() @@ -387,7 +387,7 @@ if( NOT APPLE ) install(PROGRAMS $/D3Dcompiler_47.dll DESTINATION bin/ COMPONENT OpenStudioApp) install(PROGRAMS $/opengl32sw.dll DESTINATION bin/ COMPONENT OpenStudioApp) - foreach(LIB ${QT_LIBS} ${QT_WEB_LIBS}) + foreach(LIB ${QT_LIBS} ${QT_WEB_LIBS} ${JKQT_LIBS}) install(PROGRAMS $/$ DESTINATION bin/ COMPONENT OpenStudioApp) endforeach() @@ -408,7 +408,7 @@ if( NOT APPLE ) install(DIRECTORY $/xcbglintegrations/ DESTINATION bin/xcbglintegrations/ COMPONENT OpenStudioApp) # install(PROGRAMS $/xcbglintegrations/$ DESTINATION bin/xcbglintegrations/ COMPONENT OpenStudioApp) - foreach(LIB ${QT_LIBS} ${QT_WEB_LIBS}) + foreach(LIB ${QT_LIBS} ${QT_WEB_LIBS} ${JKQT_LIBS}) install(PROGRAMS $/$ DESTINATION bin/ COMPONENT OpenStudioApp) endforeach() diff --git a/src/openstudio_lib/CMakeLists.txt b/src/openstudio_lib/CMakeLists.txt index 820de4366..ef8494f80 100644 --- a/src/openstudio_lib/CMakeLists.txt +++ b/src/openstudio_lib/CMakeLists.txt @@ -774,8 +774,7 @@ set(${target_name}_depends openstudio::openstudiolib ${QT_LIBS} ${QT_WEB_LIBS} - JKQTCommonSharedLib - JKQTPlotterSharedLib + ${JKQT_LIBS} ) if(WIN32) list(APPEND ${target_name}_depends qtwinmigrate) diff --git a/src/openstudio_lib/HVACSystemsView.cpp b/src/openstudio_lib/HVACSystemsView.cpp index 946b83140..53544baa9 100644 --- a/src/openstudio_lib/HVACSystemsView.cpp +++ b/src/openstudio_lib/HVACSystemsView.cpp @@ -689,7 +689,7 @@ OAResetSPMView::OAResetSPMView(const model::SetpointManagerOutdoorAirReset& spm) // Create a JKQTPlotter widget JKQTPlotter* plotter = new JKQTPlotter(); JKQTPDatastore* ds = plotter->getDatastore(); - + // Generate the data for the plot QVector x, y; @@ -709,7 +709,7 @@ OAResetSPMView::OAResetSPMView(const model::SetpointManagerOutdoorAirReset& spm) // Add data to the datastore size_t columnX = ds->addCopiedColumn(x, "x"); size_t columnY = ds->addCopiedColumn(y, "y"); - + JKQTPXYLineGraph* graph = new JKQTPXYLineGraph(plotter); graph->setXColumn(columnX); graph->setYColumn(columnY); @@ -745,9 +745,9 @@ SystemNodeResetSPMView::SystemNodeResetSPMView(const model::SetpointManagerSyste // Generate the data for the plot QVector x, y; - const auto lowOATemp = spm.lowReferenceTemperature(); // 5 - const auto highOATemp = spm.highReferenceTemperature(); // 30 - const auto lowVal = spm.setpointatLowReferenceTemperature(); // 25 + const auto lowOATemp = spm.lowReferenceTemperature(); // 5 + const auto highOATemp = spm.highReferenceTemperature(); // 30 + const auto lowVal = spm.setpointatLowReferenceTemperature(); // 25 const auto highVal = spm.setpointatHighReferenceTemperature(); // 18 x.append(lowOATemp - 5); y.append(lowVal); @@ -806,7 +806,7 @@ FollowOATempSPMView::FollowOATempSPMView(const model::SetpointManagerFollowOutdo new QLabel(QString("Supply temperature follows the %1 temperature with an offset of %2 C.").arg(refTempType, QString::number(offset))); mainVLayout->addWidget(followOATempSPMlabel); - // Create a JKQTPlotter widget + // Create a JKQTPlotter widget JKQTPlotter* plotter = new JKQTPlotter(); JKQTPDatastore* ds = plotter->getDatastore(); @@ -830,9 +830,9 @@ FollowOATempSPMView::FollowOATempSPMView(const model::SetpointManagerFollowOutdo graph1->setYColumn(columnY); graph1->setTitle(QObject::tr("Setpoint Follow Outdoor Air Temperature")); JKQTPXYLineGraph* graph2 = new JKQTPXYLineGraph(plotter); - graph1->setXColumn(columnX); - graph1->setYColumn(columnYOA); - graph1->setTitle(QObject::tr("Setpoint Follow Outdoor Air Temperature")); + graph2->setXColumn(columnX); + graph2->setYColumn(columnYOA); + graph2->setTitle(QObject::tr("Setpoint Follow Outdoor Air Temperature")); plotter->getXAxis()->setAxisLabel(QString("%1 Temperature [C]").arg(refTempType)); plotter->getYAxis()->setAxisLabel("Setpoint Temperature [C]"); @@ -855,7 +855,7 @@ FollowGroundTempSPMView::FollowGroundTempSPMView(const model::SetpointManagerFol new QLabel(QString("Supply temperature follows the Ground Temperature with an offset of %2 C.").arg(QString::number(offset))); mainVLayout->addWidget(followTempSPMlabel); - // Create a JKQTPlotter widget + // Create a JKQTPlotter widget JKQTPlotter* plotter = new JKQTPlotter(); JKQTPDatastore* ds = plotter->getDatastore(); @@ -879,9 +879,9 @@ FollowGroundTempSPMView::FollowGroundTempSPMView(const model::SetpointManagerFol graph1->setYColumn(columnY); graph1->setTitle(QObject::tr("Setpoint Follow Ground Temperature")); JKQTPXYLineGraph* graph2 = new JKQTPXYLineGraph(plotter); - graph1->setXColumn(columnX); - graph1->setYColumn(columnYGround); - graph1->setTitle(QObject::tr("Setpoint Follow Ground Temperature")); + graph2->setXColumn(columnX); + graph2->setYColumn(columnYGround); + graph2->setTitle(QObject::tr("Setpoint Follow Ground Temperature")); plotter->getXAxis()->setAxisLabel("Ground Temperature [C]"); plotter->getYAxis()->setAxisLabel("Setpoint Temperature [C]"); From 74e6083280efdc8e79a532f71bf0f81821a134a8 Mon Sep 17 00:00:00 2001 From: Dan Macumber Date: Mon, 1 Sep 2025 19:04:37 -0600 Subject: [PATCH 4/7] Initial working version --- CMakeLists.txt | 4 +- src/openstudio_app/CMakeLists.txt | 8 +++ src/openstudio_lib/CMakeLists.txt | 1 + src/openstudio_lib/HVACSystemsView.cpp | 78 +++++++++++++++++++++++--- 4 files changed, 82 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 26f111bd4..93b601c0a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -670,8 +670,8 @@ FetchContent_Declare(JKQTPlotter FetchContent_MakeAvailable(JKQTPlotter) -list(APPEND JKQT_LIBS Qt6::WebEngineCore) -list(APPEND JKQT_LIBS Qt6::WebEngineWidgets) +list(APPEND JKQT_LIBS JKQTCommonSharedLib) +list(APPEND JKQT_LIBS JKQTPlotterSharedLib) set(CMAKE_AUTOMOC OFF) diff --git a/src/openstudio_app/CMakeLists.txt b/src/openstudio_app/CMakeLists.txt index 1c999dc0a..9d6a182e9 100644 --- a/src/openstudio_app/CMakeLists.txt +++ b/src/openstudio_app/CMakeLists.txt @@ -275,6 +275,14 @@ elseif( WIN32 ) #COMMAND ${CMAKE_COMMAND} -E copy_if_different ${qweb_resources_v8_context_snapshot} $/resources/ ) + add_custom_command(TARGET ${target_name} + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $/ + COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $/ + COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $/ + COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $/ + ) + # On Windows, we must copy the DLLs inside the build folder or it won't find them # TODO: IMPORTED_SONAME_RELEASE now contains @rpath so it fails # get_target_property(LIBOSLIB openstudio::openstudiolib IMPORTED_LOCATION_RELEASE) diff --git a/src/openstudio_lib/CMakeLists.txt b/src/openstudio_lib/CMakeLists.txt index ef8494f80..e05ff160f 100644 --- a/src/openstudio_lib/CMakeLists.txt +++ b/src/openstudio_lib/CMakeLists.txt @@ -776,6 +776,7 @@ set(${target_name}_depends ${QT_WEB_LIBS} ${JKQT_LIBS} ) + if(WIN32) list(APPEND ${target_name}_depends qtwinmigrate) endif() diff --git a/src/openstudio_lib/HVACSystemsView.cpp b/src/openstudio_lib/HVACSystemsView.cpp index 53544baa9..40e3f9473 100644 --- a/src/openstudio_lib/HVACSystemsView.cpp +++ b/src/openstudio_lib/HVACSystemsView.cpp @@ -688,6 +688,7 @@ OAResetSPMView::OAResetSPMView(const model::SetpointManagerOutdoorAirReset& spm) // Create a JKQTPlotter widget JKQTPlotter* plotter = new JKQTPlotter(); + plotter->setPlotUpdateEnabled(false); JKQTPDatastore* ds = plotter->getDatastore(); // Generate the data for the plot @@ -713,10 +714,25 @@ OAResetSPMView::OAResetSPMView(const model::SetpointManagerOutdoorAirReset& spm) JKQTPXYLineGraph* graph = new JKQTPXYLineGraph(plotter); graph->setXColumn(columnX); graph->setYColumn(columnY); - graph->setTitle(QObject::tr("Setpoint Outdoor Air Temp Reset")); + graph->setTitle("Setpoint Outdoor Air Temp Reset"); + plotter->getXAxis()->setAxisLabel("Outdoor Air Temperature [C]"); plotter->getYAxis()->setAxisLabel("Setpoint Temperature [C]"); plotter->setMinimumSize(400, 400); + plotter->setMaximumSize(600, 400); + plotter->setToolbarEnabled(false); + plotter->clearAllMouseWheelActions(); + plotter->clearAllRegisteredMouseDoubleClickActions(); + plotter->clearAllRegisteredMouseDragActions(); + plotter->getPlotter()->setUseAntiAliasingForGraphs(false); + plotter->getPlotter()->setUseAntiAliasingForSystem(false); + plotter->getPlotter()->setUseAntiAliasingForText(false); + plotter->getPlotter()->setPlotLabel("Setpoint Follow Outdoor Air Temperature"); + plotter->addGraph(graph); + plotter->zoomToFit(); + plotter->setPlotUpdateEnabled(true); + plotter->redrawPlot(); + mainVLayout->addWidget(plotter); mainVLayout->addStretch(); } @@ -740,6 +756,7 @@ SystemNodeResetSPMView::SystemNodeResetSPMView(const model::SetpointManagerSyste // Create a JKQTPlotter widget JKQTPlotter* plotter = new JKQTPlotter(); + plotter->setPlotUpdateEnabled(false); JKQTPDatastore* ds = plotter->getDatastore(); // Generate the data for the plot @@ -765,10 +782,25 @@ SystemNodeResetSPMView::SystemNodeResetSPMView(const model::SetpointManagerSyste JKQTPXYLineGraph* graph = new JKQTPXYLineGraph(plotter); graph->setXColumn(columnX); graph->setYColumn(columnY); - graph->setTitle(QObject::tr("Setpoint System Node Reset Temperature")); + graph->setTitle("Setpoint System Node Reset Temperature"); + plotter->getXAxis()->setAxisLabel("System Node Temperature [C]"); plotter->getYAxis()->setAxisLabel("Setpoint Temperature [C]"); plotter->setMinimumSize(400, 400); + plotter->setMaximumSize(600, 400); + plotter->setToolbarEnabled(false); + plotter->clearAllMouseWheelActions(); + plotter->clearAllRegisteredMouseDoubleClickActions(); + plotter->clearAllRegisteredMouseDragActions(); + plotter->getPlotter()->setUseAntiAliasingForGraphs(false); + plotter->getPlotter()->setUseAntiAliasingForSystem(false); + plotter->getPlotter()->setUseAntiAliasingForText(false); + plotter->getPlotter()->setPlotLabel("Setpoint Follow System Node Temperature"); + plotter->addGraph(graph); + plotter->zoomToFit(); + plotter->setPlotUpdateEnabled(true); + plotter->redrawPlot(); + mainVLayout->addWidget(plotter); mainVLayout->addStretch(); } @@ -808,6 +840,7 @@ FollowOATempSPMView::FollowOATempSPMView(const model::SetpointManagerFollowOutdo // Create a JKQTPlotter widget JKQTPlotter* plotter = new JKQTPlotter(); + plotter->setPlotUpdateEnabled(false); JKQTPDatastore* ds = plotter->getDatastore(); // Generate the data for the plot @@ -828,15 +861,30 @@ FollowOATempSPMView::FollowOATempSPMView(const model::SetpointManagerFollowOutdo JKQTPXYLineGraph* graph1 = new JKQTPXYLineGraph(plotter); graph1->setXColumn(columnX); graph1->setYColumn(columnY); - graph1->setTitle(QObject::tr("Setpoint Follow Outdoor Air Temperature")); + graph1->setTitle("Setpoint Temperature"); JKQTPXYLineGraph* graph2 = new JKQTPXYLineGraph(plotter); graph2->setXColumn(columnX); graph2->setYColumn(columnYOA); - graph2->setTitle(QObject::tr("Setpoint Follow Outdoor Air Temperature")); + graph2->setTitle(refTempType); plotter->getXAxis()->setAxisLabel(QString("%1 Temperature [C]").arg(refTempType)); plotter->getYAxis()->setAxisLabel("Setpoint Temperature [C]"); plotter->setMinimumSize(400, 400); + plotter->setMaximumSize(600, 400); + plotter->setToolbarEnabled(false); + plotter->clearAllMouseWheelActions(); + plotter->clearAllRegisteredMouseDoubleClickActions(); + plotter->clearAllRegisteredMouseDragActions(); + plotter->getPlotter()->setUseAntiAliasingForGraphs(false); + plotter->getPlotter()->setUseAntiAliasingForSystem(false); + plotter->getPlotter()->setUseAntiAliasingForText(false); + plotter->getPlotter()->setPlotLabel(QString("Setpoint Follow %1 Temperature").arg(refTempType)); + plotter->addGraph(graph1); + plotter->addGraph(graph2); + plotter->zoomToFit(); + plotter->setPlotUpdateEnabled(true); + plotter->redrawPlot(); + mainVLayout->addWidget(plotter); mainVLayout->addStretch(); } @@ -857,6 +905,7 @@ FollowGroundTempSPMView::FollowGroundTempSPMView(const model::SetpointManagerFol // Create a JKQTPlotter widget JKQTPlotter* plotter = new JKQTPlotter(); + plotter->setPlotUpdateEnabled(false); JKQTPDatastore* ds = plotter->getDatastore(); // Generate the data for the plot @@ -877,15 +926,30 @@ FollowGroundTempSPMView::FollowGroundTempSPMView(const model::SetpointManagerFol JKQTPXYLineGraph* graph1 = new JKQTPXYLineGraph(plotter); graph1->setXColumn(columnX); graph1->setYColumn(columnY); - graph1->setTitle(QObject::tr("Setpoint Follow Ground Temperature")); + graph1->setTitle("Setpoint Follow Ground Temperature"); JKQTPXYLineGraph* graph2 = new JKQTPXYLineGraph(plotter); graph2->setXColumn(columnX); graph2->setYColumn(columnYGround); - graph2->setTitle(QObject::tr("Setpoint Follow Ground Temperature")); + graph2->setTitle("Setpoint Follow Ground Temperature"); - plotter->getXAxis()->setAxisLabel("Ground Temperature [C]"); + plotter->getXAxis()->setAxisLabel(QString("Ground Temperature [C]")); plotter->getYAxis()->setAxisLabel("Setpoint Temperature [C]"); plotter->setMinimumSize(400, 400); + plotter->setMaximumSize(600, 400); + plotter->setToolbarEnabled(false); + plotter->clearAllMouseWheelActions(); + plotter->clearAllRegisteredMouseDoubleClickActions(); + plotter->clearAllRegisteredMouseDragActions(); + plotter->getPlotter()->setUseAntiAliasingForGraphs(false); + plotter->getPlotter()->setUseAntiAliasingForSystem(false); + plotter->getPlotter()->setUseAntiAliasingForText(false); + plotter->getPlotter()->setPlotLabel("Setpoint Follow Ground Temperature"); + plotter->addGraph(graph1); + plotter->addGraph(graph2); + plotter->zoomToFit(); + plotter->setPlotUpdateEnabled(true); + plotter->redrawPlot(); + mainVLayout->addWidget(plotter); mainVLayout->addStretch(); } From bd6af4412fbb2689312b84233784946e249f4d09 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Fri, 12 Dec 2025 09:47:39 +0100 Subject: [PATCH 5/7] Remove QtCharts6 from AboutBox --- src/openstudio_app/AboutBox.hpp.in | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/openstudio_app/AboutBox.hpp.in b/src/openstudio_app/AboutBox.hpp.in index e3546ccab..f0e4acbde 100644 --- a/src/openstudio_app/AboutBox.hpp.in +++ b/src/openstudio_app/AboutBox.hpp.in @@ -9,8 +9,6 @@

OpenStudio is a cross-platform tool to support whole building energy and daylight modeling using EnergyPlus and Radiance.

\

OpenStudio uses the following QT modules (version ${QT_VERSION}) that are dynamically linked using GNU Lesser General Public License (LGPL): \ Qt6Core, Qt6Core5Compat Qt6Widgets, Qt6Network, Qt6Concurrent, Qt6PrintSupport, Qt6Gui, Qt6Quick, Qt6QuickWidgets, Qt6Qml, Qt6QmlModels, Qt6WebChannel, Qt6Positioning, Qt6WebEngine, Qt6WebEngineWidgets, QtWebEngineCore, Qt6DBus, Qt6Xml, Qt6Svg, Qt6OpenGL, Qt6OpenGLWidgets

\ -

And these Qt modules that are dynamically linked using GNU General Public License (GPL): \ -Qt6Charts

\

For information on QT, please refer to QT

\

A copy of the GPL 3.0 and LGPL 3.0 are included in the root path of your installation directory.

" #endif // OPENSTUDIOAPP_ABOUTBOX From dd4a482ba0aa09b65842776631af6647e485e2e0 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Fri, 12 Dec 2025 11:31:21 +0100 Subject: [PATCH 6/7] Build JKQPLotter statically (8MB) --- CMakeLists.txt | 22 ++++++++++++++++------ src/openstudio_app/CMakeLists.txt | 14 +++----------- src/openstudio_lib/CMakeLists.txt | 2 +- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 93b601c0a..6f9a05498 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -659,19 +659,29 @@ if(UNIX) list(APPEND QT_INCLUDES ${Qt6XcbQpa_INCLUDE_DIRS}) endif() +####################### JKQTPlotter ###################### # Make JKQTPlotter available after finding Qt include(FetchContent) +# Build it statically +set(OLD_BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS}) +set(BUILD_SHARED_LIBS OFF) + set(JKQtPlotter_BUILD_EXAMPLES OFF) +set(JKQtPlotter_BUILD_LIB_JKQTFASTPLOTTER OFF) + +# Force finding the same Qt +find_package(QT NAMES Qt6 COMPONENTS Core Gui Widgets PrintSupport Svg Xml OpenGl REQUIRED PATHS ${QT_INSTALL_DIR} NO_DEFAULT_PATH) -FetchContent_Declare(JKQTPlotter - GIT_REPOSITORY https://github.com/jkriege2/JKQtPlotter.git - GIT_TAG v4.0.3) +FetchContent_Declare(JKQTPlotter${QT_VERSION_MAJOR} + GIT_REPOSITORY https://github.com/jkriege2/JKQtPlotter.git + # GIT_TAG v5.0.0 # This is unreleased, but FetchContent support was added after v4.0.3 +) -FetchContent_MakeAvailable(JKQTPlotter) +FetchContent_MakeAvailable(JKQTPlotter${QT_VERSION_MAJOR}) +set(BUILD_SHARED_LIBS ${OLD_BUILD_SHARED_LIBS}) -list(APPEND JKQT_LIBS JKQTCommonSharedLib) -list(APPEND JKQT_LIBS JKQTPlotterSharedLib) +########################################################## set(CMAKE_AUTOMOC OFF) diff --git a/src/openstudio_app/CMakeLists.txt b/src/openstudio_app/CMakeLists.txt index 9d6a182e9..5436c49bd 100644 --- a/src/openstudio_app/CMakeLists.txt +++ b/src/openstudio_app/CMakeLists.txt @@ -188,7 +188,7 @@ if( APPLE ) elseif( UNIX ) - foreach(LIB ${QT_LIBS} ${QT_WEB_LIBS} ${JKQT_LIBS}) + foreach(LIB ${QT_LIBS} ${QT_WEB_LIBS}) get_property(LIB_LOCATION TARGET ${LIB} PROPERTY LOCATION) list(APPEND QT_LIB_LOCATIONS "${LIB_LOCATION}") endforeach() @@ -275,14 +275,6 @@ elseif( WIN32 ) #COMMAND ${CMAKE_COMMAND} -E copy_if_different ${qweb_resources_v8_context_snapshot} $/resources/ ) - add_custom_command(TARGET ${target_name} - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $/ - COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $/ - COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $/ - COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $/ - ) - # On Windows, we must copy the DLLs inside the build folder or it won't find them # TODO: IMPORTED_SONAME_RELEASE now contains @rpath so it fails # get_target_property(LIBOSLIB openstudio::openstudiolib IMPORTED_LOCATION_RELEASE) @@ -395,7 +387,7 @@ if( NOT APPLE ) install(PROGRAMS $/D3Dcompiler_47.dll DESTINATION bin/ COMPONENT OpenStudioApp) install(PROGRAMS $/opengl32sw.dll DESTINATION bin/ COMPONENT OpenStudioApp) - foreach(LIB ${QT_LIBS} ${QT_WEB_LIBS} ${JKQT_LIBS}) + foreach(LIB ${QT_LIBS} ${QT_WEB_LIBS}) install(PROGRAMS $/$ DESTINATION bin/ COMPONENT OpenStudioApp) endforeach() @@ -416,7 +408,7 @@ if( NOT APPLE ) install(DIRECTORY $/xcbglintegrations/ DESTINATION bin/xcbglintegrations/ COMPONENT OpenStudioApp) # install(PROGRAMS $/xcbglintegrations/$ DESTINATION bin/xcbglintegrations/ COMPONENT OpenStudioApp) - foreach(LIB ${QT_LIBS} ${QT_WEB_LIBS} ${JKQT_LIBS}) + foreach(LIB ${QT_LIBS} ${QT_WEB_LIBS}) install(PROGRAMS $/$ DESTINATION bin/ COMPONENT OpenStudioApp) endforeach() diff --git a/src/openstudio_lib/CMakeLists.txt b/src/openstudio_lib/CMakeLists.txt index e05ff160f..522b1b965 100644 --- a/src/openstudio_lib/CMakeLists.txt +++ b/src/openstudio_lib/CMakeLists.txt @@ -774,7 +774,7 @@ set(${target_name}_depends openstudio::openstudiolib ${QT_LIBS} ${QT_WEB_LIBS} - ${JKQT_LIBS} + JKQTPlotter${QT_VERSION_MAJOR}::JKQTPlotter${QT_VERSION_MAJOR} ) if(WIN32) From 56d9f806e6426f603c8db6c0b5f62d5e08f20212 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Fri, 12 Dec 2025 12:47:11 +0100 Subject: [PATCH 7/7] Add MSVC options for JKQTPLotter per the example https://github.com/jkriege2/JKQtPlotter/tree/master/examples/cmake_fetchcontent_example --- CMakeLists.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f9a05498..1ceff90cd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -679,6 +679,16 @@ FetchContent_Declare(JKQTPlotter${QT_VERSION_MAJOR} ) FetchContent_MakeAvailable(JKQTPlotter${QT_VERSION_MAJOR}) + +if (MSVC) + target_compile_definitions(JKQTPlotter${QT_VERSION_MAJOR} PRIVATE + _USE_MATH_DEFINES # To enable M_PI, M_E,.. + DNOMINMAX # To Prevent Errors with min() and max() + _CRT_NO_VA_START_VALIDATION # To fix error: C2338: va_start argument must not have reference type and must not be parenthesized + ) + target_compile_options(JKQTPlotter${QT_VERSION_MAJOR} PRIVATE /EHsc /wd4018) +endif() + set(BUILD_SHARED_LIBS ${OLD_BUILD_SHARED_LIBS}) ##########################################################