From 72675e0519982a2ba22493faecb218981f40f95f Mon Sep 17 00:00:00 2001 From: codeboss <2422523675@qq.com> Date: Sat, 5 Oct 2024 21:15:07 +0800 Subject: [PATCH] 1 --- StoryPresent/dag_layout.cpp | 193 ++++++++++++++++++++++++----------- StoryPresent/dag_layout.h | 15 +-- StoryPresent/dag_present.cpp | 4 +- 3 files changed, 145 insertions(+), 67 deletions(-) diff --git a/StoryPresent/dag_layout.cpp b/StoryPresent/dag_layout.cpp index fa30579..69d94bb 100644 --- a/StoryPresent/dag_layout.cpp +++ b/StoryPresent/dag_layout.cpp @@ -65,7 +65,7 @@ void dags::DAGOrderHelper::setLayerNumber(int v) { this->layer_number = v; } -double dags::DAGOrderHelper::sortNumber() const { +QVariant dags::DAGOrderHelper::sortNumber() const { return this->sort_number; } @@ -230,35 +230,47 @@ QList> DAGGraph::tidy_graph_nodes() { #include void DAGGraph::graph_layer_nodes_sort_forward(int layer_index, const QList>& nodes) { QList> nodes_within_current_layer; - for (auto n : nodes) - if (n->layerNumber() == layer_index) { - nodes_within_current_layer.append(n); - } + std::copy_if(nodes.begin(), nodes.end(), std::back_inserter(nodes_within_current_layer), + [=](std::shared_ptr ins) { return ins->layerNumber() == layer_index; }); if (nodes_within_current_layer.size()) { // 计算当前层次所有节点排序 if (!layer_index) { for (auto idx = 0; idx < nodes_within_current_layer.size(); ++idx) { - nodes_within_current_layer[idx]->setSortNumber(idx + 1); + auto target_node = nodes_within_current_layer[idx]; + if(target_node->sortNumber().isNull()) + target_node->setSortNumber(idx + 1); } } else if (layer_index > 0) { + QList> nodes_fixed; for (auto target_node : nodes_within_current_layer) { - QList prev_sorts; auto upstream_list = target_node->getUpstreamNodes(); - std::transform(upstream_list.begin(), upstream_list.end(), - std::back_inserter(prev_sorts), [](std::shared_ptr inst) { - return inst->sortNumber(); - }); + std::sort(upstream_list.begin(), upstream_list.end(), + [](std::shared_ptr a, std::shared_ptr b) { return a->sortNumber() < b->sortNumber(); }); - if (prev_sorts.size()) { - auto target_sum = std::accumulate(prev_sorts.begin(), prev_sorts.end(), 0.0); - target_node->setSortNumber(target_sum / prev_sorts.size()); + if (upstream_list.size()) { + auto sort_anchor = upstream_list[(upstream_list.size() - 1) / 2]; + target_node->setSortNumber(sort_anchor->sortNumber().toInt()); + nodes_fixed << sort_anchor; + } + } + + QList> nodes_hangout; + std::copy_if(nodes_within_current_layer.begin(), nodes_within_current_layer.end(), + std::back_inserter(nodes_hangout), [](std::shared_ptr ins) { + return ins->sortNumber().isNull(); + }); + if(nodes_hangout.size()){ + auto min_anchor = std::min_element(nodes_fixed.begin(), nodes_fixed.end(), + [](std::shared_ptr a, std::shared_ptr b) { return a->sortNumber() < b->sortNumber(); }); + + for (int idx = 0; idx < nodes_hangout.size(); ++idx) { + nodes_hangout[idx]->setSortNumber((*min_anchor)->sortNumber().toInt() - idx - 1); } } // 提取当前层次节点排序值 - //this->current_nodelist_separate(nodes_within_current_layer); this->current_nodelist_filling(layer_index, nodes); } @@ -268,19 +280,108 @@ void DAGGraph::graph_layer_nodes_sort_forward(int layer_index, const QList>& nodes) +{ + // 提取本层次节点 + QList> nodes_within_current_layer; + std::copy_if(nodes.begin(), nodes.end(), std::back_inserter(nodes_within_current_layer), + [=](std::shared_ptr ins) { return ins->layerNumber() == layer_index; }); + if(!nodes_within_current_layer.size()) + return; + + + std::sort(nodes_within_current_layer.begin(), nodes_within_current_layer.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(); + }); + + // 提取节点划分档次 + QList ordered_values; + std::transform(nodes_within_current_layer.begin(), nodes_within_current_layer.end(), + std::back_inserter(ordered_values), [=](std::shared_ptr ins) { + return ins->sortNumber().toInt(); + }); + ordered_values = ordered_values.toSet().toList(); + std::sort(ordered_values.begin(), ordered_values.end()); + + // 填缝 + ordered_values << ordered_values.last() + 1; + for (auto idx = 1; idx < ordered_values.size(); ++idx) { + auto prev_sortv = ordered_values[idx - 1]; + auto curr_sortv = ordered_values[idx]; + + QList> pick_ups; + std::copy_if(nodes_within_current_layer.begin(), nodes_within_current_layer.end(), std::back_inserter(pick_ups), + [=](std::shared_ptr ins) { return ins->sortNumber() >= prev_sortv && ins->sortNumber() < curr_sortv; }); + + for (int idx = 0; idx < std::min(curr_sortv - prev_sortv, pick_ups.size()); idx++) { + auto target_node = pick_ups[idx]; + target_node->setSortNumber(prev_sortv + idx); + } + if (curr_sortv - prev_sortv < pick_ups.size()) { + auto npicks = pick_ups.mid(curr_sortv - prev_sortv); + auto inc_span = 1.0 / (npicks.size() + 4); + + for (auto idx = 0; idx < npicks.size(); ++idx) { + auto nsortv = curr_sortv - 1 + (idx + 1) * inc_span; + npicks[idx]->setSortNumber(nsortv); + } + } + } +} + +void dags::DAGGraph::nodes_sort_with_above(int layer_index, const QList>& nodes) +{ + // 提取所有已知节点 + QList> sorting_nodes; + std::copy_if(nodes.begin(), nodes.end(), std::back_inserter(sorting_nodes), + [&](std::shared_ptr n) { return n->layerNumber() <= layer_index; }); + + // 排序值提取与重排 + QList sort_values; + std::transform(sorting_nodes.begin(), sorting_nodes.end(), std::back_inserter(sort_values), + [](std::shared_ptr n)->double { return n->sortNumber().toDouble(); }); + sort_values = sort_values.toSet().toList(); + std::sort(sort_values.begin(), sort_values.end()); + + // 检索排序中轴 + auto temp_anchor = std::make_pair(DBL_MAX, -1); + for (int nidx = 0; nidx < sort_values.size(); ++nidx) { + auto value_span = std::abs(sort_values[nidx]); + if (value_span <= temp_anchor.first) + temp_anchor = std::make_pair(value_span, nidx); + } + + // 排序值重整 + for (int sorting_idx = 0; sorting_idx < sorting_nodes.size(); ++sorting_idx) { + auto node = sorting_nodes[sorting_idx]; + auto node_sortv = node->sortNumber().toDouble(); + auto sort_idx = sort_values.indexOf(node_sortv); + node->setSortNumber(sort_idx - temp_anchor.second); + } +} +/* +void dags::DAGGraph::current_nodelist_filling_backward(int layer_index, const QList>& nodes) { // 提取既有排序成果 QList> ordered_node; std::copy_if(nodes.begin(), nodes.end(), std::back_inserter(ordered_node), [=](std::shared_ptr ins) { - if (!ins->isFakeNode() && ins->layerNumber() < layer_index) { - auto next_nodes = ins->layerNode()->nextNodes(); - for (auto nd : next_nodes) { - if (nd->layerValue() >= layer_index) - return true; - } - } - return false; + return !ins->isFakeNode() && ins->layerNumber() > layer_index; }); QList ordered_values; std::transform(ordered_node.begin(), ordered_node.end(), std::back_inserter(ordered_values), @@ -327,36 +428,6 @@ void dags::DAGGraph::current_nodelist_filling(int layer_index, const QList>& nodes) -{ - // 提取所有已知节点 - QList> sorting_nodes; - std::copy_if(nodes.begin(), nodes.end(), std::back_inserter(sorting_nodes), - [&](std::shared_ptr n) { return n->layerNumber() <= layer_index; }); - - // 排序值提取与重排 - QList sort_values; - std::transform(sorting_nodes.begin(), sorting_nodes.end(), std::back_inserter(sort_values), - [](std::shared_ptr n)->double { return n->sortNumber(); }); - sort_values = sort_values.toSet().toList(); - std::sort(sort_values.begin(), sort_values.end()); - - // 检索排序中轴 - auto temp_anchor = std::make_pair(DBL_MAX, -1); - for (int nidx = 0; nidx < sort_values.size(); ++nidx) { - auto value_span = std::abs(sort_values[nidx]); - if (value_span <= temp_anchor.first) - temp_anchor = std::make_pair(value_span, nidx); - } - - // 排序值重整 - for (int sorting_idx = 0; sorting_idx < sorting_nodes.size(); ++sorting_idx) { - auto node = sorting_nodes[sorting_idx]; - auto sort_idx = sort_values.indexOf(node->sortNumber()); - node->setSortNumber(sort_idx - temp_anchor.second); - } -} - void dags::DAGGraph::current_nodelist_separate(const QList>& nodes_within_current_layer) { QList sort_values; @@ -406,13 +477,13 @@ void dags::DAGGraph::current_layer_separate(int layer_index, const QListcurrent_nodelist_separate(nodes_within_current_layer); } - +*/ 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); - this->current_layer_separate(layer_index, total_nodes); + this->current_nodelist_filling(layer_index, total_nodes); this->nodes_sort_with_belows(layer_index, total_nodes); layer_index--; }; @@ -540,7 +611,7 @@ void dags::DAGGraph::node_adjust_via_next_sibling(std::shared_ptrsetSortNumber(next_layer_nodes.first()->sortNumber()); + curr_node->setSortNumber(next_layer_nodes.first()->sortNumber().toDouble()); } } @@ -554,7 +625,7 @@ void dags::DAGGraph::nodes_sort_with_belows(int curr_layer, const QList sort_values; std::transform(sorting_nodes.begin(), sorting_nodes.end(), std::back_inserter(sort_values), - [](std::shared_ptr n)->double { return n->sortNumber(); }); + [](std::shared_ptr n)->double { return n->sortNumber().toDouble(); }); sort_values = sort_values.toSet().toList(); std::sort(sort_values.begin(), sort_values.end()); @@ -569,7 +640,7 @@ void dags::DAGGraph::nodes_sort_with_belows(int curr_layer, const QListsortNumber()); + auto sort_idx = sort_values.indexOf(node->sortNumber().toDouble()); node->setSortNumber(sort_idx - temp_anchor.second); } } @@ -601,7 +672,11 @@ void dags::DAGGraph::graphLayout() { this->graph_layer_nodes_sort_forward(0, tidy_nodes); this->node_with_layout = tidy_nodes; - this->graph_adjust_after_layout(tidy_nodes); + int times = 2; + while(times--){ + this->graph_adjust_after_layout(tidy_nodes); + this->graph_layer_nodes_sort_forward(0, tidy_nodes); + } } diff --git a/StoryPresent/dag_layout.h b/StoryPresent/dag_layout.h index 53d6da6..f8769d1 100644 --- a/StoryPresent/dag_layout.h +++ b/StoryPresent/dag_layout.h @@ -35,7 +35,7 @@ namespace dags { std::shared_ptr relate_bind = nullptr; std::shared_ptr towards_to = nullptr; int layer_number = 0; - double sort_number = 0; + QVariant sort_number; QList> __prev_layer_nodes; public: @@ -60,7 +60,7 @@ namespace dags { int layerNumber() const; void setLayerNumber(int v); - double sortNumber() const; + QVariant sortNumber() const; void setSortNumber(double v); QList> getUpstreamNodes() const; @@ -77,6 +77,7 @@ namespace dags { public: void rebuildFromEdges(const QList& arrow_list); void graphLayout(); + QList> nodeWithLayout() const; int maxLayerCount() const; @@ -88,11 +89,10 @@ namespace dags { QList> tidy_graph_nodes(); void graph_layer_nodes_sort_forward(int layer_index, const QList> &nodes); - void current_nodelist_filling(int curr_layer, const QList>& total_nodes); - void nodes_sort_with_above(int curr_layer, const QList>& total_nodes); - void current_nodelist_separate(const QList>& total_nodes); - void current_layer_separate(int layer_index, const QList>& nodes); + //void current_nodelist_filling_backward(int curr_layer, const QList>& total_nodes); + //void current_nodelist_separate(const QList>& total_nodes); + //void current_layer_separate(int layer_index, const QList>& nodes); void graph_adjust_after_layout(const QList>& total_nodes); //bool layer_adjust_after_layout(int curr_layer, const QList>& total_nodes); @@ -100,6 +100,9 @@ namespace dags { bool 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); + + void current_nodelist_filling(int curr_layer, const QList>& total_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); }; } diff --git a/StoryPresent/dag_present.cpp b/StoryPresent/dag_present.cpp index c642e21..066de36 100644 --- a/StoryPresent/dag_present.cpp +++ b/StoryPresent/dag_present.cpp @@ -177,7 +177,7 @@ QList DAGActiveView::layer_nodes_construction(const QHashheadsNode()->bindPoint().name(); auto curr_gnode = new PenetrateNode(20, from, to); this->scene_bind.addItem(curr_gnode); - curr_gnode->setPos(prev_layer_end, data_node->sortNumber() * (this->node_span + this->font().pointSizeF()) * 7); + curr_gnode->setPos(prev_layer_end, data_node->sortNumber().toDouble() * (this->node_span + this->font().pointSizeF()) * 7); current_nodes_helper[curr_gnode] = data_node; } @@ -188,7 +188,7 @@ QList DAGActiveView::layer_nodes_construction(const QHashlayerNode()->bindPoint().name(), node_type_vx, this->font()); this->scene_bind.addItem(curr_gnode); - curr_gnode->setPos(prev_layer_end, data_node->sortNumber() * (this->node_span + this->font().pointSizeF()) * 7); + curr_gnode->setPos(prev_layer_end, data_node->sortNumber().toDouble() * (this->node_span + this->font().pointSizeF()) * 7); current_nodes_helper[curr_gnode] = data_node; }