This commit is contained in:
codeboss 2024-10-10 21:40:39 +08:00
parent 829868be1c
commit 97cd475c7f
3 changed files with 101 additions and 286 deletions

View File

@ -264,8 +264,8 @@ void DAGGraph::nodes_sort_forward_within_layer(int layer_index, const QList<std:
QList<std::shared_ptr<DAGOrderHelper>> nodes_hangout;
std::copy_if(nodes_within_current_layer.begin(), nodes_within_current_layer.end(),
std::back_inserter(nodes_hangout), [](std::shared_ptr<DAGOrderHelper> 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<std:
std::sort(nodes_within_current_layer.begin(), nodes_within_current_layer.end(),
[](std::shared_ptr<DAGOrderHelper> a, std::shared_ptr<DAGOrderHelper> 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<std::shared_ptr<D
QList<int> ordered_values;
std::transform(nodes_within_current_layer.begin(), nodes_within_current_layer.end(),
std::back_inserter(ordered_values), [=](std::shared_ptr<DAGOrderHelper> 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<std::shared_ptr<DAGOrderHelper>> dags::DAGGraph::layer_adjust_via_next_sib
std::sort(curr_layer_nodes.begin(), curr_layer_nodes.end(),
[](std::shared_ptr<DAGOrderHelper>a, std::shared_ptr<DAGOrderHelper> 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<DAGOrderHelper> a, std::shared_ptr<DAGOrderHelper> b) { return a->sortNumber() < b->sortNumber(); });
auto upnode_b = std::min_element(prevs_b.begin(), prevs_b.end(),
[](std::shared_ptr<DAGOrderHelper> a, std::shared_ptr<DAGOrderHelper> b) { return a->sortNumber() < b->sortNumber(); });
auto upnode_a = std::min_element(prevs_a.begin(), prevs_a.end(),
[](std::shared_ptr<DAGOrderHelper> a, std::shared_ptr<DAGOrderHelper> b) { return a->sortNumber() < b->sortNumber(); });
auto upnode_b = std::min_element(prevs_b.begin(), prevs_b.end(),
[](std::shared_ptr<DAGOrderHelper> a, std::shared_ptr<DAGOrderHelper> 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<DAGOrderHelper
QList<std::shared_ptr<DAGOrderHelper>> next_layer_nodes;
std::copy_if(total_nodes.begin(), total_nodes.end(), std::back_inserter(next_layer_nodes),
[&](std::shared_ptr<DAGOrderHelper> 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<DAGOrderHelper> a, std::shared_ptr<DAGOrderHelper> 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<std::sha
}
}
void dags::DAGGraph::node_adjust_ingraph_forward(const QList<std::shared_ptr<DAGOrderHelper>>& 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<std::shared_ptr<DAGOrderHelper>>& total_nodes) {
// int layer_index = 0;
// QList<std::shared_ptr<DAGOrderHelper>> 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<std::shared_ptr<DAGOrderHelper>>& nodes) {
if (layer_index) {
QList<std::shared_ptr<DAGOrderHelper>> nodes_within_current_layer;
std::copy_if(nodes.begin(), nodes.end(), std::back_inserter(nodes_within_current_layer),
[=](std::shared_ptr<DAGOrderHelper> n) { return n->layerNumber() == layer_index; });
//QList<std::shared_ptr<DAGOrderHelper>> dags::DAGGraph::nodes_revise_forward_within_layer(int layer_index, const QList<std::shared_ptr<DAGOrderHelper>>& nodes) {
//
//
//
// QList<std::shared_ptr<DAGOrderHelper>> nodes_within_previous_layer;
// if (layer_index) {
// std::copy_if(nodes.begin(), nodes.end(), std::back_inserter(nodes_within_previous_layer),
// [=](std::shared_ptr<DAGOrderHelper> n) { return n->layerNumber() == layer_index - 1; });
// }
// QList<std::shared_ptr<DAGOrderHelper>> nodes_within_current_layer;
// std::copy_if(nodes.begin(), nodes.end(), std::back_inserter(nodes_within_current_layer),
// [=](std::shared_ptr<DAGOrderHelper> n) { return n->layerNumber() == layer_index; });
//
// if (nodes_within_current_layer.size()) {
// QList<std::tuple<std::shared_ptr<DAGOrderHelper>, 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<std::pair<int, int>> sort_arrows;
std::for_each(nodes_within_current_layer.begin(), nodes_within_current_layer.end(),
[&](std::shared_ptr<DAGOrderHelper> curr_node) {
auto prev_nodes = curr_node->getUpstreamNodes();
std::for_each(prev_nodes.begin(), prev_nodes.end(),
[&](std::shared_ptr<DAGOrderHelper> n) {
sort_arrows << std::make_pair(n->sortNumber().toInt(), curr_node->sortNumber().toInt());
});
});
//double dags::DAGGraph::node_revise_via_upstream(const QList<std::tuple<std::shared_ptr<DAGOrderHelper>, double>>& prev_nodes, std::shared_ptr<DAGOrderHelper> node) {
// auto upstream_nodes = node->getUpstreamNodes();
// QList<double> lev_rst;
// std::transform(upstream_nodes.begin(), upstream_nodes.end(),
// std::back_inserter(lev_rst), [&](std::shared_ptr<DAGOrderHelper> upn)->double {
// auto trans_it = std::find_if(prev_nodes.begin(), prev_nodes.end(),
// [&](std::tuple<std::shared_ptr<DAGOrderHelper>, 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<std::shared_ptr<DAGOrderHelper>>& total_nodes)
{
// 挑选当前层次节点
QList<std::shared_ptr<DAGOrderHelper>> curr_layer_nodes;
std::copy_if(total_nodes.begin(), total_nodes.end(), std::back_inserter(curr_layer_nodes),
[&](std::shared_ptr<DAGOrderHelper> inst) { return inst->layerNumber() == curr_layer; });
if (!curr_layer_nodes.size())
return false;
// 计算排序系数
QList<std::tuple<std::shared_ptr<DAGOrderHelper>, qlonglong, qlonglong, qlonglong, qlonglong>> orders_helper;
std::transform(curr_layer_nodes.begin(), curr_layer_nodes.end(), std::back_inserter(orders_helper),
[&](std::shared_ptr<DAGOrderHelper> 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<std::shared_ptr<DAGOrderHelper>, qlonglong, qlonglong, qlonglong, qlonglong> a,
std::tuple<std::shared_ptr<DAGOrderHelper>, 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<int> sort_values;
std::transform(curr_layer_nodes.begin(), curr_layer_nodes.end(), std::back_inserter(sort_values),
[](std::shared_ptr<DAGOrderHelper> 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<std::shared_ptr<DAGOrderHelper>>& total_nodes) {
// 提取层次节点并排序节点
QList<std::shared_ptr<DAGOrderHelper>> nodes_within_current_layer;
std::copy_if(total_nodes.begin(), total_nodes.end(), std::back_inserter(nodes_within_current_layer),
[=](std::shared_ptr<DAGOrderHelper> inst) {
return layer_index == inst->layerNumber();
});
std::sort(nodes_within_current_layer.begin(), nodes_within_current_layer.end(),
[](std::shared_ptr<DAGOrderHelper> a, std::shared_ptr<DAGOrderHelper> b) {
return a->sortNumber() < b->sortNumber();
});
if (!nodes_within_current_layer.size())
return false;
// 获取布局系数
QList<std::pair<std::shared_ptr<DAGOrderHelper>, 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<DAGOrderHelper> a, std::shared_ptr<DAGOrderHelper> b) {
return a->layerNumber() < b->layerNumber();
});
sort_helper.append(std::make_pair(inst, (*anchor_it)->sortNumber()));
}
QList<QVariant> sort_backup;
std::transform(sort_helper.begin(), sort_helper.end(), std::back_inserter(sort_backup),
[](std::pair<std::shared_ptr<DAGOrderHelper>, 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<std::shared_ptr<DAGOrderHelper>, QVariant> u) {
u.first->setSortNumber(u.second.toDouble() - val_revised);
});
this->current_nodelist_filling_indi(nodes_within_current_layer);
return true;
}
/*
std::pair<qlonglong, qlonglong> dags::DAGGraph::node_evaluate_with_downstream(std::shared_ptr<DAGOrderHelper> curr_node, const QList<std::shared_ptr<DAGOrderHelper>>& 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<std::shared_ptr<DAGOrderHelper>> next_nodes;
std::transform(n_datas.begin(), n_datas.end(), std::back_inserter(next_nodes),
[&](std::shared_ptr<DAGLayerHelper> 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<DAGOrderHelper> a, std::shared_ptr<DAGOrderHelper> 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<qlonglong, qlonglong> dags::DAGGraph::node_evaluate_with_upstream(std::shared_ptr<DAGOrderHelper> curr_node, const QList<std::shared_ptr<DAGOrderHelper>>& total_nodes)
{
auto prim_nodes = curr_node->getUpstreamNodes();
if (!prim_nodes.size())
return std::make_pair(curr_node->layerNumber(), curr_node->sortNumber().toLongLong());
QList<std::shared_ptr<DAGOrderHelper>> prev_nodes;
std::transform(prim_nodes.begin(), prim_nodes.end(), std::back_inserter(prev_nodes),
[&](std::shared_ptr<DAGOrderHelper> 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<DAGOrderHelper> 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<DAGOrderHelper> a, std::shared_ptr<DAGOrderHelper> 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<std::shared_ptr<DAGLayerHelper>> sort_seqs;
QList<std::shared_ptr<DAGLayerHelper>> 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);
}

View File

@ -102,9 +102,10 @@ namespace dags {
void nodes_sort_with_above(int curr_layer, const QList<std::shared_ptr<DAGOrderHelper>>& total_nodes);
void nodes_sort_with_belows(int curr_layer, const QList<std::shared_ptr<DAGOrderHelper>>& total_nodes);
void node_adjust_ingraph_forward(const QList<std::shared_ptr<DAGOrderHelper>>& total_nodes);
bool nodes_revise_forward_within_layer(int layer_index, const QList<std::shared_ptr<DAGOrderHelper>>& nodes);
bool node_adjust_inlayer_partition_indi(int layer_index, const QList<std::shared_ptr<DAGOrderHelper>>& total_nodes);
//void graph_springs_layout_forward(const QList<std::shared_ptr<DAGOrderHelper>>& total_nodes);
//QList<std::shared_ptr<DAGOrderHelper>> nodes_revise_forward_within_layer(int layer_index, const QList<std::shared_ptr<DAGOrderHelper>>& nodes);
//double node_revise_via_upstream(const QList<std::tuple<std::shared_ptr<DAGOrderHelper>, double>>& prev_nodes, std::shared_ptr<DAGOrderHelper> node);
//bool current_nodelist_filling_springs(const QList<std::shared_ptr<DAGOrderHelper>>& ordered_nodes);
//bool node_adjust_inlayer_forward(int curr_layer, const QList<std::shared_ptr<DAGOrderHelper>>& total_nodes);

View File

@ -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);
}