Compare commits

..

8 Commits

Author SHA1 Message Date
codeboss e1ddd85af5 1 2024-10-06 08:32:04 +08:00
codeboss 72675e0519 1 2024-10-05 21:15:07 +08:00
codeboss 6906c2fe10 1 2024-10-05 17:20:41 +08:00
codeboss 207bdf845c 1 2024-10-05 10:57:49 +08:00
codeboss b24507a479 1 2024-10-05 10:26:07 +08:00
codeboss 0ba87a2d70 1 2024-10-05 10:19:24 +08:00
codeboss 436e88a708 1 2024-10-05 10:11:42 +08:00
codeboss 4a23bc826d 1 2024-10-04 20:12:19 +08:00
11 changed files with 358 additions and 93 deletions

View File

@ -114,7 +114,7 @@
<ClCompile Include="dag_present.cpp" /> <ClCompile Include="dag_present.cpp" />
<ClCompile Include="data_type.cpp" /> <ClCompile Include="data_type.cpp" />
<ClCompile Include="storyline_compare.cpp" /> <ClCompile Include="storyline_compare.cpp" />
<ClCompile Include="view_present.cpp" /> <ClCompile Include="cmp_present.cpp" />
<ClCompile Include="xast_parse.cpp" /> <ClCompile Include="xast_parse.cpp" />
<QtRcc Include="storypresent.qrc" /> <QtRcc Include="storypresent.qrc" />
<QtMoc Include="storypresent.h" /> <QtMoc Include="storypresent.h" />
@ -126,7 +126,7 @@
<QtMoc Include="dag_present.h" /> <QtMoc Include="dag_present.h" />
<ClInclude Include="data_type.h" /> <ClInclude Include="data_type.h" />
<ClInclude Include="storyline_compare.h" /> <ClInclude Include="storyline_compare.h" />
<ClInclude Include="view_present.h" /> <ClInclude Include="cmp_present.h" />
<ClInclude Include="xast_parse.h" /> <ClInclude Include="xast_parse.h" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@ -49,7 +49,7 @@
<ClCompile Include="dag_present.cpp"> <ClCompile Include="dag_present.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="view_present.cpp"> <ClCompile Include="cmp_present.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="storyline_compare.cpp"> <ClCompile Include="storyline_compare.cpp">
@ -66,7 +66,7 @@
<ClInclude Include="data_type.h"> <ClInclude Include="data_type.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="view_present.h"> <ClInclude Include="cmp_present.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="storyline_compare.h"> <ClInclude Include="storyline_compare.h">

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerCommandArguments>--test</LocalDebuggerCommandArguments> <LocalDebuggerCommandArguments>--graph dag --path E:/storyline.xast</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

View File

@ -1,4 +1,4 @@
#include "view_present.h" #include "cmp_present.h"
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QSplitter> #include <QSplitter>

View File

@ -49,11 +49,11 @@ std::shared_ptr<DAGLayerHelper> dags::DAGOrderHelper::layerNode() const {
return this->layer_bind; return this->layer_bind;
} }
std::shared_ptr<DAGLayerHelper> dags::DAGOrderHelper::relateNode() const { std::shared_ptr<DAGLayerHelper> dags::DAGOrderHelper::tailsNode() const {
return this->relate_bind; return this->relate_bind;
} }
std::shared_ptr<DAGLayerHelper> dags::DAGOrderHelper::towardsNode() const { std::shared_ptr<DAGLayerHelper> dags::DAGOrderHelper::headsNode() const {
return this->towards_to; return this->towards_to;
} }
@ -65,7 +65,7 @@ void dags::DAGOrderHelper::setLayerNumber(int v) {
this->layer_number = v; this->layer_number = v;
} }
double dags::DAGOrderHelper::sortNumber() const { QVariant dags::DAGOrderHelper::sortNumber() const {
return this->sort_number; return this->sort_number;
} }
@ -153,7 +153,7 @@ std::shared_ptr<DAGLayerHelper> DAGGraph::spawns_peak(QList<std::shared_ptr<DAGL
return std::shared_ptr<DAGLayerHelper>(); return std::shared_ptr<DAGLayerHelper>();
} }
void DAGGraph::graph_recovery(QList<std::shared_ptr<DAGLayerHelper>> sort_seqs) { void DAGGraph::graph_recovery(const QList<std::shared_ptr<DAGLayerHelper>>& sort_seqs) {
for (auto it : sort_seqs) { for (auto it : sort_seqs) {
it->inputCount() = 0; it->inputCount() = 0;
} }
@ -170,7 +170,7 @@ void DAGGraph::graph_recovery(QList<std::shared_ptr<DAGLayerHelper>> sort_seqs)
} }
} }
int DAGGraph::node_layering(std::shared_ptr<DAGLayerHelper> inst, int layer_current) { int DAGGraph::node_layering(const std::shared_ptr<DAGLayerHelper>& inst, int layer_current) {
auto max_remains = layer_current; auto max_remains = layer_current;
if (!layer_current || inst->layerValue() < layer_current) { if (!layer_current || inst->layerValue() < layer_current) {
inst->setLayerValue(layer_current); inst->setLayerValue(layer_current);
@ -227,75 +227,244 @@ QList<std::shared_ptr<DAGOrderHelper>> DAGGraph::tidy_graph_nodes() {
return temp_array; return temp_array;
} }
void DAGGraph::graph_layer_nodes_sort(int layer_index, QList<std::shared_ptr<DAGOrderHelper>> nodes) { #include <QDebug>
void DAGGraph::graph_layer_nodes_sort_forward(int layer_index, const QList<std::shared_ptr<DAGOrderHelper>>& nodes) {
QList<std::shared_ptr<DAGOrderHelper>> nodes_within_current_layer; QList<std::shared_ptr<DAGOrderHelper>> nodes_within_current_layer;
for (auto n : nodes) std::copy_if(nodes.begin(), nodes.end(), std::back_inserter(nodes_within_current_layer),
if (n->layerNumber() == layer_index) { [=](std::shared_ptr<DAGOrderHelper> ins) { return ins->layerNumber() == layer_index; });
nodes_within_current_layer.append(n);
}
if (nodes_within_current_layer.size()) { if (nodes_within_current_layer.size()) {
// 计算当前层次所有节点排序 // 计算当前层次所有节点排序
if (!layer_index) { if (!layer_index) {
for (auto idx = 0; idx < nodes_within_current_layer.size(); ++idx) { 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) { else if (layer_index > 0) {
QList<std::shared_ptr<DAGOrderHelper>> nodes_fixed;
for (auto target_node : nodes_within_current_layer) { for (auto target_node : nodes_within_current_layer) {
QList<double> prev_sorts;
auto upstream_list = target_node->getUpstreamNodes(); auto upstream_list = target_node->getUpstreamNodes();
std::transform(upstream_list.begin(), upstream_list.end(), std::sort(upstream_list.begin(), upstream_list.end(),
std::back_inserter(prev_sorts), [](std::shared_ptr<DAGOrderHelper> inst) { [](std::shared_ptr<DAGOrderHelper> a, std::shared_ptr<DAGOrderHelper> b) { return a->sortNumber() < b->sortNumber(); });
return inst->sortNumber();
});
if (prev_sorts.size()) { if (upstream_list.size()) {
auto target_sum = std::accumulate(prev_sorts.begin(), prev_sorts.end(), 0.0); auto sort_anchor = upstream_list[(upstream_list.size() - 1) / 2];
target_node->setSortNumber(target_sum / prev_sorts.size()); target_node->setSortNumber(sort_anchor->sortNumber().toInt());
nodes_fixed << sort_anchor;
} }
} }
// 当前层次节点排序值修正 QList<std::shared_ptr<DAGOrderHelper>> nodes_hangout;
std::sort(nodes_within_current_layer.begin(), nodes_within_current_layer.end(), std::copy_if(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(); }); std::back_inserter(nodes_hangout), [](std::shared_ptr<DAGOrderHelper> ins) {
return ins->sortNumber().isNull();
});
if (nodes_hangout.size()) {
auto min_anchor = std::min_element(nodes_fixed.begin(), nodes_fixed.end(),
[](std::shared_ptr<DAGOrderHelper> a, std::shared_ptr<DAGOrderHelper> b) { return a->sortNumber() < b->sortNumber(); });
for (auto idx = 1; idx < nodes_within_current_layer.size(); ++idx) { for (int idx = 0; idx < nodes_hangout.size(); ++idx) {
auto prev = nodes_within_current_layer[idx - 1]; nodes_hangout[idx]->setSortNumber((*min_anchor)->sortNumber().toInt() - idx - 1);
auto curr = nodes_within_current_layer[idx]; }
if (prev->sortNumber() == curr->sortNumber()) }
curr->setSortNumber(curr->sortNumber() + 0.000000000000001);
// 提取当前层次节点排序值
this->current_nodelist_filling_indi(layer_index, nodes);
}
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<std::shared_ptr<DAGOrderHelper>>& nodes)
{
// 提取本层次节点
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> ins) { return ins->layerNumber() == layer_index; });
if (!nodes_within_current_layer.size())
return false;
std::sort(nodes_within_current_layer.begin(), nodes_within_current_layer.end(),
[](std::shared_ptr<DAGOrderHelper>a, std::shared_ptr<DAGOrderHelper> 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<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();
});
// 提取节点划分档次
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();
});
ordered_values = ordered_values.toSet().toList();
std::sort(ordered_values.begin(), ordered_values.end());
if (ordered_values.size() == nodes_within_current_layer.size())
return false;
// 填缝
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<std::shared_ptr<DAGOrderHelper>> pick_ups;
std::copy_if(nodes_within_current_layer.begin(), nodes_within_current_layer.end(), std::back_inserter(pick_ups),
[=](std::shared_ptr<DAGOrderHelper> 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);
} }
} }
}
return true;
}
// 提取所有已知节点 void dags::DAGGraph::nodes_sort_with_above(int layer_index, const QList<std::shared_ptr<DAGOrderHelper>>& nodes)
QList<std::shared_ptr<DAGOrderHelper>> sorting_nodes; {
std::copy_if(nodes.begin(), nodes.end(), std::back_inserter(sorting_nodes), // 提取所有已知节点
[&](std::shared_ptr<DAGOrderHelper> n) { return n->layerNumber() <= layer_index; }); QList<std::shared_ptr<DAGOrderHelper>> sorting_nodes;
std::copy_if(nodes.begin(), nodes.end(), std::back_inserter(sorting_nodes),
[&](std::shared_ptr<DAGOrderHelper> n) { return n->layerNumber() <= layer_index; });
// 排序值提取与重排 // 排序值提取与重排
QList<double> sort_values; QList<double> sort_values;
std::transform(sorting_nodes.begin(), sorting_nodes.end(), std::back_inserter(sort_values), std::transform(sorting_nodes.begin(), sorting_nodes.end(), std::back_inserter(sort_values),
[](std::shared_ptr<DAGOrderHelper> n)->double { return n->sortNumber(); }); [](std::shared_ptr<DAGOrderHelper> n)->double { return n->sortNumber().toDouble(); });
sort_values = sort_values.toSet().toList(); sort_values = sort_values.toSet().toList();
std::sort(sort_values.begin(), sort_values.end()); std::sort(sort_values.begin(), sort_values.end());
// 检索排序中轴 // 检索排序中轴
auto temp_anchor = std::make_pair<double, int>(DBL_MAX, -1); auto temp_anchor = std::make_pair<double, int>(DBL_MAX, -1);
for (int nidx = 0; nidx < sort_values.size(); ++nidx) { for (int nidx = 0; nidx < sort_values.size(); ++nidx) {
auto value_span = std::abs(sort_values[nidx]); auto value_span = std::abs(sort_values[nidx]);
if (value_span <= temp_anchor.first) if (value_span <= temp_anchor.first)
temp_anchor = std::make_pair(value_span, nidx); 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::graph_adjust_after_layout(const QList<std::shared_ptr<DAGOrderHelper>>& 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))
this->nodes_sort_with_belows(layer_index, total_nodes);
layer_index--;
};
}
bool dags::DAGGraph::layer_adjust_via_next_sibling(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; });
for (auto node : curr_layer_nodes) {
this->node_adjust_via_next_sibling(node, total_nodes);
}
return curr_layer;
}
void dags::DAGGraph::node_adjust_via_next_sibling(std::shared_ptr<DAGOrderHelper> curr_node, const QList<std::shared_ptr<DAGOrderHelper>>& total_nodes)
{
// 计算下游调整参考节点
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();
}
else {
if (inst->isFakeNode()) {
return curr_node->layerNode() == inst->tailsNode();
}
else {
auto next_vnodes = curr_node->layerNode()->nextNodes();
return next_vnodes.contains(inst->layerNode());
}
}
} }
return false;
});
// 排序值重整 std::sort(next_layer_nodes.begin(), next_layer_nodes.end(),
for (int sorting_idx = 0; sorting_idx < sorting_nodes.size(); ++sorting_idx) { [](std::shared_ptr<DAGOrderHelper> a, std::shared_ptr<DAGOrderHelper> b) {
auto node = sorting_nodes[sorting_idx]; return a->sortNumber() < b->sortNumber();
auto sort_idx = sort_values.indexOf(node->sortNumber()); });
node->setSortNumber(sort_idx - temp_anchor.second);
}
this->graph_layer_nodes_sort(layer_index + 1, nodes); if (next_layer_nodes.size()) {
curr_node->setSortNumber(next_layer_nodes.first()->sortNumber().toDouble());
}
}
void dags::DAGGraph::nodes_sort_with_belows(int curr_layer, const QList<std::shared_ptr<DAGOrderHelper>>& total_nodes)
{
// 提取所有已知节点
QList<std::shared_ptr<DAGOrderHelper>> sorting_nodes;
std::copy_if(total_nodes.begin(), total_nodes.end(), std::back_inserter(sorting_nodes),
[=](std::shared_ptr<DAGOrderHelper> ins) { return ins->layerNumber() >= curr_layer; });
// 排序值提取与重排
QList<double> sort_values;
std::transform(sorting_nodes.begin(), sorting_nodes.end(), std::back_inserter(sort_values),
[](std::shared_ptr<DAGOrderHelper> 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<double, int>(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().toDouble());
node->setSortNumber(sort_idx - temp_anchor.second);
} }
} }
@ -322,8 +491,14 @@ void dags::DAGGraph::graphLayout() {
} }
auto tidy_nodes = this->tidy_graph_nodes(); auto tidy_nodes = this->tidy_graph_nodes();
this->graph_layer_nodes_sort(0, tidy_nodes); this->graph_layer_nodes_sort_forward(0, tidy_nodes);
this->node_with_layout = tidy_nodes; this->node_with_layout = tidy_nodes;
int times = 1;
while (times--) {
this->graph_adjust_after_layout(tidy_nodes);
this->graph_layer_nodes_sort_forward(0, tidy_nodes);
}
} }

View File

@ -35,7 +35,7 @@ namespace dags {
std::shared_ptr<DAGLayerHelper> relate_bind = nullptr; std::shared_ptr<DAGLayerHelper> relate_bind = nullptr;
std::shared_ptr<DAGLayerHelper> towards_to = nullptr; std::shared_ptr<DAGLayerHelper> towards_to = nullptr;
int layer_number = 0; int layer_number = 0;
double sort_number = 0; QVariant sort_number;
QList<std::shared_ptr<DAGOrderHelper>> __prev_layer_nodes; QList<std::shared_ptr<DAGOrderHelper>> __prev_layer_nodes;
public: public:
@ -54,13 +54,13 @@ namespace dags {
bool isFakeNode() const; bool isFakeNode() const;
std::shared_ptr<DAGLayerHelper> layerNode() const; std::shared_ptr<DAGLayerHelper> layerNode() const;
std::shared_ptr<DAGLayerHelper> relateNode() const; std::shared_ptr<DAGLayerHelper> tailsNode() const;
std::shared_ptr<DAGLayerHelper> towardsNode() const; std::shared_ptr<DAGLayerHelper> headsNode() const;
int layerNumber() const; int layerNumber() const;
void setLayerNumber(int v); void setLayerNumber(int v);
double sortNumber() const; QVariant sortNumber() const;
void setSortNumber(double v); void setSortNumber(double v);
QList<std::shared_ptr<DAGOrderHelper>> getUpstreamNodes() const; QList<std::shared_ptr<DAGOrderHelper>> getUpstreamNodes() const;
@ -76,17 +76,26 @@ namespace dags {
public: public:
void rebuildFromEdges(const QList<graph_data::Arrow>& arrow_list); void rebuildFromEdges(const QList<graph_data::Arrow>& arrow_list);
void graphLayout();
QList<std::shared_ptr<DAGOrderHelper>> nodeWithLayout() const; QList<std::shared_ptr<DAGOrderHelper>> nodeWithLayout() const;
int maxLayerCount() const; int maxLayerCount() const;
void graphLayout();
private: private:
std::shared_ptr<DAGLayerHelper> spawns_peak(QList<std::shared_ptr<DAGLayerHelper>>& ref_set); std::shared_ptr<DAGLayerHelper> spawns_peak(QList<std::shared_ptr<DAGLayerHelper>>& ref_set);
void graph_recovery(QList<std::shared_ptr<DAGLayerHelper>> sort_seqs); void graph_recovery(const QList<std::shared_ptr<DAGLayerHelper>> &sort_seqs);
int node_layering(std::shared_ptr<DAGLayerHelper> inst, int layer_current); int node_layering(const std::shared_ptr<DAGLayerHelper> &inst, int layer_current);
int node_layering_adj(std::shared_ptr<DAGLayerHelper> inst); int node_layering_adj(std::shared_ptr<DAGLayerHelper> inst);
QList<std::shared_ptr<DAGOrderHelper>> tidy_graph_nodes(); QList<std::shared_ptr<DAGOrderHelper>> tidy_graph_nodes();
void graph_layer_nodes_sort(int layer_index, QList<std::shared_ptr<DAGOrderHelper>> nodes); void graph_layer_nodes_sort_forward(int layer_index, const QList<std::shared_ptr<DAGOrderHelper>> &nodes);
void graph_adjust_after_layout(const QList<std::shared_ptr<DAGOrderHelper>>& total_nodes);
bool layer_adjust_via_next_sibling(int curr_layer, const QList<std::shared_ptr<DAGOrderHelper>>& total_nodes);
void node_adjust_via_next_sibling(std::shared_ptr<DAGOrderHelper> curr_node, const QList<std::shared_ptr<DAGOrderHelper>>& total_nodes);
bool current_nodelist_filling_indi(int curr_layer, const QList<std::shared_ptr<DAGOrderHelper>>& total_nodes);
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);
}; };
} }

View File

@ -60,6 +60,7 @@ void PenetrateNode::paint(QPainter* painter, const QStyleOptionGraphicsItem* opt
auto outline = this->boundingRect(); auto outline = this->boundingRect();
painter->save(); painter->save();
painter->setRenderHint(QPainter::Antialiasing);
auto ypos = outline.height() / 2 - 3; auto ypos = outline.height() / 2 - 3;
if (this->isHighlighted()) if (this->isHighlighted())
@ -172,11 +173,11 @@ QList<IGraphNode*> DAGActiveView::layer_nodes_construction(const QHash<IGraphNod
// ¹¹½¨µ±Ç°²ã´ÎͼÐνڵã // ¹¹½¨µ±Ç°²ã´ÎͼÐνڵã
for (auto& data_node : current_layer_datas) { for (auto& data_node : current_layer_datas) {
if (data_node->isFakeNode()) { if (data_node->isFakeNode()) {
auto from = data_node->relateNode()->bindPoint().name(); auto from = data_node->tailsNode()->bindPoint().name();
auto to = data_node->towardsNode()->bindPoint().name(); auto to = data_node->headsNode()->bindPoint().name();
auto curr_gnode = new PenetrateNode(20, from, to); auto curr_gnode = new PenetrateNode(20, from, to);
this->scene_bind.addItem(curr_gnode); 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; current_nodes_helper[curr_gnode] = data_node;
} }
@ -187,7 +188,7 @@ QList<IGraphNode*> DAGActiveView::layer_nodes_construction(const QHash<IGraphNod
} }
auto curr_gnode = new ActivePresentNode(data_node->layerNode()->bindPoint().name(), node_type_vx, this->font()); auto curr_gnode = new ActivePresentNode(data_node->layerNode()->bindPoint().name(), node_type_vx, this->font());
this->scene_bind.addItem(curr_gnode); 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; current_nodes_helper[curr_gnode] = data_node;
} }

View File

@ -2,8 +2,9 @@
#include "dag_layout.h" #include "dag_layout.h"
#include "xast_parse.h" #include "xast_parse.h"
#include "dag_present.h" #include "dag_present.h"
#include "view_present.h" #include "cmp_present.h"
#include <argsparser.h> #include <argsparser.h>
#include "storypresent.h"
#include <QDebug> #include <QDebug>
#include <QMessageBox> #include <QMessageBox>
#include <QTextEdit> #include <QTextEdit>
@ -24,7 +25,13 @@ int main(int argc, char* argv[]) {
auto test_mode = std::make_shared<MatchMode>(0x000bu, u8"开发过程内部测试"); auto test_mode = std::make_shared<MatchMode>(0x000bu, u8"开发过程内部测试");
cmdrec << test_mode; cmdrec << test_mode;
(*test_mode) << std::make_shared<IndexParam>(u8"StoryPresent", u8"程序名") << make_shared<FloatOption>(u8"test", u8"打印帮助文档"); (*test_mode) << std::make_shared<IndexParam>(u8"StoryPresent", u8"程序名") << make_shared<FloatOption>(u8"test", u8"内部开发测试选项");
auto graph_mode = std::make_shared<MatchMode>(0x000cu, u8"图形化展示故事内容");
cmdrec << graph_mode;
(*graph_mode) << std::make_shared<IndexParam>(u8"StoryPresent", u8"程序名")
<< make_shared<FloatKeyValue>(u8"graph", u8"内部开发测试选项填写dag或udg")
<< make_shared<FloatKeyValue>(u8"path", u8"指定xast文件路径");
auto rst = cmdrec.parse(argc, argv); auto rst = cmdrec.parse(argc, argv);
QTextEdit msg; QTextEdit msg;
@ -44,26 +51,16 @@ int main(int argc, char* argv[]) {
case 0x000bu: case 0x000bu:
{ {
auto arrows = QList<graph_data::Arrow>() << }break;
graph_data::Arrow(u8"a中文测试", u8"b中文测试") << case 0x000cu:
graph_data::Arrow(u8"c中文测试", u8"b中文测试") << {
graph_data::Arrow(u8"c中文测试", u8"d中文测试") << auto type = rst->getUnitViaKey(u8"graph");
graph_data::Arrow(u8"b中文测试", u8"e中文测试") << auto path = rst->getUnitViaKey(u8"path");
graph_data::Arrow(u8"d中文测试", u8"e中文测试") << if (type->value().toString() == "dag") {
graph_data::Arrow(u8"c中文测试", u8"e中文测试"); auto view = new StoryPresent();
auto view = new dags::DAGActiveView; view->loadXAST(path->value().toString());
view->updateWithEdges(arrows); view->show();
view->show(); }
//dags::DAGGraph tools;
//tools.rebuildFromEdges(arrows);
//tools.graphLayout();
//for (auto n : tools.nodeWithLayout()) {
// msg.setWindowTitle("layout-message");
// msg.append(QString("node:%3,layer:%1,sort:%2").arg(n->layerNumber()).arg(n->sortNumber()).arg(n->layerNode()->bindPoint().name()));
// msg.show();
//}
}break; }break;
default: default:
break; break;

View File

@ -1,9 +1,81 @@
#include "storypresent.h" #include "storypresent.h"
#include <QFileInfo>
#include <QMessageBox>
#include <QMenu>
#include <QMenuBar>
StoryPresent::StoryPresent(QWidget *parent) using namespace dags;
: QMainWindow(parent) using namespace xast_parse;
StoryPresent::StoryPresent(QWidget* parent)
: QMainWindow(parent), _story_present(new DAGActiveView(this))
{ {
setCentralWidget(_story_present);
auto mbar = menuBar();
auto view = mbar->addMenu(u8"视图");
view->addAction(u8"缩小", this, &StoryPresent::lesser, Qt::CTRL + Qt::Key_N);
view->addAction(u8"放大", this, &StoryPresent::bigger, Qt::CTRL + Qt::Key_P);
} }
StoryPresent::~StoryPresent() StoryPresent::~StoryPresent()
{} {}
#include "xast_parse.h"
void StoryPresent::loadXAST(const QString& ast_path)
{
QFileInfo finfo(ast_path);
if (!finfo.exists() || !finfo.isFile()) {
QMessageBox::critical(this, u8"文件错误", QString(u8"指定文件(%1非法").arg(ast_path));
return;
}
xast_parse::XAST_Parser t(ast_path);
this->_story_graph = t.storyGraph();
QList<graph_data::Arrow> arrows;
for (auto& key : this->_story_graph.keys()) {
auto story_line = this->_story_graph[key];
auto arrow_start = story_line->name();
auto frag_temp = story_line->firstChild();
while (frag_temp) {
switch (frag_temp->type()) {
case SliceType::FragmentDefines: {
auto arrow_tail = std::dynamic_pointer_cast<FragmentDefine>(frag_temp)->name() + u8"@" + story_line->name();
arrows << graph_data::Arrow(arrow_start, arrow_tail);
arrow_start = arrow_tail;
}break;
case SliceType::FragmentRefers: {
auto conv_refer = std::dynamic_pointer_cast<FragmentRefer>(frag_temp);
auto arrow_tail = conv_refer->fragmentRefer() + u8"@" + conv_refer->storyRefer();
arrows << graph_data::Arrow(arrow_start, arrow_tail);
arrow_start = arrow_tail;
}break;
default: break;
}
frag_temp = frag_temp->nextSlice();
}
}
this->_story_present->updateWithEdges(arrows);
}
#include <QTransform>
void StoryPresent::bigger()
{
_scale_value *= 1.1;
QTransform trans_base;
trans_base.scale(_scale_value, _scale_value);
this->_story_present->setTransform(trans_base);
}
void StoryPresent::lesser()
{
_scale_value /= 1.1;
QTransform trans_base;
trans_base.scale(_scale_value, _scale_value);
this->_story_present->setTransform(trans_base);
}

View File

@ -1,6 +1,8 @@
#pragma once #pragma once
#include <QtWidgets/QMainWindow> #include <QtWidgets/QMainWindow>
#include "dag_present.h"
#include "xast_parse.h"
class StoryPresent : public QMainWindow { class StoryPresent : public QMainWindow {
Q_OBJECT Q_OBJECT
@ -9,4 +11,13 @@ public:
StoryPresent(QWidget* parent = nullptr); StoryPresent(QWidget* parent = nullptr);
~StoryPresent(); ~StoryPresent();
void loadXAST(const QString &ast_path);
private:
double _scale_value = 1;
dags::DAGActiveView *const _story_present;
QHash<QString, std::shared_ptr<xast_parse::StoryDefine>> _story_graph;
void bigger();
void lesser();
}; };