diff --git a/StoryPresent/dag_layout.cpp b/StoryPresent/dag_layout.cpp index b5208e0..5e03a29 100644 --- a/StoryPresent/dag_layout.cpp +++ b/StoryPresent/dag_layout.cpp @@ -264,8 +264,8 @@ void DAGGraph::nodes_sort_forward_within_layer(int layer_index, const 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 vspan = 1.0 / (nodes_hangout.size() + 1); for (int idx = 0; idx < nodes_hangout.size(); ++idx) { @@ -275,8 +275,8 @@ void DAGGraph::nodes_sort_forward_within_layer(int layer_index, const QList a, std::shared_ptr b) { - return a->sortNumber() < b->sortNumber(); - }); + return a->sortNumber() < b->sortNumber(); + }); // 提取当前层次节点排序值 this->current_nodelist_filling_indi(nodes_within_current_layer); @@ -290,8 +290,8 @@ bool dags::DAGGraph::current_nodelist_filling_indi(const 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()); @@ -379,23 +379,23 @@ QList> dags::DAGGraph::layer_adjust_via_next_sib 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(); + 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; + 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(); }); + 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 (*upnode_a)->sortNumber() < (*upnode_b)->sortNumber(); + }); return curr_layer_nodes; } @@ -405,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()); @@ -464,253 +464,67 @@ 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++; - } -} +//void dags::DAGGraph::graph_springs_layout_forward(const QList>& total_nodes) { +// int layer_index = 0; +// QList> nodes; +// while ((nodes = this->nodes_revise_forward_within_layer(layer_index, total_nodes)).size()) { +// current_nodelist_filling_springs(nodes); +// nodes_sort_with_above(layer_index, total_nodes); +// layer_index++; +// } +//} -bool dags::DAGGraph::nodes_revise_forward_within_layer(int layer_index, const QList>& nodes) { - if (layer_index) { - QList> nodes_within_current_layer; - std::copy_if(nodes.begin(), nodes.end(), std::back_inserter(nodes_within_current_layer), - [=](std::shared_ptr n) { return n->layerNumber() == layer_index; }); +//QList> dags::DAGGraph::nodes_revise_forward_within_layer(int layer_index, const QList>& nodes) { +// +// +// +// QList> nodes_within_previous_layer; +// if (layer_index) { +// std::copy_if(nodes.begin(), nodes.end(), std::back_inserter(nodes_within_previous_layer), +// [=](std::shared_ptr n) { return n->layerNumber() == layer_index - 1; }); +// } +// QList> nodes_within_current_layer; +// std::copy_if(nodes.begin(), nodes.end(), std::back_inserter(nodes_within_current_layer), +// [=](std::shared_ptr n) { return n->layerNumber() == layer_index; }); +// +// if (nodes_within_current_layer.size()) { +// QList, int>> items_forwards; +// for (auto node : nodes_within_current_layer) { +// auto forwards = node_revise_via_upstream(nodes_within_previous_layer, node); +// items_forwards.append(std::make_tuple(node, forwards)); +// } +// +// for (auto idx = 0; idx < items_forwards.size(); ++idx) { +// auto curr_item = items_forwards[idx]; +// if (std::get<1>(curr_item) > 2) { +// auto node = std::get<0>(curr_item); +// node->setSortNumber(node->sortNumber().toInt() + std::get<1>(curr_item)); +// } +// } +// } +// +// return nodes_within_current_layer; +//} - QList> sort_arrows; - std::for_each(nodes_within_current_layer.begin(), nodes_within_current_layer.end(), - [&](std::shared_ptr curr_node) { - auto prev_nodes = curr_node->getUpstreamNodes(); - std::for_each(prev_nodes.begin(), prev_nodes.end(), - [&](std::shared_ptr n) { - sort_arrows << std::make_pair(n->sortNumber().toInt(), curr_node->sortNumber().toInt()); - }); - }); +//double dags::DAGGraph::node_revise_via_upstream(const QList, double>>& prev_nodes, std::shared_ptr node) { +// auto upstream_nodes = node->getUpstreamNodes(); +// QList lev_rst; +// std::transform(upstream_nodes.begin(), upstream_nodes.end(), +// std::back_inserter(lev_rst), [&](std::shared_ptr upn)->double { +// auto trans_it = std::find_if(prev_nodes.begin(), prev_nodes.end(), +// [&](std::tuple, double> ins) { +// return upn == std::get<0>(ins); +// }); +// if (trans_it != prev_nodes.end()) { +// auto trans_val = (std::get<1>(*trans_it) / std::get<0>(*trans_it)->layerNode()->nextNodes().size()); +// return upn->sortNumber().toDouble() - node->sortNumber().toDouble() + trans_val; +// } +// return upn->sortNumber().toDouble() - node->sortNumber().toDouble(); +// }); +// +// return std::accumulate(lev_rst.begin(), lev_rst.end(), 0.0); +//} - - } - return true; -} - -/* -bool dags::DAGGraph::node_adjust_inlayer_forward(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), - [&](std::shared_ptr inst) { return inst->layerNumber() == curr_layer; }); - - if (!curr_layer_nodes.size()) - return false; - - // 计算排序系数 - 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_p = this->node_evaluate_with_upstream(ins, total_nodes); - auto val_n = this->node_evaluate_with_downstream(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, qlonglong, qlonglong> a, - std::tuple, qlonglong, qlonglong, qlonglong, qlonglong> b) - { - auto prev_nodesa = std::get<0>(a)->getUpstreamNodes(); - auto prev_nodesb = std::get<0>(b)->getUpstreamNodes(); - if (!prev_nodesa.size() && !prev_nodesb.size()) - return a < b; - - if (prev_nodesa.size() && prev_nodesb.size()) { - if (std::get<3>(a) == std::get<3>(b)) { - if (std::get<4>(a) == std::get<4>(b)) { - if (std::get<1>(a) == std::get<1>(b)) { - return std::get<2>(a) < std::get<2>(b); - } - return std::get<1>(a) < std::get<1>(b); - } - return std::get<4>(a) < std::get<4>(b); - } - return std::get<3>(a) < std::get<3>(b); - } - - if (prev_nodesa.size()) { - return false; - } - return true; - }); - - QList sort_values; - std::transform(curr_layer_nodes.begin(), curr_layer_nodes.end(), std::back_inserter(sort_values), - [](std::shared_ptr ins) { return ins->sortNumber().toInt(); }); - std::sort(sort_values.begin(), sort_values.end()); - - // 重新设定节点次序 - for (auto idx = 0; idx < sort_values.size(); ++idx) { - std::get<0>(orders_helper[idx])->setSortNumber(sort_values[idx]); - } - - return true; -} -*/ -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; @@ -747,7 +561,7 @@ void dags::DAGGraph::backwardsLayoutImpls() { } void dags::DAGGraph::adjustLayoutImpls() { - //this->node_adjust_ingraph_forward(this->node_with_layout); + //this->graph_springs_layout_forward(this->node_with_layout); } diff --git a/StoryPresent/dag_layout.h b/StoryPresent/dag_layout.h index ec9c9a4..c4345ef 100644 --- a/StoryPresent/dag_layout.h +++ b/StoryPresent/dag_layout.h @@ -102,9 +102,10 @@ 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); - bool node_adjust_inlayer_partition_indi(int layer_index, const QList>& total_nodes); + //void graph_springs_layout_forward(const QList>& total_nodes); + //QList> nodes_revise_forward_within_layer(int layer_index, const QList>& nodes); + //double node_revise_via_upstream(const QList, double>>& prev_nodes, std::shared_ptr node); + //bool current_nodelist_filling_springs(const QList>& ordered_nodes); //bool node_adjust_inlayer_forward(int curr_layer, const QList>& total_nodes); diff --git a/StoryPresent/storypresent.cpp b/StoryPresent/storypresent.cpp index 7dccb43..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); }