Kaynağa Gözat

更新node节点箭头,移动算法路径

Signed-off-by: codeClown <zhaomengshou@126.com>
codeClown 1 yıl önce
ebeveyn
işleme
49d66f9756

+ 2 - 0
.gitignore

@@ -35,3 +35,5 @@ Makefile*
 *.qmlproject.user.*
 
 !bin/libmysql.dll
+QtNodes/src/ConnectionPainter.cpp
+bin/QtNodesd.exp

+ 8 - 0
QFD/QFD.pro

@@ -63,13 +63,17 @@ INCLUDEPATH += $$PWD/common
 INCLUDEPATH += $$PWD/../Eigen
 
 SOURCES += \
+    algorithm/AverageMethod.cpp \
+    algorithm/ConsistencyCheck.cpp \
     algorithm/EntropyWeights.cpp \
     algorithm/GreyClusterEvaluation.cpp \
     algorithm/HierarchicalAnalysis.cpp \
     algorithm/HierarchyWeighting.cpp \
     algorithm/MatterElementAnalysis.cpp \
+    algorithm/MinMaxAnalysis.cpp \
     algorithm/PCA.cpp \
     algorithm/SetPairAnalysis.cpp \
+    algorithm/ZScore.cpp \
     algorithm/test_main.cpp \
     common/ExpertManager.cpp \
     common/ProjectManager.cpp \
@@ -114,13 +118,17 @@ SOURCES += \
     widgets/SchemeWidget.cpp
 
 HEADERS += \
+    algorithm/AverageMethod.h \
+    algorithm/ConsistencyCheck.h \
     algorithm/EntropyWeights.h \
     algorithm/GreyClusterEvaluation.h \
     algorithm/HierarchicalAnalysis.h \
     algorithm/HierarchyWeighting.h \
     algorithm/MatterElementAnalysis.h \
+    algorithm/MinMaxAnalysis.h \
     algorithm/PCA.h \
     algorithm/SetPairAnalysis.h \
+    algorithm/ZScore.h \
     common/ExpertManager.h \
     common/ProjectManager.h \
     common/QFDAlert.h \

+ 0 - 0
QFD/shemeTable/AverageMethod.cpp → QFD/algorithm/AverageMethod.cpp


+ 0 - 0
QFD/shemeTable/AverageMethod.h → QFD/algorithm/AverageMethod.h


+ 0 - 0
QFD/shemeTable/ConsistencyCheck.cpp → QFD/algorithm/ConsistencyCheck.cpp


+ 0 - 0
QFD/shemeTable/ConsistencyCheck.h → QFD/algorithm/ConsistencyCheck.h


+ 0 - 0
QFD/shemeTable/MinMaxAnalysis.cpp → QFD/algorithm/MinMaxAnalysis.cpp


+ 0 - 0
QFD/shemeTable/MinMaxAnalysis.h → QFD/algorithm/MinMaxAnalysis.h


+ 0 - 0
QFD/shemeTable/ZScore.cpp → QFD/algorithm/ZScore.cpp


+ 0 - 0
QFD/shemeTable/ZScore.h → QFD/algorithm/ZScore.h


+ 52 - 0
QFD/shemeFlow/DataFlowModel.h

@@ -0,0 +1,52 @@
+#ifndef DATAFLOWMODEL_H
+#define DATAFLOWMODEL_H
+
+#include <QtNodes/DataFlowGraphModel>
+
+using QtNodes::ConnectionId;
+using QtNodes::DataFlowGraphModel;
+using QtNodes::NodeDelegateModelRegistry;
+using QtNodes::NodeFlag;
+using QtNodes::NodeFlags;
+using QtNodes::NodeId;
+
+class DataFlowModel : public DataFlowGraphModel
+{
+public:
+    DataFlowModel(std::shared_ptr<NodeDelegateModelRegistry> registry)
+        : DataFlowGraphModel(std::move(registry)), _detachPossible { true }, _nodesLocked { false }
+    {
+    }
+
+    bool detachPossible(ConnectionId const) const override { return _detachPossible; }
+
+    void setDetachPossible(bool d = true) { _detachPossible = d; }
+
+    //----
+
+    NodeFlags nodeFlags(NodeId nodeId) const override
+    {
+        auto basicFlags = DataFlowGraphModel::nodeFlags(nodeId);
+
+        if (_nodesLocked)
+            basicFlags |= NodeFlag::Locked;
+
+        return basicFlags;
+    }
+
+    void setNodesLocked(bool b = true)
+    {
+        _nodesLocked = b;
+
+        for (NodeId nodeId : allNodeIds()) {
+            Q_EMIT nodeFlagsUpdated(nodeId);
+        }
+    }
+
+private:
+    bool _detachPossible;
+
+    bool _nodesLocked;
+};
+
+#endif  // DATAFLOWMODEL_H

+ 281 - 0
QFD/shemeFlow/FlowGraphModel.cpp

@@ -0,0 +1,281 @@
+#include "FlowGraphModel.h"
+
+FlowGraphModel::FlowGraphModel() : _nextNodeId { 0 } { }
+
+FlowGraphModel::~FlowGraphModel()
+{
+    //
+}
+
+std::unordered_set<NodeId> FlowGraphModel::allNodeIds() const
+{
+    return _nodeIds;
+}
+
+std::unordered_set<ConnectionId> FlowGraphModel::allConnectionIds(NodeId const nodeId) const
+{
+    std::unordered_set<ConnectionId> result;
+
+    std::copy_if(_connectivity.begin(), _connectivity.end(), std::inserter(result, std::end(result)),
+                 [&nodeId](ConnectionId const &cid) { return cid.inNodeId == nodeId || cid.outNodeId == nodeId; });
+
+    return result;
+}
+
+std::unordered_set<ConnectionId> FlowGraphModel::connections(NodeId nodeId, PortType portType,
+                                                             PortIndex portIndex) const
+{
+    std::unordered_set<ConnectionId> result;
+
+    std::copy_if(_connectivity.begin(), _connectivity.end(), std::inserter(result, std::end(result)),
+                 [&portType, &portIndex, &nodeId](ConnectionId const &cid) {
+                     return (getNodeId(portType, cid) == nodeId && getPortIndex(portType, cid) == portIndex);
+                 });
+
+    return result;
+}
+
+bool FlowGraphModel::connectionExists(ConnectionId const connectionId) const
+{
+    return (_connectivity.find(connectionId) != _connectivity.end());
+}
+
+NodeId FlowGraphModel::addNode(QString const nodeType)
+{
+    NodeId newId = newNodeId();
+    // Create new node.
+    _nodeIds.insert(newId);
+
+    Q_EMIT nodeCreated(newId);
+
+    return newId;
+}
+
+bool FlowGraphModel::connectionPossible(ConnectionId const connectionId) const
+{
+    return _connectivity.find(connectionId) == _connectivity.end();
+}
+
+void FlowGraphModel::addConnection(ConnectionId const connectionId)
+{
+    _connectivity.insert(connectionId);
+
+    Q_EMIT connectionCreated(connectionId);
+}
+
+bool FlowGraphModel::nodeExists(NodeId const nodeId) const
+{
+    return (_nodeIds.find(nodeId) != _nodeIds.end());
+}
+
+QVariant FlowGraphModel::nodeData(NodeId nodeId, NodeRole role) const
+{
+    Q_UNUSED(nodeId);
+
+    QVariant result;
+
+    switch (role) {
+    case NodeRole::Type:
+        result = QString("Default Node Type");
+        break;
+
+    case NodeRole::Position:
+        result = _nodeGeometryData[nodeId].pos;
+        break;
+
+    case NodeRole::Size:
+        result = _nodeGeometryData[nodeId].size;
+        break;
+
+    case NodeRole::CaptionVisible:
+        result = true;
+        break;
+
+    case NodeRole::Caption:
+        result = QString("Node");
+        break;
+
+    case NodeRole::Style: {
+        auto style = StyleCollection::nodeStyle();
+        result     = style.toJson().toVariantMap();
+    } break;
+
+    case NodeRole::InternalData:
+        break;
+
+    case NodeRole::InPortCount:
+        result = 1u;
+        break;
+
+    case NodeRole::OutPortCount:
+        result = 1u;
+        break;
+
+    case NodeRole::Widget:
+        result = QVariant();
+        break;
+    }
+
+    return result;
+}
+
+bool FlowGraphModel::setNodeData(NodeId nodeId, NodeRole role, QVariant value)
+{
+    bool result = false;
+
+    switch (role) {
+    case NodeRole::Type:
+        break;
+    case NodeRole::Position: {
+        _nodeGeometryData[nodeId].pos = value.value<QPointF>();
+
+        Q_EMIT nodePositionUpdated(nodeId);
+
+        result = true;
+    } break;
+
+    case NodeRole::Size: {
+        _nodeGeometryData[nodeId].size = value.value<QSize>();
+        result                         = true;
+    } break;
+
+    case NodeRole::CaptionVisible:
+        break;
+
+    case NodeRole::Caption:
+        break;
+
+    case NodeRole::Style:
+        break;
+
+    case NodeRole::InternalData:
+        break;
+
+    case NodeRole::InPortCount:
+        break;
+
+    case NodeRole::OutPortCount:
+        break;
+
+    case NodeRole::Widget:
+        break;
+    }
+
+    return result;
+}
+
+QVariant FlowGraphModel::portData(NodeId nodeId, PortType portType, PortIndex portIndex, PortRole role) const
+{
+    switch (role) {
+    case PortRole::Data:
+        return QVariant();
+        break;
+
+    case PortRole::DataType:
+        return QVariant();
+        break;
+
+    case PortRole::ConnectionPolicyRole:
+        return QVariant::fromValue(ConnectionPolicy::One);
+        break;
+
+    case PortRole::CaptionVisible:
+        return true;
+        break;
+
+    case PortRole::Caption:
+        if (portType == PortType::In)
+            return QString::fromUtf8("Port In");
+        else
+            return QString::fromUtf8("Port Out");
+
+        break;
+    }
+
+    return QVariant();
+}
+
+bool FlowGraphModel::setPortData(NodeId nodeId, PortType portType, PortIndex portIndex, QVariant const &value,
+                                 PortRole role)
+{
+    Q_UNUSED(nodeId);
+    Q_UNUSED(portType);
+    Q_UNUSED(portIndex);
+    Q_UNUSED(value);
+    Q_UNUSED(role);
+
+    return false;
+}
+
+bool FlowGraphModel::deleteConnection(ConnectionId const connectionId)
+{
+    bool disconnected = false;
+
+    auto it = _connectivity.find(connectionId);
+
+    if (it != _connectivity.end()) {
+        disconnected = true;
+
+        _connectivity.erase(it);
+    }
+
+    if (disconnected)
+        Q_EMIT connectionDeleted(connectionId);
+
+    return disconnected;
+}
+
+bool FlowGraphModel::deleteNode(NodeId const nodeId)
+{
+    // Delete connections to this node first.
+    auto connectionIds = allConnectionIds(nodeId);
+
+    for (auto &cId : connectionIds) {
+        deleteConnection(cId);
+    }
+
+    _nodeIds.erase(nodeId);
+    _nodeGeometryData.erase(nodeId);
+
+    Q_EMIT nodeDeleted(nodeId);
+
+    return true;
+}
+
+QJsonObject FlowGraphModel::saveNode(NodeId const nodeId) const
+{
+    QJsonObject nodeJson;
+
+    nodeJson["id"] = static_cast<qint64>(nodeId);
+
+    {
+        QPointF const pos = nodeData(nodeId, NodeRole::Position).value<QPointF>();
+
+        QJsonObject posJson;
+        posJson["x"]         = pos.x();
+        posJson["y"]         = pos.y();
+        nodeJson["position"] = posJson;
+    }
+
+    return nodeJson;
+}
+
+void FlowGraphModel::loadNode(QJsonObject const &nodeJson)
+{
+    NodeId restoredNodeId = static_cast<NodeId>(nodeJson["id"].toInt());
+
+    // Next NodeId must be larger that any id existing in the graph
+    _nextNodeId = std::max(_nextNodeId, restoredNodeId + 1);
+
+    // Create new node.
+    _nodeIds.insert(restoredNodeId);
+
+    Q_EMIT nodeCreated(restoredNodeId);
+
+    {
+        QJsonObject posJson = nodeJson["position"].toObject();
+        QPointF const pos(posJson["x"].toDouble(), posJson["y"].toDouble());
+
+        setNodeData(restoredNodeId, NodeRole::Position, pos);
+    }
+}

+ 104 - 0
QFD/shemeFlow/FlowGraphModel.h

@@ -0,0 +1,104 @@
+#ifndef FLOWGRAPHMODEL_H
+#define FLOWGRAPHMODEL_H
+
+#include <QJsonObject>
+#include <QPointF>
+#include <QSize>
+
+#include <QtNodes/AbstractGraphModel>
+#include <QtNodes/ConnectionIdUtils>
+#include <QtNodes/StyleCollection>
+
+using ConnectionId     = QtNodes::ConnectionId;
+using ConnectionPolicy = QtNodes::ConnectionPolicy;
+using NodeFlag         = QtNodes::NodeFlag;
+using NodeId           = QtNodes::NodeId;
+using NodeRole         = QtNodes::NodeRole;
+using PortIndex        = QtNodes::PortIndex;
+using PortRole         = QtNodes::PortRole;
+using PortType         = QtNodes::PortType;
+using StyleCollection  = QtNodes::StyleCollection;
+using QtNodes::InvalidNodeId;
+
+/**
+ * The class implements a bare minimum required to demonstrate a model-based
+ * graph.
+ */
+class FlowGraphModel : public QtNodes::AbstractGraphModel
+{
+    Q_OBJECT
+public:
+    struct NodeGeometryData
+    {
+        QSize size;
+        QPointF pos;
+    };
+
+public:
+    FlowGraphModel();
+
+    ~FlowGraphModel() override;
+
+    std::unordered_set<NodeId> allNodeIds() const override;
+
+    std::unordered_set<ConnectionId> allConnectionIds(NodeId const nodeId) const override;
+
+    std::unordered_set<ConnectionId> connections(NodeId nodeId, PortType portType, PortIndex portIndex) const override;
+
+    bool connectionExists(ConnectionId const connectionId) const override;
+
+    NodeId addNode(QString const nodeType = QString()) override;
+
+    /**
+     * Connection is possible when graph contains no connectivity data
+     * in both directions `Out -> In` and `In -> Out`.
+     */
+    bool connectionPossible(ConnectionId const connectionId) const override;
+
+    void addConnection(ConnectionId const connectionId) override;
+
+    bool nodeExists(NodeId const nodeId) const override;
+
+    QVariant nodeData(NodeId nodeId, NodeRole role) const override;
+
+    bool setNodeData(NodeId nodeId, NodeRole role, QVariant value) override;
+
+    QVariant portData(NodeId nodeId, PortType portType, PortIndex portIndex, PortRole role) const override;
+
+    bool setPortData(NodeId nodeId, PortType portType, PortIndex portIndex, QVariant const &value,
+                     PortRole role = PortRole::Data) override;
+
+    bool deleteConnection(ConnectionId const connectionId) override;
+
+    bool deleteNode(NodeId const nodeId) override;
+
+    QJsonObject saveNode(NodeId const) const override;
+
+    /// @brief Creates a new node based on the informatoin in `nodeJson`.
+    /**
+     * @param nodeJson conains a `NodeId`, node's position, internal node
+     * information.
+     */
+    void loadNode(QJsonObject const &nodeJson) override;
+
+    NodeId newNodeId() override { return _nextNodeId++; }
+
+private:
+    std::unordered_set<NodeId> _nodeIds;
+
+    /// [Important] This is a user defined data structure backing your model.
+    /// In your case it could be anything else representing a graph, for example, a
+    /// table. Or a collection of structs with pointers to each other. Or an
+    /// abstract syntax tree, you name it.
+    ///
+    /// This data structure contains the graph connectivity information in both
+    /// directions, i.e. from Node1 to Node2 and from Node2 to Node1.
+    std::unordered_set<ConnectionId> _connectivity;
+
+    mutable std::unordered_map<NodeId, NodeGeometryData> _nodeGeometryData;
+
+    /// A convenience variable needed for generating unique node ids.
+    unsigned int _nextNodeId;
+};
+
+#endif  // FLOWGRAPHMODEL_H

+ 172 - 0
QFD/shemeFlow/ShemeFlowPanel.cpp

@@ -0,0 +1,172 @@
+#include "DataFlowModel.h"
+#include "FlowGraphModel.h"
+#include "FlowTemplateDataModel.h"
+#include "ShemeFlowPanel.h"
+
+#include <QtNodes/BasicGraphicsScene>
+#include <QtNodes/ConnectionStyle>
+#include <QtNodes/DataFlowGraphicsScene>
+#include <QtNodes/GraphicsView>
+#include <QtNodes/GraphicsViewStyle>
+#include <QtNodes/NodeDelegateModelRegistry>
+
+#include <QCheckBox>
+#include <QGroupBox>
+#include <QHBoxLayout>
+
+using QtNodes::BasicGraphicsScene;
+using QtNodes::ConnectionStyle;
+using QtNodes::DataFlowGraphicsScene;
+using QtNodes::GraphicsView;
+using QtNodes::GraphicsViewStyle;
+using QtNodes::NodeDelegateModelRegistry;
+using QtNodes::NodeRole;
+using QtNodes::NodeStyle;
+
+static std::shared_ptr<NodeDelegateModelRegistry> registerDataModels()
+{
+    auto ret = std::make_shared<NodeDelegateModelRegistry>();
+
+    ret->registerModel<FlowTemplateDataModel>();
+
+    return ret;
+}
+static FlowGraphModel graphModel;
+
+static void setStyle_()
+{
+    GraphicsViewStyle::setStyle(
+            R"(
+  {
+    "GraphicsViewStyle": {
+      "BackgroundColor": [255, 255, 255],
+      "FineGridColor": [255, 255, 255],
+      "CoarseGridColor": [255, 255, 255]
+    }
+  }
+  )");
+
+    NodeStyle::setNodeStyle(
+            R"(
+  {
+    "NodeStyle": {
+      "NormalBoundaryColor": "darkgray",
+      "SelectedBoundaryColor": "deepskyblue",
+      "GradientColor0": "mintcream",
+      "GradientColor1": "mintcream",
+      "GradientColor2": "mintcream",
+      "GradientColor3": "mintcream",
+      "ShadowColor": [200, 200, 200],
+      "FontColor": [10, 10, 10],
+      "FontColorFaded": [100, 100, 100],
+      "ConnectionPointColor": "white",
+      "PenWidth": 2.0,
+      "HoveredPenWidth": 2.5,
+      "ConnectionPointDiameter": 10.0,
+      "Opacity": 1.0
+    }
+  }
+  )");
+
+    ConnectionStyle::setConnectionStyle(
+            R"(
+  {
+    "ConnectionStyle": {
+      "ConstructionColor": "gray",
+      "NormalColor": "black",
+      "SelectedColor": "gray",
+      "SelectedHaloColor": "deepskyblue",
+      "HoveredColor": "deepskyblue",
+
+      "LineWidth": 3.0,
+      "ConstructionLineWidth": 2.0,
+      "PointDiameter": 10.0,
+
+      "UseDataDefinedColors": false
+    }
+  }
+  )");
+}
+
+ShemeFlowPanel::ShemeFlowPanel(QWidget *parent) : QWidget(parent)
+{
+    setStyle_();
+#if 0
+    DataFlowModel *graphModel = new DataFlowModel(registerDataModels());
+
+    // Initialize and connect two nodes.
+    {
+        NodeId id1 = graphModel->addNode(FlowTemplateData().type().id);
+        graphModel->setNodeData(id1, NodeRole::Position, QPointF(0, 0));
+
+        NodeId id2 = graphModel->addNode(FlowTemplateData().type().id);
+        graphModel->setNodeData(id2, NodeRole::Position, QPointF(300, 300));
+
+        graphModel->addConnection(ConnectionId { id1, 0, id2, 0 });
+    }
+
+    auto scene = new DataFlowGraphicsScene(*graphModel);
+
+    QHBoxLayout *l = new QHBoxLayout(this);
+
+    GraphicsView *view = new GraphicsView(scene);
+
+    l->addWidget(view);
+
+    QGroupBox *groupBox = new QGroupBox("Options");
+
+    QCheckBox *cb1 = new QCheckBox("Nodes are locked");
+    QCheckBox *cb2 = new QCheckBox("Connections detachable");
+    cb2->setChecked(true);
+
+    QVBoxLayout *vbl = new QVBoxLayout;
+    vbl->addWidget(cb1);
+    vbl->addWidget(cb2);
+    vbl->addStretch();
+    groupBox->setLayout(vbl);
+
+    QObject::connect(cb1, &QCheckBox::stateChanged,
+                     [graphModel](int state) { graphModel->setNodesLocked(state == Qt::Checked); });
+
+    QObject::connect(cb2, &QCheckBox::stateChanged,
+                     [graphModel](int state) { graphModel->setDetachPossible(state == Qt::Checked); });
+
+    l->addWidget(groupBox);
+
+    this->setWindowTitle("Locked Nodes and Connections");
+    this->resize(800, 600);
+#endif
+
+    // Initialize and connect two nodes.
+    {
+        NodeId id1 = graphModel.addNode();
+        graphModel.setNodeData(id1, NodeRole::Position, QPointF(0, 0));
+
+        NodeId id2 = graphModel.addNode();
+        graphModel.setNodeData(id2, NodeRole::Position, QPointF(300, 300));
+
+        graphModel.addConnection(ConnectionId { id1, 0, id2, 0 });
+    }
+
+    auto scene = new BasicGraphicsScene(graphModel);
+
+    GraphicsView *view = new GraphicsView(scene);
+
+    //    // Setup context menu for creating new nodes.
+    view->setContextMenuPolicy(Qt::ActionsContextMenu);
+    QAction *createNodeAction = new QAction(QStringLiteral("Create Node"), view);
+    QObject::connect(createNodeAction, &QAction::triggered, [&]() {
+        // Mouse position in scene coordinates.
+        QPointF posView = view->mapToScene(view->mapFromGlobal(QCursor::pos()));
+
+        NodeId const newId = graphModel.addNode();
+        graphModel.setNodeData(newId, NodeRole::Position, posView);
+    });
+    view->insertAction(view->actions().front(), createNodeAction);
+
+    view->setWindowTitle("Simple Node Graph");
+    view->resize(800, 600);
+
+    QHBoxLayout *l = new QHBoxLayout(this);
+    l->addWidget(view);
+}

+ 12 - 0
QFD/shemeFlow/ShemeFlowPanel.h

@@ -0,0 +1,12 @@
+#ifndef SHEMEFLOWPANEL_H
+#define SHEMEFLOWPANEL_H
+
+#include <QWidget>
+
+class ShemeFlowPanel : public QWidget
+{
+public:
+    explicit ShemeFlowPanel(QWidget *parent = nullptr);
+};
+
+#endif  // SHEMEFLOWPANEL_H

+ 7 - 2
QFD/shemeFlow/shemeFlow.pri

@@ -1,5 +1,10 @@
 HEADERS += \
-    $$PWD/FlowTemplateDataModel.h
+    $$PWD/DataFlowModel.h \
+    $$PWD/FlowGraphModel.h \
+    $$PWD/FlowTemplateDataModel.h \
+    $$PWD/ShemeFlowPanel.h
 
 SOURCES += \
-    $$PWD/FlowTemplateDataModel.cpp
+    $$PWD/FlowGraphModel.cpp \
+    $$PWD/FlowTemplateDataModel.cpp \
+    $$PWD/ShemeFlowPanel.cpp

+ 5 - 5
QFD/shemeTable/AnalysisTableWidget.cpp

@@ -1,7 +1,7 @@
 #include "AnalysisTableWidget.h"
 #include "RequirementImportance.h"
 
-#include "ConsistencyCheck.h"
+#include "algorithm/ConsistencyCheck.h"
 #include <QDebug>
 #include <QHeaderView>
 #include <QTime>
@@ -150,7 +150,7 @@ void AnalysisTableWidget::paintMatrixTable(QList<NodeMatrixInfo *> nodeValueInfo
             DemandWeightService().AddNodeWeightInfoList(list);
         }
     } else {
-        //获取到指标体系需求重要度
+        // 获取到指标体系需求重要度
         model->setHorizontalHeaderItem(1, new QStandardItem("权重"));
         model->horizontalHeaderItem(1)->setToolTip("权重");
         for (int c = 0; c < col; ++c) {
@@ -232,7 +232,7 @@ void AnalysisTableWidget::paintMatrixTable(QList<NodeMatrixInfo *> nodeValueInfo
             model->item(row, c)->setTextAlignment(Qt::AlignCenter);
             model->item(row, c)->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
         }
-        //保存技术重要度
+        // 保存技术重要度
         QList<TechnicalImport *> importList;
 
         for (int c = 0; c < col; c++) {
@@ -336,7 +336,7 @@ void AnalysisTableWidget::paintCompositeMatrixTable(QList<NodeMatrixInfo *> node
         }
 
     } else {
-        //获取到指标体系需求重要度
+        // 获取到指标体系需求重要度
         model->setHorizontalHeaderItem(1, new QStandardItem("权重"));
         model->horizontalHeaderItem(1)->setToolTip("权重");
         for (int c = 0; c < col; ++c) {
@@ -490,7 +490,7 @@ void AnalysisTableWidget::paintSecondMatrixTable(QList<NodeMatrixInfo *> nodeVal
             model->item(r, col + 2)->setTextAlignment(Qt::AlignCenter);
             model->item(r, col + 2)->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
         }
-        //校验成功持久化数据
+        // 校验成功持久化数据
         QStringList nodeList   = cc.getNodes();
         QVector<qreal> weights = cc.getWieghts();
         QList<DemandWeight *> list;

+ 5 - 5
QFD/shemeTable/GroupTableWidget.cpp

@@ -2,7 +2,7 @@
 
 #include "RequirementImportance.h"
 
-#include "ConsistencyCheck.h"
+#include "algorithm/ConsistencyCheck.h"
 #include <QDebug>
 #include <QHeaderView>
 #include <QTime>
@@ -55,7 +55,7 @@ void GroupTableWidget::paintDemandTable(QList<QList<DemandWeight *>> nodeValueIn
     }
     model->setHorizontalHeaderItem(col + 1, new QStandardItem("群策结果"));
     model->horizontalHeaderItem(col + 1)->setToolTip("群策结果");
-    //第一行权重渲染
+    // 第一行权重渲染
     for (int c = 0; c < col + 1; c++) {
         if (c == 0) {
             model->setItem(0, c, new QStandardItem("专家权重"));
@@ -115,7 +115,7 @@ void GroupTableWidget::paintDemandTable(QList<QList<DemandWeight *>> nodeValueIn
             dataSource << data;
         }
     }
-    //最后一列进行计算
+    // 最后一列进行计算
     bool valid = false;
     if (arithmeticMethod == "arithmetic") {
         for (int r = 1; r < row + 1; r++) {
@@ -178,7 +178,7 @@ void GroupTableWidget::paintTechnicalTable(QList<QList<TechnicalImport *>> nodeV
     }
     model->setHorizontalHeaderItem(col + 1, new QStandardItem("技术重要度"));
     model->horizontalHeaderItem(col + 1)->setToolTip("技术重要度");
-    //第一行权重渲染
+    // 第一行权重渲染
     for (int c = 0; c < col + 1; c++) {
         if (c == 0) {
             model->setItem(0, c, new QStandardItem("专家权重"));
@@ -222,7 +222,7 @@ void GroupTableWidget::paintTechnicalTable(QList<QList<TechnicalImport *>> nodeV
             dataSource << data;
         }
     }
-    //最后一列进行计算
+    // 最后一列进行计算
 
     if (arithmeticMethod == "arithmetic") {
         for (int r = 1; r < row + 1; r++) {

+ 0 - 511
QFD/shemeTable/MatrixPanelWidget111.cpp

@@ -1,511 +0,0 @@
-#include "MatrixPanelWidget.h"
-#include "ui_MatrixPanelWidget.h"
-#include "MatrixTableWidget.h"
-#include "MatrixTableTechMeasuresWidget.h"
-#include "dbService/DBServiceSet.h"
-
-#include <CollectKnowledgeWidget.h>
-
-MatrixPanelWidget::MatrixPanelWidget(QWidget *parent) : QWidget(parent), ui(new Ui::MatrixPanelWidget)
-{
-    ui->setupUi(this);
-
-    firstLayout      = new QGridLayout;
-    firstPlainWidget = nullptr;
-    ui->stackedWidget->widget(0)->setLayout(firstLayout);
-    secondLayout      = new QGridLayout;
-    secondPlainWidget = nullptr;
-    ui->stackedWidget->widget(1)->setLayout(secondLayout);
-    ui->stackedWidget->setCurrentIndex(0);
-
-    ui->saveBtn->setDisabled(true);
-}
-
-MatrixPanelWidget::MatrixPanelWidget(QWidget *parent, ProfessorInfo professor)
-    : QWidget(parent), ui(new Ui::MatrixPanelWidget)
-{
-    ui->setupUi(this);
-
-    firstLayout      = new QGridLayout;
-    firstPlainWidget = nullptr;
-    ui->stackedWidget->widget(0)->setLayout(firstLayout);
-    secondLayout      = new QGridLayout;
-    secondPlainWidget = nullptr;
-    ui->stackedWidget->widget(1)->setLayout(secondLayout);
-    ui->stackedWidget->setCurrentIndex(0);
-
-    ui->saveBtn->setDisabled(true);
-
-    m_professor = professor;
-}
-
-MatrixPanelWidget::~MatrixPanelWidget()
-{
-    if (currentMindNodes) { delete currentMindNodes; }
-    if (classifiedNodes) { delete classifiedNodes; }
-    if (indexsRefClassifiedNodes) { delete indexsRefClassifiedNodes; }
-    delete ui;
-}
-
-void MatrixPanelWidget::init(const QStringList indexsRef, const QStringList indexs)
-{
-    indexsRefClassifiedNodes = nullptr;
-    if (!indexsRef.isEmpty()) {
-        MindNodeManager *indexsRefNodes = new MindNodeManager();  //是否参考指标体系
-        getMindNodes(indexsRefNodes, indexsRef);
-        indexsRefClassifiedNodes = new QList<QList<MindNodeManager::NodeMessage>>;
-        sortMindNodes(*indexsRefNodes, indexsRefClassifiedNodes);
-        delete indexsRefNodes;
-    }
-
-    if (!indexs.isEmpty()) {
-        currentMindNodes = new MindNodeManager();
-        classifiedNodes  = new QList<QList<MindNodeManager::NodeMessage>>;
-        getMindNodes(currentMindNodes, indexs);
-        sortMindNodes(*currentMindNodes, classifiedNodes);
-    } else {
-        currentMindNodes = nullptr;
-        classifiedNodes  = nullptr;
-    }
-
-    ui->toatalPagesLabel->setText(QString("共%1页").arg(getPages()));
-    ui->currPageLabel->setText(QString("当前第0页"));
-    if (!indexsRef.isEmpty()) {
-        currentTab = "技术措施";
-        initPlainTechMeasuresWidget();
-        setPage(1);
-        return;
-    }
-    if (!indexs.isEmpty()) {
-        currentTab = "";
-        initPlainWidget();
-        setPage(1);
-        return;
-    }
-}
-
-void MatrixPanelWidget::sortMindNodes(const MindNodeManager &manager,
-                                      QList<QList<MindNodeManager::NodeMessage>> *classify)
-{
-
-    for (MindNodeManager::NodeMessage msg : manager.getMindNodes()) {
-        QStringList nodePonit = msg.node.split(".");
-        while (nodePonit.count() - 1 > classify->count()) {
-            (*classify) << QList<MindNodeManager::NodeMessage>();
-        }
-        (*classify)[nodePonit.count() - 2] << msg;
-    }
-}
-
-void MatrixPanelWidget::getMindNodes(MindNodeManager *manager, QStringList listNodes)
-{
-    int sn[16];
-    memset(sn, 0, sizeof(int) * 16);
-    int spaceNum = -1;
-    int level    = 0;
-    MindNodeManager::NodeMessage temp;
-
-    manager->setMindName(listNodes[0].trimmed());
-
-    for (int i = 1; i < listNodes.count(); i++) {
-        int tempSpace = 0;
-        for (QString s : listNodes[i]) {
-            if (s == " ") {
-                tempSpace++;
-            } else {
-                break;
-            }
-        }
-        tempSpace /= 4;
-        if (tempSpace == 1) {  //一级
-            spaceNum = tempSpace;
-            level    = 0;
-            sn[level]++;
-            memset((void *)&sn[1], 0, sizeof(int) * 15);
-        } else {
-            if (spaceNum < tempSpace) {  //空格增加
-                spaceNum = tempSpace;
-                level++;
-                sn[level]++;
-            } else if (spaceNum == tempSpace) {  //同一级
-                sn[level]++;
-            } else {
-                spaceNum  = tempSpace;
-                sn[level] = 0;
-                level--;
-                sn[level]++;
-            }
-        }
-        QString node = "1";
-        for (int l : sn) {
-            if (l > 0) {
-                node += QString(".%1").arg(l);
-            } else {
-                break;
-            }
-        }
-        if (listNodes[i].trimmed().isEmpty()) {
-            temp.name   = QString("NULL(节点%1)").arg(node);
-            temp.node   = node;
-            temp.remark = "";
-            manager->pushNewMind(temp);
-        } else {
-            temp.name   = listNodes[i].trimmed().split("\t")[0];
-            temp.node   = node;
-            temp.remark = listNodes[i].trimmed().split("\t")[1];
-            manager->pushNewMind(temp);
-        }
-    }
-}
-
-QStringList MatrixPanelWidget::getFirstIndexNodes(const MindNodeManager &manager)
-{
-    QList<QList<MindNodeManager::NodeMessage>> classify;
-
-    for (MindNodeManager::NodeMessage msg : manager.getMindNodes()) {
-        QStringList nodePonit = msg.node.split(".");
-        while (nodePonit.count() - 1 > classify.count()) {
-            classify << QList<MindNodeManager::NodeMessage>();
-        }
-        classify[nodePonit.count() - 2] << msg;
-    }
-
-    QStringList firstNodes;
-
-    for (MindNodeManager::NodeMessage msg : classify.first()) {
-        firstNodes << msg.name;
-    }
-    return firstNodes;
-}
-
-QStringList MatrixPanelWidget::getLastIndexNodes(const MindNodeManager &manager)
-{
-    QList<QList<MindNodeManager::NodeMessage>> classify;
-
-    for (MindNodeManager::NodeMessage msg : manager.getMindNodes()) {
-        QStringList nodePonit = msg.node.split(".");
-        while (nodePonit.count() - 1 > classify.count()) {
-            classify << QList<MindNodeManager::NodeMessage>();
-        }
-        classify[nodePonit.count() - 2] << msg;
-    }
-
-    QStringList lastNodes;
-
-    for (MindNodeManager::NodeMessage msg : classify.last()) {
-        lastNodes << msg.name;
-    }
-    return lastNodes;
-}
-
-int MatrixPanelWidget::getPages()
-{
-#if 0
-    int max = 0;
-    for (MindNodeManager::NodeMessage msg : currentMindNodes->getMindNodes()) {
-        QStringList nodePonit = msg.node.split(".");
-        if (max < nodePonit.count() - 1) { max = nodePonit.count() - 1; }
-    }
-    return max;
-#else
-    if (!classifiedNodes) { return 0; }
-    return classifiedNodes->count();
-#endif
-}
-
-void MatrixPanelWidget::setPage(int page)
-{
-    if (page < 1 || page > getPages()) { return; }
-    currentPage = page;
-    ui->currPageLabel->setText(QString("当前第%1页").arg(currentPage));
-    if (currentPage == 1) {
-        ui->prePageBtn->setDisabled(true);
-        ui->nextPageBtn->setDisabled(false);
-    } else if (currentPage == getPages()) {
-        ui->prePageBtn->setDisabled(false);
-        ui->nextPageBtn->setDisabled(true);
-    } else {
-        ui->prePageBtn->setDisabled(false);
-        ui->nextPageBtn->setDisabled(false);
-    }
-    paintPlainWidget();
-}
-
-void MatrixPanelWidget::initPlainWidget()
-{
-    if (getPages() == 0) { return; }
-
-    //准备第一页,非tab的
-    MatrixTableWidget *table = new MatrixTableWidget((indexsRefClassifiedNodes == nullptr), nullptr);
-    connect(table, &MatrixTableWidget::dataReady, this, &MatrixPanelWidget::oneTableDataReady);
-    if (indexsRefClassifiedNodes) {
-        for (MindNodeManager::NodeMessage msg : indexsRefClassifiedNodes->last()) {
-            table->addRowNode(msg.node, msg.name, msg.remark);
-        }
-    }
-    for (MindNodeManager::NodeMessage msg : classifiedNodes->first()) {
-        table->addColNode(msg.node, msg.name, msg.remark);
-        if (indexsRefClassifiedNodes == nullptr) { table->addRowNode(msg.node, msg.name, msg.remark); }
-    }
-    table->paintMatrixTable();
-    firstLayout->addWidget(table);
-
-    //准备第二页,tab组合的
-    for (int p = 1; p < getPages(); ++p) {
-        QTabWidget *tab = new QTabWidget;
-        tab->setTabPosition(QTabWidget::South);
-        for (MindNodeManager::NodeMessage msg : classifiedNodes->at(p - 1)) {
-            QString node = msg.node;
-            //            MatrixTableWidget *table = nullptr;
-            table = nullptr;
-            for (MindNodeManager::NodeMessage info : classifiedNodes->at(p)) {
-                if ((info.node.count('.') == msg.node.count('.') + 1)
-                    && (info.node.left(msg.node.count()) == msg.node)) {
-                    if (!table) { table = new MatrixTableWidget((indexsRefClassifiedNodes == nullptr), nullptr); }
-                    if (table) {
-                        table->addColNode(info.node, info.name, info.remark);
-                        if (!indexsRefClassifiedNodes) { table->addRowNode(info.node, info.name, info.remark); }
-                    }
-                }
-            }
-            if (indexsRefClassifiedNodes) {
-                for (MindNodeManager::NodeMessage msg : indexsRefClassifiedNodes->last()) {
-                    table->addRowNode(msg.node, msg.name, msg.remark);
-                }
-            }
-            if (table) {
-                table->paintMatrixTable();
-                tab->addTab(table, msg.name);
-                connect(table, &MatrixTableWidget::dataReady, this, &MatrixPanelWidget::oneTableDataReady);
-            }
-        }
-        tabWidgets << tab;
-    }
-
-    //    secondLayout->addWidget(tab);
-}
-
-void MatrixPanelWidget::initPlainTechMeasuresWidget()
-{
-    if (getPages() == 0) { return; }
-
-    //准备第一页,非tab的
-    MatrixTableTechMeasuresWidget *table = new MatrixTableTechMeasuresWidget(nullptr);
-    connect(table, &MatrixTableTechMeasuresWidget::dataReady, this, &MatrixPanelWidget::oneTechMeasureTableDataReady);
-    if (indexsRefClassifiedNodes) {
-        for (MindNodeManager::NodeMessage msg : indexsRefClassifiedNodes->last()) {
-            table->addRowNode(msg.node, msg.name, msg.remark);
-        }
-    }
-    for (MindNodeManager::NodeMessage msg : classifiedNodes->first()) {
-        table->addColNode(msg.node, msg.name, msg.remark);
-        if (indexsRefClassifiedNodes == nullptr) { table->addRowNode(msg.node, msg.name, msg.remark); }
-    }
-    table->paintMatrixTable();
-    firstLayout->addWidget(table);
-
-    //准备第二页,tab组合的
-    for (int p = 1; p < getPages(); ++p) {
-        QTabWidget *tab = new QTabWidget;
-        tab->setTabPosition(QTabWidget::South);
-        for (MindNodeManager::NodeMessage msg : classifiedNodes->at(p - 1)) {
-            QString node = msg.node;
-            //            MatrixTableWidget *table = nullptr;
-            table = nullptr;
-            for (MindNodeManager::NodeMessage info : classifiedNodes->at(p)) {
-                if ((info.node.count('.') == msg.node.count('.') + 1)
-                    && (info.node.left(msg.node.count()) == msg.node)) {
-                    if (!table) { table = new MatrixTableTechMeasuresWidget(nullptr); }
-                    if (table) {
-                        table->addColNode(info.node, info.name, info.remark);
-                        if (!indexsRefClassifiedNodes) { table->addRowNode(info.node, info.name, info.remark); }
-                    }
-                }
-            }
-            if (indexsRefClassifiedNodes) {
-                for (MindNodeManager::NodeMessage msg : indexsRefClassifiedNodes->last()) {
-                    table->addRowNode(msg.node, msg.name, msg.remark);
-                }
-            }
-            if (table) {
-                table->paintMatrixTable();
-                tab->addTab(table, msg.name);
-                connect(table, &MatrixTableTechMeasuresWidget::dataReady, this,
-                        &MatrixPanelWidget::oneTechMeasureTableDataReady);
-            }
-        }
-        tabWidgets << tab;
-    }
-
-    //    secondLayout->addWidget(tab);
-}
-
-void MatrixPanelWidget::paintPlainWidget()
-{
-    bool firstShow = true;
-    if (getPages() == 0) { return; }
-
-    if (currentPage > 1) { firstShow = false; }
-
-    if (firstShow) {
-        ui->stackedWidget->setCurrentIndex(0);
-    } else {
-        QTabWidget *newTab = tabWidgets.at(currentPage - 2);
-        if (secondLayout->count() == 0) {
-            secondLayout->addWidget(newTab);
-            newTab->show();
-        } else {
-            QTabWidget *currTab = qobject_cast<QTabWidget *>(secondLayout->itemAt(0)->widget());
-            if (newTab == currTab) {
-                qDebug() << "same tab";
-            } else {
-                secondLayout->removeWidget(currTab);
-                currTab->hide();
-                secondLayout->addWidget(newTab);
-                newTab->show();
-            }
-        }
-        ui->stackedWidget->setCurrentIndex(1);
-    }
-}
-void MatrixPanelWidget::on_prePageBtn_clicked()
-{
-    setPage(currentPage - 1);
-}
-
-void MatrixPanelWidget::on_nextPageBtn_clicked()
-{
-    setPage(currentPage + 1);
-}
-
-void MatrixPanelWidget::on_saveBtn_clicked()
-{
-    if (currentTab == "技术措施") {
-        QList<NodeMatrixInfo *> nodeInfoList;
-        MatrixTableTechMeasuresWidget *first =
-                qobject_cast<MatrixTableTechMeasuresWidget *>(firstLayout->itemAt(0)->widget());
-
-        //保存第一页数据
-        for (MatrixDataSource s : first->getSource()) {
-            NodeMatrixInfo *t = new NodeMatrixInfo();
-            t->abscissa       = s.abscissa;
-            t->ordinate       = s.ordinate;
-            t->node           = s.node;
-            t->nodeValue      = s.nodeValue;
-            t->expertId       = m_professor.id;
-            t->expertName     = m_professor.name;
-            t->engineerId     = m_professor.engineer.engineerId;
-            t->writeDate      = m_professor.createDataTime;
-
-            nodeInfoList.append(t);
-        }
-        DBServiceSet().AddNodeMatrixInfoList(nodeInfoList);
-
-        //保存第二页数据,如果有
-        QList<NodeMatrixInfo *> secondNodeInfoList;
-        for (QTabWidget *tabWidget : tabWidgets) {
-            for (int i = 0; i < tabWidget->count(); ++i) {
-                MatrixTableTechMeasuresWidget *table =
-                        dynamic_cast<MatrixTableTechMeasuresWidget *>(tabWidget->widget(i));
-                for (MatrixDataSource s : table->getSource()) {
-                    NodeMatrixInfo *t = new NodeMatrixInfo();
-                    t->abscissa       = s.abscissa;
-                    t->ordinate       = s.ordinate;
-                    t->node           = s.node;
-                    t->nodeValue      = s.nodeValue;
-                    secondNodeInfoList.append(t);
-                }
-            }
-        }
-        DBServiceSet().AddNodeMatrixInfoList(secondNodeInfoList);
-        QMessageBox::information(this, tr("成功"), tr("数据保存成功"));
-        this->close();
-    } else {
-        QList<NodeMatrixInfo *> nodeInfoList;
-        MatrixTableWidget *first = qobject_cast<MatrixTableWidget *>(firstLayout->itemAt(0)->widget());
-        //保存第一页数据
-        for (MatrixDataSource s : first->getSource()) {
-            NodeMatrixInfo *t = new NodeMatrixInfo();
-            t->abscissa       = s.abscissa;
-            t->ordinate       = s.ordinate;
-            t->node           = s.node;
-            t->nodeValue      = s.nodeValue;
-            nodeInfoList.append(t);
-        }
-        DBServiceSet().AddNodeMatrixInfoList(nodeInfoList);
-
-        //保存第二页数据,如果有
-        QList<NodeMatrixInfo *> secondNodeInfoList;
-        for (QTabWidget *tabWidget : tabWidgets) {
-            for (int i = 0; i < tabWidget->count(); ++i) {
-                MatrixTableWidget *table = dynamic_cast<MatrixTableWidget *>(tabWidget->widget(i));
-                for (MatrixDataSource s : table->getSource()) {
-                    NodeMatrixInfo *t = new NodeMatrixInfo();
-                    t->abscissa       = s.abscissa;
-                    t->ordinate       = s.ordinate;
-                    t->node           = s.node;
-                    t->nodeValue      = s.nodeValue;
-                    t->expertId       = m_professor.name;
-                    t->expertName     = m_professor.name;
-                    t->engineerId     = m_professor.engineer.engineerId;
-                    t->writeDate      = m_professor.createDataTime;
-                    secondNodeInfoList.append(t);
-                }
-            }
-            DBServiceSet().AddNodeMatrixInfoList(secondNodeInfoList);
-            QMessageBox::information(this, tr("成功"), tr("数据保存成功"));
-            this->close();
-        }
-    }
-
-    void MatrixPanelWidget::oneTableDataReady(bool status)
-    {
-        if (status) {
-            bool filled              = true;
-            MatrixTableWidget *first = qobject_cast<MatrixTableWidget *>(firstLayout->itemAt(0)->widget());
-            if (!first->isDataReady()) { filled = false; }
-            for (QTabWidget *tab : tabWidgets) {
-                for (int t = 0; t < tab->count(); ++t) {
-                    MatrixTableWidget *table = qobject_cast<MatrixTableWidget *>(tab->widget(t));
-                    if (!table->isDataReady()) { filled = false; }
-                }
-            }
-
-            if (filled) {
-                ui->saveBtn->setDisabled(false);
-            } else {
-                ui->saveBtn->setDisabled(true);
-            }
-        } else {
-            ui->saveBtn->setDisabled(true);
-        }
-    }
-
-    void MatrixPanelWidget::oneTechMeasureTableDataReady(bool status)
-    {
-        qDebug() << "status = " << status;
-        if (status) {
-            bool filled = true;
-            MatrixTableTechMeasuresWidget *first =
-                    qobject_cast<MatrixTableTechMeasuresWidget *>(firstLayout->itemAt(0)->widget());
-            if (!first->isDataReady()) { filled = false; }
-            qDebug() << "filled1 = " << filled;
-            qDebug() << "tabWidgets = " << tabWidgets.size();
-            for (QTabWidget *tab : tabWidgets) {
-                for (int t = 0; t < tab->count(); ++t) {
-                    MatrixTableTechMeasuresWidget *table =
-                            qobject_cast<MatrixTableTechMeasuresWidget *>(tab->widget(t));
-                    qDebug() << "table = " << table->isDataReady();
-                    if (!table->isDataReady()) { filled = false; }
-                }
-            }
-            qDebug() << "filled2 = " << filled;
-            if (filled) {
-                ui->saveBtn->setDisabled(false);
-            } else {
-                ui->saveBtn->setDisabled(true);
-            }
-        } else {
-            ui->saveBtn->setDisabled(true);
-        }
-    }

+ 7 - 7
QFD/shemeTable/MatrixTableWidget.cpp

@@ -1,6 +1,6 @@
 #include "MatrixTableWidget.h"
 #include "MatrixTableItemDelegate.h"
-#include "shemeTable/ConsistencyCheck.h"
+#include "algorithm/ConsistencyCheck.h"
 
 #include <QApplication>
 #include <QDebug>
@@ -138,12 +138,12 @@ void MatrixTableWidget::nodeValueChanged(QStandardItem *item)
     if (paintDone) {
         bool valid         = false;
         QStringList valist = item->text().trimmed().split("/");
-        if (valist.count() > 2) {  //两个除号
+        if (valist.count() > 2) {  // 两个除号
             valid = false;
             item->setText("");
         } else if (valist.count() == 2) {
-            bool num = false;  //分子
-            bool den = false;  //分母
+            bool num = false;  // 分子
+            bool den = false;  // 分母
             valist[0].toDouble(&num);
             valist[1].toDouble(&den);
             if ((!num) || (!den)) {
@@ -224,7 +224,7 @@ void MatrixTableWidget::itemClicked(const QModelIndex &index)
 
 void MatrixTableWidget::pollCellsData()
 {
-    //检测是否存在空值
+    // 检测是否存在空值
     for (int r = 0; r < model->rowCount(); ++r) {
         for (int c = 0; c < model->columnCount(); ++c) {
             if (model->item(r, c)->text().isEmpty()) {
@@ -272,7 +272,7 @@ void MatrixTableWidget::pollCellsData()
                 }
             }
         } else {
-            //校验成功持久化数据
+            // 校验成功持久化数据
             QStringList nodeList   = cc.getNodes();
             QVector<qreal> weights = cc.getWieghts();
             qDebug() << weights;
@@ -291,7 +291,7 @@ void MatrixTableWidget::pollCellsData()
                     list.append(demandWeight);
                 }
             } else {
-                //查询出第一页权重
+                // 查询出第一页权重
                 QList<DemandWeight *> firstList;
                 DemandWeightService().QueryByTableIndexAndTableMsg(&firstList, m_expertId, m_engineerId, 0,
                                                                    m_table_msg);

+ 0 - 106
QFD/shemeTable/SetPairAnalysis.cpp

@@ -1,106 +0,0 @@
-#include "SetPairAnalysis.h"
-#include <QDebug>
-
-/********************************************************************
- *@Demo1归一化均值
- * QVector<SetPairAnalysis::EvaluateIndex> rMat;
- * rMat << SetPairAnalysis::EvaluateIndex { 70, 20, 10 };
- * rMat << SetPairAnalysis::EvaluateIndex { 70, 18, 12 };
- * QVector<qreal> wMat, eMat;
- * wMat << 1.0 << 0.5 << 1.0;
- * eMat << 1.0 << 1.0 << -1.0;
- * SetPairAnalysis spa(rMat, wMat, eMat);
- * SetPairAnalysis::Relations r = spa.getRelations();
- * qDebug() << r;
- *
- *@Demo2总体平衡均值
- * QVector<SetPairAnalysis::EvaluateIndex> rMat;
- * QVector<qreal> wMat, eMat;
- * rMat << SetPairAnalysis::EvaluateIndex { 2.5, 66, 80, 800 };
- * rMat << SetPairAnalysis::EvaluateIndex { 3.0, 79, 77, 810 };
- * rMat << SetPairAnalysis::EvaluateIndex { 3.5, 85, 90, 900 };
- * rMat << SetPairAnalysis::EvaluateIndex { 4.0, 98, 92, 920 };
- * rMat << SetPairAnalysis::EvaluateIndex { 3.5, 83, 88, 780 };
- * wMat << 0.3 << 0.5 << 0.15 << 0.05;
- * eMat << 1.0 << 1.0 << 1.0 << 1.0;
- * QVector<bool> dir;
- * dir << false << true << false << false;
- * SetPairAnalysis spa(rMat, wMat, eMat, dir);
- * SetPairAnalysis::Relations r = spa.getRelations();
- * qDebug() << r;
- *
- *
- ********************************************************************/
-
-SetPairAnalysis::SetPairAnalysis(const QVector<SetPairAnalysis::EvaluateIndex> &rMat, const QVector<qreal> &wMat,
-                                 const QVector<qreal> &eMat, const QVector<bool> &optiDir)
-    : m_rMat(rMat), m_wMat(wMat), m_eMat(eMat)
-{
-    Q_ASSERT(rMat.count() != 0);
-    Q_ASSERT(rMat.at(0).count() != 0);
-    // Q_ASSERT(rMat.at(0).count() == wMat.count());
-
-    if (optiDir.isEmpty()) {
-        for (auto &r : m_rMat) {
-            qreal sum = 0;
-            for (int i = 0; i < r.count(); ++i) {
-                sum += r.at(i);
-            }
-            for (int i = 0; i < r.count(); ++i) {
-                r[i] = r[i] / sum;
-            }
-        }
-    } else {
-        EvaluateIndex optiIndex = EvaluateIndex(m_rMat.at(0).count());
-        for (int r = 0; r < m_rMat.count(); ++r) {
-            for (int i = 0; i < m_rMat.at(r).count(); ++i) {
-                if (r == 0) {
-                    optiIndex[i] = m_rMat.at(r).at(i);
-                } else {
-                    if (optiDir.at(i)) {  //最大值
-                        if (optiIndex.at(i) < m_rMat.at(r).at(i)) {
-                            optiIndex[i] = m_rMat.at(r).at(i);
-                        }
-                    } else {
-                        if (optiIndex.at(i) > m_rMat.at(r).at(i)) {
-                            optiIndex[i] = m_rMat.at(r).at(i);
-                        }
-                    }
-                }
-            }
-        }
-        // qDebug() << optiIndex;
-        for (auto &r : m_rMat) {
-            for (int i = 0; i < r.count(); ++i) {
-                if (optiDir.at(i)) {  //最大值
-                    // qDebug() << r[i] << "/" << optiIndex.at(i);
-                    r[i] = r[i] / optiIndex.at(i);
-                } else {
-                    // qDebug() << optiIndex.at(i) << "/" << r[i];
-                    r[i] = optiIndex.at(i) / r[i];
-                }
-            }
-            // qDebug() << "next";
-        }
-    }
-
-    //    qDebug() << m_rMat;
-    if (m_eMat.isEmpty()) {
-        m_eMat = QVector<qreal>(m_wMat.count(), 1.0);
-    }
-}
-
-SetPairAnalysis::Relations SetPairAnalysis::getRelations() const
-{
-    Relations uMat;
-
-    for (auto r : m_rMat) {
-        qreal ui = 0;
-        for (int i = 0; i < r.count(); ++i) {
-            ui += r.at(i) * m_wMat.at(i) * m_eMat.at(i);
-        }
-        uMat << ui;
-    }
-
-    return uMat;
-}

+ 0 - 47
QFD/shemeTable/SetPairAnalysis.h

@@ -1,47 +0,0 @@
-#ifndef SETPAIRANALYSIS_H
-#define SETPAIRANALYSIS_H
-
-#include <QString>
-#include <QVector>
-
-/**
- * @brief 集对分析法,SPA,又称同异反综合分析法
- * 集成析是从系统的角度去认识确定性和不确定性的关系,并确定研究对象是一个确定不确定系统,
- * 其不确定性和确定性共同处于一个统一体之中。因此别从确定的角度和不确足的角度来研究不确定性的规律,并用联系度表示。
- * a:S/N 相同属性联系度(同一度)
- * b:F/N 相异属性联系度(差异度)
- * c:P/N 相反属性联系度(对立度)
- * 集对联系度公式:u = a + b*i + c*j
- */
-class SetPairAnalysis
-{
-public:
-    typedef QVector<qreal> EvaluateIndex;  //评估指标
-    typedef QVector<qreal> Relations;      //联系度
-    typedef QStringList EvaluateNames;     //评估对象
-    /**
-     * @brief 集对分析法构造函数
-     * @param rMat 同异反评估矩阵
-     * @param wMat 权重系数矩阵
-     * @param eMat 同异反系数矩阵
-     * @param optiDir false:最小值,true:最大值
-     */
-    SetPairAnalysis(const QVector<EvaluateIndex> &rMat, const QVector<qreal> &wMat,
-                    const QVector<qreal> &eMat = QVector<qreal>(), const QVector<bool> &optiDir = QVector<bool>());
-
-    void setEvaluateNames(const EvaluateNames &names) { m_evalNames = names; }
-    EvaluateNames getEvaluateNames() const { return m_evalNames; }
-    /**
-     * @brief 联系度值
-     * @return
-     */
-    Relations getRelations() const;
-
-private:
-    QVector<EvaluateIndex> m_rMat;
-    QVector<qreal> m_wMat;
-    QVector<qreal> m_eMat;
-    EvaluateNames m_evalNames;
-};
-
-#endif  // SETPAIRANALYSIS_H

+ 10 - 11
QFD/shemeTable/shemeTable.pri

@@ -5,13 +5,13 @@ FORMS += \
     $$PWD/MatrixPanelWidget.ui \
     $$PWD/ModelViewTable.ui \
     $$PWD/ProfessionInfo.ui \
-    $$PWD/UserConfigDlg.ui
+    $$PWD/ProfessorInputTable.ui \
+    $$PWD/UserConfigDlg.ui \
+    $$PWD/mainwindow.ui
 
 HEADERS += \
     $$PWD/AnalysisPanelWidget.h \
     $$PWD/AnalysisTableWidget.h \
-    $$PWD/AverageMethod.h \
-    $$PWD/ConsistencyCheck.h \
     $$PWD/ExportProjectDlg.h \
     $$PWD/GroupPanelWidget.h \
     $$PWD/GroupTableWidget.h \
@@ -19,20 +19,18 @@ HEADERS += \
     $$PWD/MatrixTableItemDelegate.h \
     $$PWD/MatrixTableTechMeasuresWidget.h \
     $$PWD/MatrixTableWidget.h \
-    $$PWD/MinMaxAnalysis.h \
     $$PWD/ModelViewTable.h \
+    $$PWD/ProfessInputTable.h \
     $$PWD/ProfessionInfo.h \
+    $$PWD/ProfessorInputTable.h \
     $$PWD/RequirementImportance.h \
-    $$PWD/SetPairAnalysis.h \
     $$PWD/SpinBoxDelegate.h \
     $$PWD/UserConfigDlg.h \
-    $$PWD/ZScore.h
+    $$PWD/mainwindow.h
 
 SOURCES += \
     $$PWD/AnalysisPanelWidget.cpp \
     $$PWD/AnalysisTableWidget.cpp \
-    $$PWD/AverageMethod.cpp \
-    $$PWD/ConsistencyCheck.cpp \
     $$PWD/ExportProjectDlg.cpp \
     $$PWD/GroupPanelWidget.cpp \
     $$PWD/GroupTableWidget.cpp \
@@ -40,10 +38,11 @@ SOURCES += \
     $$PWD/MatrixTableItemDelegate.cpp \
     $$PWD/MatrixTableTechMeasuresWidget.cpp \
     $$PWD/MatrixTableWidget.cpp \
-    $$PWD/MinMaxAnalysis.cpp \
     $$PWD/ModelViewTable.cpp \
+    $$PWD/ProfessInputTable.cpp \
     $$PWD/ProfessionInfo.cpp \
-    $$PWD/SetPairAnalysis.cpp \
+    $$PWD/ProfessorInputTable.cpp \
     $$PWD/SpinBoxDelegate.cpp \
     $$PWD/UserConfigDlg.cpp \
-    $$PWD/ZScore.cpp
+    $$PWD/main.cpp \
+    $$PWD/mainwindow.cpp

+ 75 - 23
QtNodes/src/ConnectionPainter.cpp

@@ -8,12 +8,52 @@
 #include "Definitions.hpp"
 #include "NodeData.hpp"
 #include "StyleCollection.hpp"
+#include <QtMath>
 
 namespace QtNodes {
 
+static QPainterPath arrowPath(QPainterPath const &cubic)
+{
+    QPainterPath arrow;
+
+    // 绘制箭头
+    double ctrlPercent = 0.9;
+    if (cubic.length() > 100) {
+        ctrlPercent = cubic.percentAtLength(cubic.length() - 10);
+    } else if (cubic.length() < 10) {
+        ctrlPercent = 0.5;
+    }
+    QPointF end       = cubic.pointAtPercent(1);
+    QPointF ctrlPoint = cubic.pointAtPercent(ctrlPercent);
+    double angle      = cubic.angleAtPercent(ctrlPercent);
+
+    QLineF lineBottom;
+    lineBottom.setP1(ctrlPoint);
+    lineBottom.setAngle(angle + 90);
+    //    double scale     = 0.05 - ctrlPercent / 50;
+    //    qreal lineLength = cubic.length() * scale;
+    //    if (lineLength < 5) {
+    //        lineLength = 5;
+    //    } else if (lineLength > 10) {
+    //        lineLength = 10;
+    //    }
+    qreal lineLength = 5;
+    lineBottom.setLength(lineLength);
+    QPointF arrowLeft = lineBottom.p2();
+    lineBottom.setAngle(lineBottom.angle() + 180);
+    QPointF arrowRight = lineBottom.p2();
+
+    arrow.moveTo(end);
+    arrow.lineTo(arrowLeft);
+    arrow.lineTo(arrowRight);
+    arrow.lineTo(end);
+
+    return arrow;
+}
+
 static QPainterPath cubicPath(ConnectionGraphicsObject const &connection)
 {
-    QPointF const &in = connection.endPoint(PortType::In);
+    QPointF const &in  = connection.endPoint(PortType::In);
     QPointF const &out = connection.endPoint(PortType::Out);
 
     auto const c1c2 = connection.pointsC1C2();
@@ -52,7 +92,7 @@ static void debugDrawing(QPainter *painter, ConnectionGraphicsObject const &cgo)
     Q_UNUSED(painter);
 
     {
-        QPointF const &in = cgo.endPoint(PortType::In);
+        QPointF const &in  = cgo.endPoint(PortType::In);
         QPointF const &out = cgo.endPoint(PortType::Out);
 
         auto const points = cgo.pointsC1C2();
@@ -97,12 +137,17 @@ static void drawSketchLine(QPainter *painter, ConnectionGraphicsObject const &cg
 
         // cubic spline
         painter->drawPath(cubic);
+
+        // arrow line
+        auto arrow = arrowPath(cubic);
+        painter->setBrush(pen.color());
+        painter->drawPath(arrow);
     }
 }
 
 static void drawHoveredOrSelected(QPainter *painter, ConnectionGraphicsObject const &cgo)
 {
-    bool const hovered = cgo.connectionState().hovered();
+    bool const hovered  = cgo.connectionState().hovered();
     bool const selected = cgo.isSelected();
 
     // drawn as a fat background
@@ -113,8 +158,7 @@ static void drawHoveredOrSelected(QPainter *painter, ConnectionGraphicsObject co
 
         QPen pen;
         pen.setWidth(2 * lineWidth);
-        pen.setColor(selected ? connectionStyle.selectedHaloColor()
-                              : connectionStyle.hoveredColor());
+        pen.setColor(selected ? connectionStyle.selectedHaloColor() : connectionStyle.hoveredColor());
 
         painter->setPen(pen);
         painter->setBrush(Qt::NoBrush);
@@ -122,6 +166,11 @@ static void drawHoveredOrSelected(QPainter *painter, ConnectionGraphicsObject co
         // cubic spline
         auto const cubic = cubicPath(cgo);
         painter->drawPath(cubic);
+
+        // arrow line
+        auto arrow = arrowPath(cubic);
+        painter->setBrush(pen.color());
+        painter->drawPath(arrow);
     }
 }
 
@@ -137,8 +186,8 @@ static void drawNormalLine(QPainter *painter, ConnectionGraphicsObject const &cg
     auto const &connectionStyle = QtNodes::StyleCollection::connectionStyle();
 
     QColor normalColorOut = connectionStyle.normalColor();
-    QColor normalColorIn = connectionStyle.normalColor();
-    QColor selectedColor = connectionStyle.selectedColor();
+    QColor normalColorIn  = connectionStyle.normalColor();
+    QColor selectedColor  = connectionStyle.selectedColor();
 
     bool useGradientColor = false;
 
@@ -149,22 +198,17 @@ static void drawNormalLine(QPainter *painter, ConnectionGraphicsObject const &cg
 
         auto const cId = cgo.connectionId();
 
-        auto dataTypeOut = graphModel
-                               .portData(cId.outNodeId,
-                                         PortType::Out,
-                                         cId.outPortIndex,
-                                         PortRole::DataType)
-                               .value<NodeDataType>();
+        auto dataTypeOut = graphModel.portData(cId.outNodeId, PortType::Out, cId.outPortIndex, PortRole::DataType)
+                                   .value<NodeDataType>();
 
-        auto dataTypeIn
-            = graphModel.portData(cId.inNodeId, PortType::In, cId.inPortIndex, PortRole::DataType)
-                  .value<NodeDataType>();
+        auto dataTypeIn = graphModel.portData(cId.inNodeId, PortType::In, cId.inPortIndex, PortRole::DataType)
+                                  .value<NodeDataType>();
 
         useGradientColor = (dataTypeOut.id != dataTypeIn.id);
 
         normalColorOut = connectionStyle.normalColor(dataTypeOut.id);
-        normalColorIn = connectionStyle.normalColor(dataTypeIn.id);
-        selectedColor = normalColorOut.darker(200);
+        normalColorIn  = connectionStyle.normalColor(dataTypeIn.id);
+        selectedColor  = normalColorOut.darker(200);
     }
 
     // geometry
@@ -192,7 +236,7 @@ static void drawNormalLine(QPainter *painter, ConnectionGraphicsObject const &cg
 
         for (unsigned int i = 0ul; i < segments; ++i) {
             double ratioPrev = double(i) / segments;
-            double ratio = double(i + 1) / segments;
+            double ratio     = double(i + 1) / segments;
 
             if (i == segments / 2) {
                 QColor cIn = normalColorIn;
@@ -205,13 +249,16 @@ static void drawNormalLine(QPainter *painter, ConnectionGraphicsObject const &cg
             painter->drawLine(cubic.pointAtPercent(ratioPrev), cubic.pointAtPercent(ratio));
         }
 
+        // arrow line
+        auto arrow = arrowPath(cubic);
+        painter->setBrush(p.color());
+        painter->drawPath(arrow);
+
         {
             QIcon icon(":convert.png");
 
             QPixmap pixmap = icon.pixmap(QSize(22, 22));
-            painter->drawPixmap(cubic.pointAtPercent(0.50)
-                                    - QPoint(pixmap.width() / 2, pixmap.height() / 2),
-                                pixmap);
+            painter->drawPixmap(cubic.pointAtPercent(0.50) - QPoint(pixmap.width() / 2, pixmap.height() / 2), pixmap);
         }
     } else {
         p.setColor(normalColorOut);
@@ -224,6 +271,11 @@ static void drawNormalLine(QPainter *painter, ConnectionGraphicsObject const &cg
         painter->setBrush(Qt::NoBrush);
 
         painter->drawPath(cubic);
+
+        // arrow line
+        auto arrow = arrowPath(cubic);
+        painter->setBrush(p.color());
+        painter->drawPath(arrow);
     }
 }
 
@@ -251,4 +303,4 @@ void ConnectionPainter::paint(QPainter *painter, ConnectionGraphicsObject const
     painter->drawEllipse(cgo.in(), pointRadius, pointRadius);
 }
 
-} // namespace QtNodes
+}  // namespace QtNodes