From 5661ba80e8a8781ad435138f4e2028a8c68ebeaa Mon Sep 17 00:00:00 2001 From: codeboss <2422523675@qq.com> Date: Sun, 6 Oct 2024 16:03:19 +0800 Subject: [PATCH] helf --- StoryPresent/dag_layout.cpp | 179 +++++++++++++++++++++++++++++++--- StoryPresent/dag_layout.h | 9 +- StoryPresent/dag_present.cpp | 3 + StoryPresent/storypresent.cpp | 6 +- 4 files changed, 178 insertions(+), 19 deletions(-) diff --git a/StoryPresent/dag_layout.cpp b/StoryPresent/dag_layout.cpp index 1eeb640..4e95b9a 100644 --- a/StoryPresent/dag_layout.cpp +++ b/StoryPresent/dag_layout.cpp @@ -270,16 +270,21 @@ void DAGGraph::graph_layer_nodes_sort_forward(int layer_index, const QList a, std::shared_ptr b) { + return a->sortNumber() < b->sortNumber(); + }); + // 提取当前层次节点排序值 - this->current_nodelist_filling_indi(layer_index, nodes); + this->current_nodelist_filling_indi(nodes_within_current_layer); } this->nodes_sort_with_above(layer_index, nodes); this->graph_layer_nodes_sort_forward(layer_index + 1, nodes); } } - -bool dags::DAGGraph::current_nodelist_filling_indi(int layer_index, const QList>& nodes) +/* +bool dags::DAGGraph::current_layer_filling_indi(int layer_index, const QList>& nodes) { // 提取本层次节点 QList> nodes_within_current_layer; @@ -308,6 +313,11 @@ bool dags::DAGGraph::current_nodelist_filling_indi(int layer_index, const QList< return (*upnode_a)->sortNumber() < (*upnode_b)->sortNumber(); }); + this->current_nodelist_filling_indi(nodes_within_current_layer); +} +*/ +bool dags::DAGGraph::current_nodelist_filling_indi(const QList>& nodes_within_current_layer) +{ // 提取节点划分档次 QList ordered_values; std::transform(nodes_within_current_layer.begin(), nodes_within_current_layer.end(), @@ -376,20 +386,25 @@ void dags::DAGGraph::nodes_sort_with_above(int layer_index, const QListsetSortNumber(sort_idx - temp_anchor.second); } + + //for (auto n : sorting_nodes) { + // qDebug() << n->layerNumber() << n->sortNumber().toDouble(); + //} + //qDebug() << "=============================="; } void dags::DAGGraph::graph_adjust_after_layout(const QList>& total_nodes) { auto layer_index = this->maxLayerCount() - 1; while (layer_index > -1) { - this->layer_adjust_via_next_sibling(layer_index, total_nodes); - if (this->current_nodelist_filling_indi(layer_index, total_nodes)) + auto nlist = this->layer_adjust_via_next_sibling(layer_index, total_nodes); + if (this->current_nodelist_filling_indi(nlist)) this->nodes_sort_with_belows(layer_index, total_nodes); layer_index--; }; } -bool dags::DAGGraph::layer_adjust_via_next_sibling(int curr_layer, const QList>& total_nodes) +QList> dags::DAGGraph::layer_adjust_via_next_sibling(int curr_layer, const QList>& total_nodes) { QList> curr_layer_nodes; std::copy_if(total_nodes.begin(), total_nodes.end(), std::back_inserter(curr_layer_nodes), @@ -399,7 +414,27 @@ bool dags::DAGGraph::layer_adjust_via_next_sibling(int curr_layer, const QListnode_adjust_via_next_sibling(node, total_nodes); } - return curr_layer; + std::sort(curr_layer_nodes.begin(), curr_layer_nodes.end(), + [](std::shared_ptra, std::shared_ptr b)->bool { + auto prevs_a = a->getUpstreamNodes(); + auto prevs_b = b->getUpstreamNodes(); + + if (!prevs_a.size() && !prevs_b.size()) + return a > b; + if (!prevs_a.size()) + return true; + if (!prevs_b.size()) + return false; + + auto upnode_a = std::min_element(prevs_a.begin(), prevs_a.end(), + [](std::shared_ptr a, std::shared_ptr b) { return a->sortNumber() < b->sortNumber(); }); + auto upnode_b = std::min_element(prevs_b.begin(), prevs_b.end(), + [](std::shared_ptr a, std::shared_ptr b) { return a->sortNumber() < b->sortNumber(); }); + + return (*upnode_a)->sortNumber() < (*upnode_b)->sortNumber(); + }); + + return curr_layer_nodes; } void dags::DAGGraph::node_adjust_via_next_sibling(std::shared_ptr curr_node, const QList>& total_nodes) @@ -473,6 +508,11 @@ void dags::DAGGraph::node_adjust_ingraph_forward(const QListnode_adjust_inlayer_forward(layer_index, total_nodes)) { layer_index++; + } + + for (auto idx = 0; idx < layer_index; ++idx) { + this->sort_index_partition_indi(idx, total_nodes); + this->nodes_sort_with_above(idx, total_nodes); } } @@ -487,18 +527,28 @@ bool dags::DAGGraph::node_adjust_inlayer_forward(int curr_layer, const QList, qlonglong, qlonglong>> orders_helper; + QList, qlonglong, qlonglong, qlonglong, qlonglong>> orders_helper; std::transform(curr_layer_nodes.begin(), curr_layer_nodes.end(), std::back_inserter(orders_helper), [&](std::shared_ptr ins) { - auto val = this->node_evaluate_with_downstream(ins, total_nodes); - return std::make_tuple(ins, val.first, val.second); + auto val_n = this->node_evaluate_with_downstream(ins, total_nodes); + auto val_p = this->node_evaluate_with_upstream(ins, total_nodes); + return std::make_tuple(ins, val_n.first, val_n.second, val_p.first, val_p.second); }); // 排序当前层次节点 - std::sort(orders_helper.begin(), orders_helper.end(), - [](std::tuple, qlonglong, qlonglong> a, std::tuple, qlonglong, qlonglong> b) { - if (std::get<1>(a) == std::get<1>(b)) + std::sort(orders_helper.begin(), orders_helper.end(), []( + std::tuple, qlonglong, qlonglong, qlonglong, qlonglong> a, + std::tuple, qlonglong, qlonglong, qlonglong, qlonglong> b) + { + if (std::get<1>(a) == std::get<1>(b)) { + if (std::get<2>(a) == std::get<2>(b)) { + if (std::get<3>(a) == std::get<3>(b)) { + return std::get<4>(a) < std::get<4>(b); + } + return std::get<3>(a) < std::get<3>(b); + } return std::get<2>(a) < std::get<2>(b); + } return std::get<1>(a) < std::get<1>(b); }); @@ -516,6 +566,75 @@ bool dags::DAGGraph::node_adjust_inlayer_forward(int curr_layer, const QList>& total_nodes) +{ + // 提取层次节点 + QList> nodes_within_current_layer; + std::copy_if(total_nodes.begin(), total_nodes.end(), std::back_inserter(nodes_within_current_layer), + [=](std::shared_ptr inst) { + return layer_index == inst->layerNumber(); + }); + // 排序节点 + std::sort(nodes_within_current_layer.begin(), nodes_within_current_layer.end(), + [](std::shared_ptr a, std::shared_ptr b) { + return a->sortNumber() < b->sortNumber(); + }); + + if (!nodes_within_current_layer.size()) + return false; + + + // 获取布局系数 + QList, QVariant>> sort_helper; + for (auto& inst : nodes_within_current_layer) { + auto prev_nodes = inst->getUpstreamNodes(); + if (!prev_nodes.size()) { + sort_helper.append(std::make_pair(inst, QVariant())); + continue; + } + + auto anchor_it = std::min_element(prev_nodes.begin(), prev_nodes.end(), + [](std::shared_ptr a, std::shared_ptr b) { + return a->layerNumber() < b->layerNumber(); + }); + sort_helper.append(std::make_pair(*anchor_it, (*anchor_it)->sortNumber())); + } + + QVariant start_value; + for (auto idx = 0; idx < sort_helper.size(); ++idx) { + auto curr_u = sort_helper[idx]; + if (!curr_u.second.isNull()) { + start_value = curr_u.second; + if (idx > 0) { + auto u = sort_helper[0]; + sort_helper[0] = std::make_pair(u.first, start_value.toInt() - 1); + } + break; + } + } + if (start_value.isNull()) + return false; + + for (int idx = 1; idx < sort_helper.size(); ++idx) { + auto prev_u = sort_helper[idx - 1]; + auto curr_u = sort_helper[idx]; + + if (curr_u.second.isNull()) { + sort_helper[idx] = std::make_pair(curr_u.first, prev_u.second); + } + if (curr_u.second < prev_u.second) { + sort_helper[idx] = std::make_pair(curr_u.first, prev_u.second); + } + } + std::for_each(sort_helper.begin(), sort_helper.end(), + [](std::pair, QVariant> u) { + u.first->setSortNumber(u.second.toDouble()); + }); + + this->current_nodelist_filling_indi(nodes_within_current_layer); + return true; +} + std::pair dags::DAGGraph::node_evaluate_with_downstream(std::shared_ptr node, const QList>& total_nodes) { decltype(node) next_node; @@ -555,6 +674,40 @@ std::pair dags::DAGGraph::node_evaluate_with_downstream(st return std::make_pair(next_node->layerNumber(), next_node->sortNumber().toLongLong()); } +std::pair dags::DAGGraph::node_evaluate_with_upstream(std::shared_ptr node, const QList>& total_nodes) +{ + auto prim_nodes = node->getUpstreamNodes(); + if (!prim_nodes.size()) + return std::make_pair(node->layerNumber(), node->sortNumber().toLongLong()); + + QList> prev_nodes; + std::transform(prim_nodes.begin(), prim_nodes.end(), std::back_inserter(prev_nodes), + [&](std::shared_ptr ins) { + if (!ins->isFakeNode()) { + return ins; + } + + auto prev_data = ins->tailsNode(); + auto target_it = std::find_if(total_nodes.begin(), total_nodes.end(), + [&](std::shared_ptr nins) { + if (!nins->isFakeNode()) + return nins->layerNode() == prev_data; + return false; + }); + + return *target_it; + }); + + + auto prev_it = std::min_element(prev_nodes.begin(), prev_nodes.end(), + [](std::shared_ptr a, std::shared_ptr b) { + if (a->layerNumber() == b->layerNumber()) + return a->sortNumber() < b->sortNumber(); + return a->layerNumber() < b->layerNumber(); + }); + return std::make_pair((*prev_it)->layerNumber(), (*prev_it)->sortNumber().toLongLong()); +} + void dags::DAGGraph::primitiveGraphLayout() { QList> sort_seqs; QList> refs; diff --git a/StoryPresent/dag_layout.h b/StoryPresent/dag_layout.h index f3b82c5..52df8a8 100644 --- a/StoryPresent/dag_layout.h +++ b/StoryPresent/dag_layout.h @@ -93,15 +93,17 @@ namespace dags { void graph_layer_nodes_sort_forward(int layer_index, const QList> &nodes); void graph_adjust_after_layout(const QList>& total_nodes); - bool layer_adjust_via_next_sibling(int curr_layer, const QList>& total_nodes); + QList> layer_adjust_via_next_sibling(int curr_layer, const QList>& total_nodes); void node_adjust_via_next_sibling(std::shared_ptr curr_node, const QList>& total_nodes); - - bool current_nodelist_filling_indi(int curr_layer, const QList>& total_nodes); + + //bool current_layer_filling_indi(int curr_layer, const QList>& total_nodes); + bool current_nodelist_filling_indi(const QList>& ordered_nodes); void nodes_sort_with_above(int curr_layer, const QList>& total_nodes); void nodes_sort_with_belows(int curr_layer, const QList>& total_nodes); void node_adjust_ingraph_forward(const QList>& total_nodes); bool node_adjust_inlayer_forward(int curr_layer, const QList>& total_nodes); + bool sort_index_partition_indi(int layer_index, const QList>& total_nodes); /** * . * @@ -110,6 +112,7 @@ namespace dags { * \return <层次,排序值> */ std::pair node_evaluate_with_downstream(std::shared_ptr node, const QList>& total_nodes); + std::pair node_evaluate_with_upstream(std::shared_ptr node, const QList>& total_nodes); }; } diff --git a/StoryPresent/dag_present.cpp b/StoryPresent/dag_present.cpp index 678dbf3..a88b1d1 100644 --- a/StoryPresent/dag_present.cpp +++ b/StoryPresent/dag_present.cpp @@ -314,6 +314,9 @@ void dags::DAGActiveView::refreshGraph() auto total_nodes = _layout_engine->nodeWithLayout(); total_graph_nodes = this->layer_nodes_construction(QHash>(), total_nodes); + + auto rect = this->scene()->itemsBoundingRect(); + this->scene()->setSceneRect(rect); } void DAGActiveView::mousePressEvent(QMouseEvent* ev) { diff --git a/StoryPresent/storypresent.cpp b/StoryPresent/storypresent.cpp index be48cc0..0e83064 100644 --- a/StoryPresent/storypresent.cpp +++ b/StoryPresent/storypresent.cpp @@ -18,9 +18,9 @@ StoryPresent::StoryPresent(QWidget* parent) view->addAction(u8"放大", this, &StoryPresent::bigger, Qt::CTRL + Qt::Key_P); auto layout = mbar->addMenu(u8"布局调整"); - layout->addAction(u8"正向布局", this, &StoryPresent::forwardLayout); - layout->addAction(u8"逆向布局", this, &StoryPresent::backwardLayout); - layout->addAction(u8"调整布局", this, &StoryPresent::adjustLayout); + layout->addAction(u8"正向布局", this, &StoryPresent::forwardLayout, Qt::CTRL + Qt::Key_F); + layout->addAction(u8"逆向布局", this, &StoryPresent::backwardLayout, Qt::CTRL + Qt::Key_B); + layout->addAction(u8"调整布局", this, &StoryPresent::adjustLayout, Qt::CTRL+Qt::Key_A); } StoryPresent::~StoryPresent()