diff --git a/StoryPresent/dag_layout.cpp b/StoryPresent/dag_layout.cpp index cc171e9..514445f 100644 --- a/StoryPresent/dag_layout.cpp +++ b/StoryPresent/dag_layout.cpp @@ -247,37 +247,36 @@ void DAGGraph::nodes_sort_forward_within_layer(int layer_index, const QList 0) { - QList> nodes_fixed; + double min_sortv = DBL_MAX; for (auto target_node : nodes_within_current_layer) { auto upstream_list = target_node->getUpstreamNodes(); - std::sort(upstream_list.begin(), upstream_list.end(), - [](std::shared_ptr a, std::shared_ptr b) { return a->sortNumber() < b->sortNumber(); }); - 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 sort_values; + std::transform(upstream_list.begin(), upstream_list.end(), std::back_inserter(sort_values), + [](std::shared_ptr ins) { return ins->sortNumber().toDouble(); }); + + auto vals_sum = std::accumulate(sort_values.begin(), sort_values.end(), 0.0); + target_node->setSortNumber(vals_sum / sort_values.size()); + min_sortv = std::min(target_node->sortNumber().toDouble(), min_sortv); } } 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(); - }); + 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(); }); - + auto vspan = 1.0 / (nodes_hangout.size() + 1); for (int idx = 0; idx < nodes_hangout.size(); ++idx) { - nodes_hangout[idx]->setSortNumber((*min_anchor)->sortNumber().toInt() - idx - 1); + nodes_hangout[idx]->setSortNumber(min_sortv - (idx + 1) * vspan); } } 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(); - }); + return a->sortNumber() < b->sortNumber(); + }); // 提取当前层次节点排序值 this->current_nodelist_filling_indi(nodes_within_current_layer); @@ -286,16 +285,20 @@ void DAGGraph::nodes_sort_forward_within_layer(int layer_index, const QList>& nodes_within_current_layer) { + // 提取节点划分档次 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(); - }); + return ins->sortNumber().toInt(); + }); ordered_values = ordered_values.toSet().toList(); std::sort(ordered_values.begin(), ordered_values.end()); - if (ordered_values.size() == nodes_within_current_layer.size()) + //if (ordered_values.size() == nodes_within_current_layer.size()) + // return false; + + if (!ordered_values.size()) return false; // 填缝 @@ -386,10 +389,10 @@ QList> dags::DAGGraph::layer_adjust_via_next_sib 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(); }); + 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(); }); @@ -402,30 +405,30 @@ void dags::DAGGraph::node_adjust_via_next_sibling(std::shared_ptr> next_layer_nodes; std::copy_if(total_nodes.begin(), total_nodes.end(), std::back_inserter(next_layer_nodes), [&](std::shared_ptr inst) { - if (inst->layerNumber() == curr_node->layerNumber() + 1) { - if (curr_node->isFakeNode()) { - if (inst->isFakeNode()) { - return curr_node->tailsNode() == inst->tailsNode() && curr_node->headsNode() == inst->headsNode(); - } - return curr_node->headsNode() == inst->layerNode(); + if (inst->layerNumber() == curr_node->layerNumber() + 1) { + if (curr_node->isFakeNode()) { + if (inst->isFakeNode()) { + return curr_node->tailsNode() == inst->tailsNode() && curr_node->headsNode() == inst->headsNode(); + } + return curr_node->headsNode() == inst->layerNode(); + } + else { + if (inst->isFakeNode()) { + return curr_node->layerNode() == inst->tailsNode(); } else { - if (inst->isFakeNode()) { - return curr_node->layerNode() == inst->tailsNode(); - } - else { - auto next_vnodes = curr_node->layerNode()->nextNodes(); - return next_vnodes.contains(inst->layerNode()); - } + auto next_vnodes = curr_node->layerNode()->nextNodes(); + return next_vnodes.contains(inst->layerNode()); } } - return false; - }); + } + return false; + }); std::sort(next_layer_nodes.begin(), next_layer_nodes.end(), [](std::shared_ptr a, std::shared_ptr b) { - return a->sortNumber() < b->sortNumber(); - }); + return a->sortNumber() < b->sortNumber(); + }); if (next_layer_nodes.size()) { curr_node->setSortNumber(next_layer_nodes.first()->sortNumber().toDouble()); @@ -461,205 +464,9 @@ void dags::DAGGraph::nodes_sort_with_belows(int curr_layer, const QList>& total_nodes) { - int layer_index = 0; - while (this->nodes_revise_forward_within_layer(layer_index, total_nodes)) { - this->node_adjust_inlayer_partition_indi(layer_index, total_nodes); - this->nodes_sort_with_above(layer_index, total_nodes); - layer_index++; - } -} - -bool dags::DAGGraph::nodes_revise_forward_within_layer(int layer_index, const QList>& total_nodes) { - if (layer_index) { - QList> nodes_within_previous_layer; - std::copy_if(total_nodes.begin(), total_nodes.end(), std::back_inserter(nodes_within_previous_layer), - [=](std::shared_ptr n) { return n->layerNumber() == layer_index - 1; }); - std::sort(nodes_within_previous_layer.begin(), nodes_within_previous_layer.end(), - [](std::shared_ptr a, std::shared_ptr b) { - return a->sortNumber() < b->sortNumber(); - }); - - QList> nodes_within_current_layer; - std::copy_if(total_nodes.begin(), total_nodes.end(), std::back_inserter(nodes_within_current_layer), - [=](std::shared_ptr n) { return n->layerNumber() == layer_index; }); - 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(); - }); - - //for (int idx = 0; idx < nodes_within_current_layer.size(); ++idx) { - // auto ns_remains = nodes_within_current_layer; - // auto ns_currs = nodes_within_current_layer - // // 调整测试 - // for(auto adj_idx=0; adj_idx>& prevs, const QList>& currs) { - return 0; -} - -bool dags::DAGGraph::node_adjust_inlayer_partition_indi(int layer_index, 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(inst, (*anchor_it)->sortNumber())); - } - - QList sort_backup; - std::transform(sort_helper.begin(), sort_helper.end(), std::back_inserter(sort_backup), - [](std::pair, QVariant> u) { return u.second; }); - - auto aligned_items_count = std::count_if(sort_backup.begin(), sort_backup.end(), [](QVariant u) { return !u.isNull(); }); - if (!aligned_items_count) - return false; - - // 补全布局系数 - 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; - } - } - 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); - } - } - - double sub_sum = 0; - // 计算修正系数 - for (auto ndx = 0; ndx < sort_backup.size(); ndx++) { - auto valbk = sort_backup[ndx]; - auto val2 = sort_helper[ndx].second; - if (!valbk.isNull()) { - sub_sum += val2.toDouble() - valbk.toDouble(); - } - } - auto val_revised = sub_sum / aligned_items_count; - std::for_each(sort_helper.begin(), sort_helper.end(), - [=](std::pair, QVariant> u) { - u.first->setSortNumber(u.second.toDouble() - val_revised); - }); - - this->current_nodelist_filling_indi(nodes_within_current_layer); - return true; -} - -/* -std::pair dags::DAGGraph::node_evaluate_with_downstream(std::shared_ptr curr_node, const QList>& total_nodes) -{ - decltype(curr_node) next_node; - if (curr_node->isFakeNode()) { - auto n_data = curr_node->headsNode(); - next_node = *std::find_if(total_nodes.begin(), total_nodes.end(), [&](decltype(curr_node) n) { - if (!n->isFakeNode()) { - return n->layerNode() == n_data; - } - return false; - }); - } - else { - auto n_datas = curr_node->layerNode()->nextNodes(); - if (!n_datas.size()) - return std::make_pair(curr_node->layerNumber(), curr_node->sortNumber().toLongLong()); - - QList> next_nodes; - std::transform(n_datas.begin(), n_datas.end(), std::back_inserter(next_nodes), - [&](std::shared_ptr inst) { - auto rst = std::find_if(total_nodes.begin(), total_nodes.end(), [&](decltype(curr_node) n) { - if (!n->isFakeNode()) { - return n->layerNode() == inst; - } - return false; - }); - return *rst; - }); - next_node = *std::min_element(next_nodes.begin(), next_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(next_node->layerNumber(), next_node->sortNumber().toLongLong()); -} - -std::pair dags::DAGGraph::node_evaluate_with_upstream(std::shared_ptr curr_node, const QList>& total_nodes) -{ - auto prim_nodes = curr_node->getUpstreamNodes(); - if (!prim_nodes.size()) - return std::make_pair(curr_node->layerNumber(), curr_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; @@ -696,7 +503,7 @@ void dags::DAGGraph::backwardsLayoutImpls() { } void dags::DAGGraph::adjustLayoutImpls() { - this->node_adjust_ingraph_forward(this->node_with_layout); + } diff --git a/StoryPresent/dag_layout.h b/StoryPresent/dag_layout.h index 45b304b..413a0fd 100644 --- a/StoryPresent/dag_layout.h +++ b/StoryPresent/dag_layout.h @@ -102,9 +102,6 @@ namespace dags { 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 nodes_revise_forward_within_layer(int layer_index, const QList>& nodes); - int forks_evaluate_with_sequence(const QList>& prevs, const QList>& currs); - bool node_adjust_inlayer_partition_indi(int layer_index, const QList>& total_nodes); + }; } diff --git a/StoryPresent/storypresent.cpp b/StoryPresent/storypresent.cpp index f2616b2..fb6beaf 100644 --- a/StoryPresent/storypresent.cpp +++ b/StoryPresent/storypresent.cpp @@ -20,7 +20,7 @@ StoryPresent::StoryPresent(QWidget* parent) auto layout = mbar->addMenu(u8"布局调整"); 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); + layout->addAction(u8"调整布局", this, &StoryPresent::adjustLayout, Qt::CTRL+Qt::Key_A); connect(_story_present, &DAGActiveView::nodeClicked, this, &StoryPresent::nodeClickAccept); } @@ -122,10 +122,14 @@ void StoryPresent::nodeClickAccept(const QPointF& pos, const QString& node_name) return; } - QList> parent_slices; - std::transform(refers.begin(), refers.end(), std::back_inserter(parent_slices), + QList> vparent_slices; + std::transform(refers.begin(), refers.end(), std::back_inserter(vparent_slices), [](std::shared_ptr ins) { return ins->parentSlice().lock(); }); + QList> parent_slices; + std::copy_if(vparent_slices.begin(), vparent_slices.end(), std::back_inserter(parent_slices), + [](std::shared_ptr ins) -> bool { return ins != nullptr; }); + decltype(parent_slices) fliter_slices; std::copy_if(parent_slices.begin(), parent_slices.end(), std::back_inserter(fliter_slices), [](std::shared_ptr ins) { return ins->type() == SliceType::StoryDefines; });