Browse Source

从数据中加载方案流程图

chengxr 1 year ago
parent
commit
ee54113108

+ 95 - 0
QFD/common/SchemePlanManager.cpp

@@ -1,5 +1,10 @@
 #include "SchemePlanManager.h"
 
+#include "ProjectManager.h"
+
+#include <QMetaEnum>
+#include <QDebug>
+
 QString SchemePlanManager::stringFromDataSource(SchemePlanManager::SchemeDataSource src)
 {
     switch (src) {
@@ -33,7 +38,97 @@ QString SchemePlanManager::stringFromAlgorithm(SchemePlanManager::Algorithm alg)
         return "物元分析法";
     case GCE:
         return "灰色聚类评估法";
+    case WeightedSum:
+        return "加权求和算法";
+    }
+}
+
+QString SchemePlanManager::processName(SchemePlanManager::SchemeProcessInfo process)
+{
+    QList<QString> l1 = { "构建权重分析指标体系", "收集权重分析数据", "指标体系优化", "指标权重计算", "", "",
+                          "分析结果展示",         "生成分析评估报告" };
+    QList<QString> l2 = {
+        "构建技术措施指标体系", "", "", "", "收集评估数据", "评估计算", "评估结果展示", "生成评估报告"
+    };
+    QList<QString> l3 = { "构建方案优选指标体系", "收集方案优选权重分析数据",
+                          "指标体系优化",         "指标权重计算",
+                          "评估数据采集",         "方案优选计算",
+                          "方案优选结果展示",     "生成方案优选报告" };
+    QList<QString> l4 = { "构建效能评估指标体系", "收集效能评估权重分析数据", "指标体系优化",
+                          "效能评估权重计算",     "收集效能评估数据",         "效能评估计算",
+                          "效能评估结果展示",     "生成效能评估报告" };
+
+    QList<QList<QString>> names = { l1, l2, l3, l4 };
+
+    /// 获取指标类型枚举值 index
+    /// 由于枚举值不是连续自然数, 故不能作为下表来索引数组
+    /// 故须使用 index 替代
+    int index           = 0;
+    QMetaEnum indexEnum = QMetaEnum::fromType<ProjectManager::IndexType>();
+    for (int i = 0; i < indexEnum.keyCount(); i++) {
+        if (indexEnum.value(i) == process.indexType) {
+            index = i;
+            break;
+        }
+    }
+
+    if (index >= 0 && index < names.count() && process.type >= 0 && process.type < names[index].count()) {
+        return names[index][process.type];
     }
+    return "";
+}
+
+QList<SchemePlanManager::SchemeDataSource>
+SchemePlanManager::processOptionalDataSource(SchemePlanManager::SchemeProcessInfo process)
+{
+    if (process.type == ImportWeightData || process.type == ImportEvalData) {
+        return { FromExpert, FromMeasurement };
+    }
+    return {};
+}
+
+/**
+ * 根据指标体系类型和方案步骤类型, 返回可选算法
+ * date: 2023-11-03 by chengxr
+ */
+QList<SchemePlanManager::Algorithm>
+SchemePlanManager::processOptionalAlgorithms(SchemePlanManager::SchemeProcessInfo process)
+{
+    switch (process.type) {
+    case OptimizeIndex:
+        return { PrincipalComponents };
+    case CalculateWeight: {
+        if (process.indexType == ProjectManager::AbilityIndex) {
+            return { Entropy, AHP };
+        } else if (process.indexType == ProjectManager::OptimalIndex) {
+            return { HWM, SPA };
+        } else if (process.indexType == ProjectManager::EfficiencyIndex) {
+            return {};
+        }
+        return {};
+    }
+    case RunEvaluate: {
+        if (process.indexType == ProjectManager::TechIndex) {
+            return { WeightedSum };
+        } else if (process.indexType == ProjectManager::OptimalIndex) {
+            return { HWM, SPA };
+        } else if (process.indexType == ProjectManager::EfficiencyIndex) {
+            return { MEA, GCE };
+        }
+        return {};
+    }
+    case IndexSystem:
+    case ImportWeightData:
+    case ImportEvalData:
+    case ShowEvalResult:
+    case GenerateReport:
+        return {};
+    }
+}
+
+bool SchemePlanManager::processIsOptional(SchemePlanManager::SchemeProcessInfo process)
+{
+    return (process.type == GenerateReport);
 }
 
 SchemePlanManager::SchemePlanManager(QObject *parent) : QObject(parent) { }

+ 17 - 4
QFD/common/SchemePlanManager.h

@@ -50,6 +50,7 @@ public:
         SPA,                  // set pair analysis 集对分析法
         MEA,                  // matter element analysis 物元分析法
         GCE,                  // Grey clustering evaluation method 灰色聚类评估法
+        WeightedSum,          // Weighted Sum 加权求和算法
     };
 
     static QString stringFromAlgorithm(Algorithm alg);
@@ -98,12 +99,24 @@ public:
         /// 效能分级, 选择灰色聚类算法计算效能评估时用到
         int efficiencyGrades = 0;
 
-        bool isOptional;     // 是否可选
-        bool isChecked;      // 选中状态
-        QString createTime;  //创建时间
-        QString updateTime;  //更新时间
+        bool isOptional;     // 是否可择执行
+        bool isChecked;      // 是否选择了执行
+        QString createTime;  // 创建时间
+        QString updateTime;  // 更新时间
     };
 
+    /// 方案步骤的名称
+    static QString processName(SchemeProcessInfo process);
+
+    /// 给定方案步骤中可选的数据来源
+    static QList<SchemeDataSource> processOptionalDataSource(SchemeProcessInfo process);
+
+    /// 给定方案步骤中可选的算法
+    static QList<Algorithm> processOptionalAlgorithms(SchemeProcessInfo process);
+
+    /// 给定方案步骤是否可以选择执行
+    static bool processIsOptional(SchemeProcessInfo process);
+
     explicit SchemePlanManager(QObject *parent = nullptr);
 
 signals:

+ 115 - 0
QFD/shemeFlow/FlowGraphNodeWidget.cpp

@@ -1,11 +1,15 @@
 #include "FlowGraphNodeWidget.h"
 
+#include "SchemePlanManager.h"
+
 #include <QBoxLayout>
 #include <QLabel>
 #include <QCheckBox>
 #include <QComboBox>
 #include <QSpinBox>
 
+#include <QDebug>
+
 FlowGraphNodeWidget::FlowGraphNodeWidget(NodeWidgetType type, QWidget *parent) : QWidget(parent), m_type(type)
 {
     setFixedSize(QSize(130, 30));
@@ -22,6 +26,7 @@ FlowGraphPlainNodeWidget::FlowGraphPlainNodeWidget(QWidget *parent) : FlowGraphN
 {
     m_label = new QLabel(this);
     m_label->setText("test");
+    m_label->setStyleSheet("{font: bold}");
     m_label->setAlignment(Qt::AlignCenter);
 
     m_layout->setMargin(0);
@@ -86,3 +91,113 @@ FlowGraphSpinNodeWidget::FlowGraphSpinNodeWidget(QWidget *parent) : FlowGraphNod
 
     m_layout->addWidget(m_spinBox);
 }
+
+FlowGraphCommonNodeWidget::FlowGraphCommonNodeWidget(QWidget *parent) : QWidget(parent)
+{
+    initWidget();
+}
+
+SchemePlanManager::SchemeProcessInfo FlowGraphCommonNodeWidget::process() const
+{
+    return m_process;
+}
+
+void FlowGraphCommonNodeWidget::setProcess(SchemePlanManager::SchemeProcessInfo i)
+{
+    m_process = i;
+    loadInfo();
+}
+
+bool FlowGraphCommonNodeWidget::isTitleHidden() const
+{
+    QList<SchemePlanManager::Algorithm> algs        = SchemePlanManager::processOptionalAlgorithms(m_process);
+    QList<SchemePlanManager::SchemeDataSource> dsrc = SchemePlanManager::processOptionalDataSource(m_process);
+    bool opt                                        = SchemePlanManager::processIsOptional(m_process);
+
+    return (algs.count() > 0 || dsrc.count() > 0 || opt);
+}
+
+void FlowGraphCommonNodeWidget::initWidget()
+{
+    setFixedWidth(160);
+
+    m_label     = new QLabel();
+    m_algCombo  = new QComboBox();
+    m_dataCombo = new QComboBox();
+    m_spinBox   = new QSpinBox();
+    m_spinBox->setPrefix("效能分级:");
+    m_spinBox->setMaximum(10);
+    m_spinBox->setMinimum(1);
+    m_checkBox = new QCheckBox("执行");
+
+    m_layout = new QVBoxLayout(this);
+    m_layout->setMargin(0);
+    m_layout->setAlignment(Qt::AlignCenter);
+    m_layout->addWidget(m_label);
+    m_layout->addWidget(m_algCombo);
+    m_layout->addWidget(m_dataCombo);
+    m_layout->addWidget(m_spinBox);
+    m_layout->addWidget(m_checkBox);
+}
+
+void FlowGraphCommonNodeWidget::loadInfo()
+{
+    QList<SchemePlanManager::Algorithm> algs        = optionalAlgs();
+    QList<SchemePlanManager::SchemeDataSource> dsrc = optionaldSource();
+    bool opt                                        = isOptional();
+
+    /// 标题
+    /// 在其他子控件都不显示时, 将标题居中显示
+    m_label->setHidden(algs.count() > 0 || dsrc.count() > 0 || opt);
+    m_label->setText(title());
+
+    /// 算法选择组件
+    m_algCombo->setHidden(algs.count() <= 0);
+    m_algCombo->clear();
+    for (SchemePlanManager::Algorithm alg : algs) {
+        m_algCombo->addItem(SchemePlanManager::stringFromAlgorithm(alg));
+    }
+    if (algs.count() > 0) {
+        m_algCombo->setCurrentIndex(algs.indexOf(m_process.algorithm));
+    }
+
+    /// 数据来源选择组件
+    m_dataCombo->setHidden(dsrc.count() <= 0);
+    m_dataCombo->clear();
+    for (SchemePlanManager::SchemeDataSource scr : dsrc) {
+        m_dataCombo->addItem(SchemePlanManager::stringFromDataSource(scr));
+    }
+    if (dsrc.count() > 0) {
+        m_dataCombo->setCurrentIndex(dsrc.indexOf(m_process.dSource));
+    }
+
+    /// 选择执行组件
+    m_checkBox->setVisible(opt);
+    m_checkBox->setChecked(m_process.isChecked);
+
+    /// 效能分级组件
+    m_spinBox->setHidden(m_process.algorithm != SchemePlanManager::GCE);
+    m_spinBox->setValue(m_process.efficiencyGrades);
+}
+
+QString FlowGraphCommonNodeWidget::title() const
+{
+    return SchemePlanManager::processName(m_process);
+}
+
+QList<SchemePlanManager::Algorithm> FlowGraphCommonNodeWidget::optionalAlgs() const
+{
+    return SchemePlanManager::processOptionalAlgorithms(m_process);
+}
+
+QList<SchemePlanManager::SchemeDataSource> FlowGraphCommonNodeWidget::optionaldSource() const
+{
+    return SchemePlanManager::processOptionalDataSource(m_process);
+    ;
+}
+
+bool FlowGraphCommonNodeWidget::isOptional() const
+{
+    return SchemePlanManager::processIsOptional(m_process);
+    ;
+}

+ 36 - 0
QFD/shemeFlow/FlowGraphNodeWidget.h

@@ -81,4 +81,40 @@ private:
     QSpinBox *m_spinBox = nullptr;
 };
 
+#include <SchemePlanManager.h>
+
+class FlowGraphCommonNodeWidget : public QWidget
+{
+    Q_OBJECT
+public:
+    explicit FlowGraphCommonNodeWidget(QWidget *parent = nullptr);
+
+    SchemePlanManager::SchemeProcessInfo process() const;
+
+    void setProcess(SchemePlanManager::SchemeProcessInfo i);
+
+    bool isTitleHidden() const;
+
+protected:
+    void initWidget();
+
+    void loadInfo();
+
+    QString title() const;
+    QList<SchemePlanManager::Algorithm> optionalAlgs() const;
+    QList<SchemePlanManager::SchemeDataSource> optionaldSource() const;
+    bool isOptional() const;
+
+private:
+    SchemePlanManager::SchemeProcessInfo m_process;
+
+    QLabel *m_label        = nullptr;
+    QComboBox *m_algCombo  = nullptr;
+    QComboBox *m_dataCombo = nullptr;
+    QSpinBox *m_spinBox    = nullptr;
+    QCheckBox *m_checkBox  = nullptr;
+
+    QVBoxLayout *m_layout = nullptr;
+};
+
 #endif  // FLOWGRAPHNODEWIDGET_H

+ 36 - 0
QFD/shemeFlow/FlowTemplateDataModel.h

@@ -481,4 +481,40 @@ public:
     QWidget *embeddedWidget() override;
 };
 
+class FlowCommonData : public NodeData
+{
+public:
+    NodeDataType type() const override { return NodeDataType { "FlowCommonData", "" }; }
+};
+
+class FlowCommonDataModel : public NodeDelegateModel
+{
+    Q_OBJECT
+
+public:
+    FlowCommonDataModel() : NodeDelegateModel() {};
+
+    ~FlowCommonDataModel() = default;
+
+    QString caption() const override { return QString(""); }
+
+    bool captionVisible() const override { return true; }
+
+    bool portCaptionVisible(PortType, PortIndex) const override { return false; }
+
+    QString portCaption(PortType, PortIndex) const override { return ""; }
+
+    QString name() const override { return QString("FlowCommonData"); }
+
+    unsigned int nPorts(PortType const) const override { return 0; }
+
+    NodeDataType dataType(PortType const, PortIndex const) const override { return FlowCommonData().type(); }
+
+    std::shared_ptr<NodeData> outData(PortIndex const) override { return std::make_shared<FlowCommonData>(); }
+
+    void setInData(std::shared_ptr<NodeData>, PortIndex const) override { }
+
+    QWidget *embeddedWidget() override { return nullptr; };
+};
+
 #endif  // FLOWTEMPLARTEDATAMODEL_H

+ 43 - 18
QFD/widgets/SchemeFlowWidget.cpp

@@ -29,6 +29,7 @@ static std::shared_ptr<NodeDelegateModelRegistry> registerDataModels()
     ret->registerModel<FlowEffiLevDataModel>();
     ret->registerModel<FlowSchemeDataModel>();
     ret->registerModel<FlowEffiDataModel>();
+    ret->registerModel<FlowCommonDataModel>();
 
     return ret;
 }
@@ -133,42 +134,70 @@ void SchemeFlowWidget::refresh()
 {
     clearAllNodes();
 
-    qreal h = 120;
+    qreal h = 200;
 
     switch (m_indexType) {
     case ProjectManager::AbilityIndex:
+        break;
     case ProjectManager::TechIndex: {
-        NodeId id1 = m_graphModel->addNode(FlowIndexData().type().id);
+        NodeId id11 = m_graphModel->addNode(FlowCommonData().type().id);
+        m_graphModel->setNodeData(id11, NodeRole::Position, QPointF(0, h * 0));
+        FlowGraphCommonNodeWidget *w11 = new FlowGraphCommonNodeWidget();
+        SchemePlanManager::SchemeProcessInfo process11;
+        process11.indexType = m_indexType;
+        process11.type      = SchemePlanManager::IndexSystem;
+        w11->setProcess(process11);
+        m_graphModel->setNodeData(id11, NodeRole::Widget, QVariant::fromValue(w11));
+
+        NodeId id12 = m_graphModel->addNode(FlowCommonData().type().id);
+        m_graphModel->setNodeData(id12, NodeRole::Position, QPointF(0, h * 1));
+        FlowGraphCommonNodeWidget *w12 = new FlowGraphCommonNodeWidget();
+        SchemePlanManager::SchemeProcessInfo process12;
+        process12.indexType = m_indexType;
+        process12.type      = SchemePlanManager::ImportEvalData;
+        process12.dSource   = SchemePlanManager::FromExpert;
+        w12->setProcess(process12);
+        if (w12->isTitleHidden()) {
+            m_graphModel->setNodeData(id12, NodeRole::Caption, SchemePlanManager::processName(process12));
+        }
+        m_graphModel->setNodeData(id12, NodeRole::Widget, QVariant::fromValue(w12));
+
+        m_graphModel->addConnection(ConnectionId { id11, 0, id12, 0 });
+
+        break;
+
+        NodeId id1 = m_graphModel->addNode(FlowCommonData().type().id);
         m_graphModel->setNodeData(id1, NodeRole::Position, QPointF(0, h * 0));
-        FlowGraphPlainNodeWidget *w = new FlowGraphPlainNodeWidget();
-        w->setText("构建权重分析指标体系");
-        m_graphModel->setNodeData(id1, NodeRole::Widget, QVariant::fromValue(w));
+        FlowGraphPlainNodeWidget *w1 = new FlowGraphPlainNodeWidget();
+        w1->setText("构建权重分析指标体系");
+        m_graphModel->setNodeData(id1, NodeRole::Widget, QVariant::fromValue(w1));
 
-        NodeId id2 = m_graphModel->addNode(FlowSampleData().type().id);
+        NodeId id2 = m_graphModel->addNode(FlowCommonData().type().id);
         m_graphModel->setNodeData(id2, NodeRole::Position, QPointF(0, h * 1));
         m_graphModel->setNodeData(id2, NodeRole::Caption, QString("收集权重分析数据"));
         m_graphModel->addConnection(ConnectionId { id1, 0, id2, 0 });
 
-        NodeId id3 = m_graphModel->addNode(FlowPCAData().type().id);
+        NodeId id3 = m_graphModel->addNode(FlowCommonData().type().id);
         m_graphModel->setNodeData(id3, NodeRole::Position, QPointF(0, h * 2));
         m_graphModel->setNodeData(id3, NodeRole::Caption, QString("指标体系优化"));
         m_graphModel->addConnection(ConnectionId { id2, 0, id3, 0 });
 
-        NodeId id4 = m_graphModel->addNode(FlowWeightData().type().id);
+        NodeId id4 = m_graphModel->addNode(FlowCommonData().type().id);
         m_graphModel->setNodeData(id4, NodeRole::Position, QPointF(0, h * 3));
         m_graphModel->setNodeData(id4, NodeRole::Caption, QString("指标权重计算"));
         m_graphModel->addConnection(ConnectionId { id3, 0, id4, 0 });
 
-        NodeId id5 = m_graphModel->addNode(FlowResultData().type().id);
+        NodeId id5 = m_graphModel->addNode(FlowCommonData().type().id);
         m_graphModel->setNodeData(id5, NodeRole::Position, QPointF(0, h * 4));
-        m_graphModel->setNodeData(id5, NodeRole::Caption, QString("分析结果展示"));
+        FlowGraphPlainNodeWidget *w5 = new FlowGraphPlainNodeWidget();
+        w5->setText("分析结果展示");
+        m_graphModel->setNodeData(id5, NodeRole::Widget, QVariant::fromValue(w5));
         m_graphModel->addConnection(ConnectionId { id4, 0, id5, 0 });
 
-        NodeId id6 = m_graphModel->addNode(FlowReportData().type().id);
+        NodeId id6 = m_graphModel->addNode(FlowCommonData().type().id);
         m_graphModel->setNodeData(id6, NodeRole::Position, QPointF(0, h * 5));
         m_graphModel->setNodeData(id6, NodeRole::Caption, QString("生成分析评估报告"));
         m_graphModel->addConnection(ConnectionId { id5, 0, id6, 0 });
-        qDebug() << __FUNCTION__ << __LINE__ << id1 << id2 << id3 << id4 << id5 << id6 << endl;
         break;
     }
     case ProjectManager::OptimalIndex: {
@@ -191,7 +220,6 @@ void SchemeFlowWidget::refresh()
         m_graphModel->setNodeData(id6, NodeRole::Position, QPointF(0, h * 4));
         m_graphModel->addConnection(ConnectionId { id5, 0, id6, 0 });
 
-        qDebug() << __FUNCTION__ << __LINE__ << id1 << id2 << id8 << id5 << id6 << endl;
         break;
     }
     case ProjectManager::EfficiencyIndex: {
@@ -213,13 +241,10 @@ void SchemeFlowWidget::refresh()
         NodeId id6 = m_graphModel->addNode(FlowReportData().type().id);
         m_graphModel->setNodeData(id6, NodeRole::Position, QPointF(0, h * 4));
         m_graphModel->addConnection(ConnectionId { id5, 0, id6, 0 });
-        qDebug() << __FUNCTION__ << __LINE__ << id1 << id7 << id9 << id5 << id6 << endl;
         break;
     }
     }
 
-    std::unordered_set<NodeId> set = m_graphModel->allNodeIds();
-    for (auto iter = set.begin(); iter != set.end(); ++iter) {
-        qDebug() << __FUNCTION__ << __LINE__ << *iter << endl;
-    }
+    //    std::unordered_set<NodeId> set = m_graphModel->allNodeIds();
+    //    for (auto iter = set.begin(); iter != set.end(); ++iter) { }
 }

+ 7 - 0
QtNodes/include/QtNodes/internal/DataFlowGraphModel.hpp

@@ -130,6 +130,13 @@ private:
     mutable std::unordered_map<NodeId, QString> _captionData;
 
     mutable std::unordered_map<NodeId, QWidget *> _widgetData;
+
+    /**
+     * 端口数
+     * date: 2023-11-03 by chengxr
+     */
+    mutable std::unordered_map<NodeId, unsigned int> _inPorts;
+    mutable std::unordered_map<NodeId, unsigned int> _outPorts;
 };
 
 }  // namespace QtNodes

+ 8 - 2
QtNodes/src/DataFlowGraphModel.cpp

@@ -196,11 +196,13 @@ QVariant DataFlowGraphModel::nodeData(NodeId nodeId, NodeRole role) const
     }
 
     case NodeRole::InPortCount:
-        result = model->nPorts(PortType::In);
+        //        result = model->nPorts(PortType::In);
+        result = _inPorts[nodeId];
         break;
 
     case NodeRole::OutPortCount:
-        result = model->nPorts(PortType::Out);
+        //        result = model->nPorts(PortType::Out);
+        result = _outPorts[nodeId];
         break;
 
     case NodeRole::Widget: {
@@ -263,9 +265,13 @@ bool DataFlowGraphModel::setNodeData(NodeId nodeId, NodeRole role, QVariant valu
         break;
 
     case NodeRole::InPortCount:
+        _inPorts[nodeId] = value.value<unsigned int>();
+        Q_EMIT nodeCreated(nodeId);
         break;
 
     case NodeRole::OutPortCount:
+        _outPorts[nodeId] = value.value<unsigned int>();
+        Q_EMIT nodeCreated(nodeId);
         break;
 
     case NodeRole::Widget: