This commit is contained in:
parent
37e3119934
commit
d416efb5b5
|
@ -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>--help</LocalDebuggerCommandArguments>
|
<LocalDebuggerCommandArguments>--test</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'">
|
||||||
|
|
|
@ -228,21 +228,22 @@ QList<std::shared_ptr<DAGOrderHelper>> DAGGraph::tidy_graph_nodes() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DAGGraph::graph_layer_nodes_sort(int layer_index, QList<std::shared_ptr<DAGOrderHelper>> nodes) {
|
void DAGGraph::graph_layer_nodes_sort(int layer_index, QList<std::shared_ptr<DAGOrderHelper>> nodes) {
|
||||||
QList<std::shared_ptr<DAGOrderHelper>> target_nodes_within_layer;
|
QList<std::shared_ptr<DAGOrderHelper>> nodes_within_current_layer;
|
||||||
for (auto n : nodes)
|
for (auto n : nodes)
|
||||||
if (n->layerNumber() == layer_index) {
|
if (n->layerNumber() == layer_index) {
|
||||||
target_nodes_within_layer.append(n);
|
nodes_within_current_layer.append(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target_nodes_within_layer.size()) {
|
if (nodes_within_current_layer.size()) {
|
||||||
|
// 计算当前层次所有节点排序
|
||||||
if (!layer_index) {
|
if (!layer_index) {
|
||||||
for (auto idx = 0; idx < target_nodes_within_layer.size(); ++idx) {
|
for (auto idx = 0; idx < nodes_within_current_layer.size(); ++idx) {
|
||||||
target_nodes_within_layer[idx]->setSortNumber(idx + 1);
|
nodes_within_current_layer[idx]->setSortNumber(idx + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (layer_index > 0) {
|
else if (layer_index > 0) {
|
||||||
for (auto target_node : target_nodes_within_layer) {
|
for (auto target_node : nodes_within_current_layer) {
|
||||||
QList<float> prev_sorts;
|
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::transform(upstream_list.begin(), upstream_list.end(),
|
||||||
std::back_inserter(prev_sorts), [](std::shared_ptr<DAGOrderHelper> inst) {
|
std::back_inserter(prev_sorts), [](std::shared_ptr<DAGOrderHelper> inst) {
|
||||||
|
@ -250,21 +251,47 @@ void DAGGraph::graph_layer_nodes_sort(int layer_index, QList<std::shared_ptr<DAG
|
||||||
});
|
});
|
||||||
|
|
||||||
if (prev_sorts.size()) {
|
if (prev_sorts.size()) {
|
||||||
target_node->setSortNumber(std::accumulate(prev_sorts.begin(), prev_sorts.end(), 0) / prev_sorts.size());
|
auto target_sum = std::accumulate(prev_sorts.begin(), prev_sorts.end(), 0.0);
|
||||||
|
target_node->setSortNumber(target_sum / prev_sorts.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort(target_nodes_within_layer.begin(), target_nodes_within_layer.end(),
|
// 当前层次节点排序值修正
|
||||||
[](std::shared_ptr<DAGOrderHelper> a, std::shared_ptr<DAGOrderHelper> b) {
|
for (auto idx = 1; idx < nodes_within_current_layer.size(); ++idx) {
|
||||||
return a->sortNumber() < b->sortNumber();
|
auto prev = nodes_within_current_layer[idx - 1];
|
||||||
});
|
auto curr = nodes_within_current_layer[idx];
|
||||||
|
if (prev->sortNumber() == curr->sortNumber())
|
||||||
for (auto idx = 0; idx < target_nodes_within_layer.size(); ++idx) {
|
curr->setSortNumber(curr->sortNumber() + DBL_MIN);
|
||||||
auto target_item = target_nodes_within_layer[idx];
|
|
||||||
target_item->setSortNumber(idx + 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 提取所有已知节点
|
||||||
|
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;
|
||||||
|
std::transform(sorting_nodes.begin(), sorting_nodes.end(), std::back_inserter(sort_values),
|
||||||
|
[](std::shared_ptr<DAGOrderHelper> 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<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());
|
||||||
|
node->setSortNumber(sort_idx - temp_anchor.second);
|
||||||
|
}
|
||||||
|
|
||||||
this->graph_layer_nodes_sort(layer_index + 1, nodes);
|
this->graph_layer_nodes_sort(layer_index + 1, nodes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "dag_present.h"
|
#include "dag_present.h"
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
using namespace dags;
|
using namespace dags;
|
||||||
|
|
||||||
|
@ -12,6 +13,7 @@ QString ActivePresentNode::nodeName() const {
|
||||||
|
|
||||||
QRectF ActivePresentNode::boundingRect() const {
|
QRectF ActivePresentNode::boundingRect() const {
|
||||||
auto rect = this->measure_base.boundingRect(this->node_name);
|
auto rect = this->measure_base.boundingRect(this->node_name);
|
||||||
|
rect.moveTo(0, 0);
|
||||||
return rect += QMarginsF(0, 0, 10, 10);
|
return rect += QMarginsF(0, 0, 10, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +30,7 @@ void ActivePresentNode::paint(QPainter* painter, const QStyleOptionGraphicsItem*
|
||||||
}
|
}
|
||||||
|
|
||||||
painter->drawRect(outline);
|
painter->drawRect(outline);
|
||||||
painter->drawText(outline - QMarginsF(5, 5, 5, 5), this->node_name);
|
painter->drawText(outline - QMarginsF(5, 5, 0, 0), this->node_name);
|
||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,9 +62,9 @@ void PenetrateNode::paint(QPainter* painter, const QStyleOptionGraphicsItem* opt
|
||||||
painter->save();
|
painter->save();
|
||||||
|
|
||||||
if (this->isHighlighted())
|
if (this->isHighlighted())
|
||||||
painter->fillRect(QRectF(0, -2, outline.width(), 4), Qt::red);
|
painter->fillRect(QRectF(0, 2, outline.width(), 4), Qt::red);
|
||||||
else
|
else
|
||||||
painter->fillRect(QRectF(0, -2, outline.width(), 4), Qt::black);
|
painter->fillRect(QRectF(0, 2, outline.width(), 4), Qt::black);
|
||||||
|
|
||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
|
@ -75,10 +77,10 @@ void TransitionCurve::layoutRefresh() {
|
||||||
auto orect = this->start_node->boundingRect();
|
auto orect = this->start_node->boundingRect();
|
||||||
auto erect = this->end_node->boundingRect();
|
auto erect = this->end_node->boundingRect();
|
||||||
|
|
||||||
auto xpos = this->start_node->pos().x() + this->start_node->boundingRect().width();
|
auto xpos = this->start_node->pos().x() + orect.width();
|
||||||
auto width_value = this->end_node->pos().x() - this->start_node->pos().x() - orect.width();
|
|
||||||
|
|
||||||
auto ypos = std::min(this->start_node->pos().y(), this->end_node->pos().y());
|
auto ypos = std::min(this->start_node->pos().y(), this->end_node->pos().y());
|
||||||
|
|
||||||
|
auto width_value = this->end_node->pos().x() - xpos;
|
||||||
auto bottom_y = std::max(this->start_node->pos().y() + orect.height(), this->end_node->pos().y() + erect.height());
|
auto bottom_y = std::max(this->start_node->pos().y() + orect.height(), this->end_node->pos().y() + erect.height());
|
||||||
|
|
||||||
this->outline = QRectF(0, 0, width_value, bottom_y - ypos);
|
this->outline = QRectF(0, 0, width_value, bottom_y - ypos);
|
||||||
|
@ -105,18 +107,20 @@ QRectF TransitionCurve::boundingRect() const {
|
||||||
|
|
||||||
void TransitionCurve::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) {
|
void TransitionCurve::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) {
|
||||||
auto outline = this->boundingRect();
|
auto outline = this->boundingRect();
|
||||||
|
|
||||||
auto start_rect = this->start_node->boundingRect();
|
auto start_rect = this->start_node->boundingRect();
|
||||||
auto end_rect = this->end_node->boundingRect();
|
auto end_rect = this->end_node->boundingRect();
|
||||||
auto aj_start_pos = this->start_node->pos() + QPointF(start_rect.width(), 0);
|
start_rect.moveTo(this->start_node->pos());
|
||||||
auto aj_end_pos = this->end_node->pos();
|
end_rect.moveTo(this->end_node->pos());
|
||||||
|
|
||||||
|
auto aj_start_pos = start_rect.topRight();
|
||||||
|
auto aj_end_pos = end_rect.topLeft();
|
||||||
auto line_span = this->prev_layer_w - start_rect.width();
|
auto line_span = this->prev_layer_w - start_rect.width();
|
||||||
|
|
||||||
painter->save();
|
painter->save();
|
||||||
painter->setRenderHint(QPainter::Antialiasing);
|
painter->setRenderHint(QPainter::Antialiasing);
|
||||||
|
|
||||||
auto start_pos = aj_start_pos - QGraphicsItem::pos();
|
auto start_pos = aj_start_pos - QGraphicsItem::pos() + QPointF(0, start_rect.height() / 2);
|
||||||
auto end_pos = aj_end_pos - QGraphicsItem::pos();
|
auto end_pos = aj_end_pos - QGraphicsItem::pos() + QPointF(0, end_rect.height() / 2);
|
||||||
|
|
||||||
auto line_epos = start_pos + QPointF(line_span, 0);
|
auto line_epos = start_pos + QPointF(line_span, 0);
|
||||||
auto control_pos0 = line_epos + QPointF((outline.width() - line_span) / 3, 0);
|
auto control_pos0 = line_epos + QPointF((outline.width() - line_span) / 3, 0);
|
||||||
|
@ -148,8 +152,7 @@ DAGActiveView::DAGActiveView(QWidget* parent)
|
||||||
this->setFont(f);
|
this->setFont(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<IGraphNode*> DAGActiveView::layer_nodes_construction(
|
QList<IGraphNode*> DAGActiveView::layer_nodes_construction(const QHash<IGraphNode*, std::shared_ptr<DAGOrderHelper>>& prev_layer_helper,
|
||||||
const QHash<IGraphNode*, std::shared_ptr<DAGOrderHelper>>& prev_layer_helper,
|
|
||||||
const QList<std::shared_ptr<DAGOrderHelper>>& total_datas, int layer_idx, double prev_layer_end) {
|
const QList<std::shared_ptr<DAGOrderHelper>>& total_datas, int layer_idx, double prev_layer_end) {
|
||||||
// 挑选当前层次节点
|
// 挑选当前层次节点
|
||||||
QList<std::shared_ptr<DAGOrderHelper>> current_layer_datas;
|
QList<std::shared_ptr<DAGOrderHelper>> current_layer_datas;
|
||||||
|
@ -166,14 +169,13 @@ QList<IGraphNode*> DAGActiveView::layer_nodes_construction(
|
||||||
return current_nodes_helper.keys();
|
return current_nodes_helper.keys();
|
||||||
|
|
||||||
// 构建当前层次图形节点
|
// 构建当前层次图形节点
|
||||||
double ypos_acc = 0;
|
|
||||||
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->relateNode()->bindPoint().name();
|
||||||
auto to = data_node->towardsNode()->bindPoint().name();
|
auto to = data_node->towardsNode()->bindPoint().name();
|
||||||
auto curr_gnode = new PenetrateNode(20, from, to);
|
auto curr_gnode = new PenetrateNode(20, from, to);
|
||||||
curr_gnode->setPos(prev_layer_end, ypos_acc);
|
this->scene_bind.addItem(curr_gnode);
|
||||||
ypos_acc += curr_gnode->boundingRect().height();
|
curr_gnode->setPos(prev_layer_end, data_node->sortNumber() * (this->node_span + this->font().pointSizeF()) * 7);
|
||||||
|
|
||||||
current_nodes_helper[curr_gnode] = data_node;
|
current_nodes_helper[curr_gnode] = data_node;
|
||||||
}
|
}
|
||||||
|
@ -183,12 +185,11 @@ QList<IGraphNode*> DAGActiveView::layer_nodes_construction(
|
||||||
node_type_vx = PrsnType::StartNode;
|
node_type_vx = PrsnType::StartNode;
|
||||||
}
|
}
|
||||||
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());
|
||||||
curr_gnode->setPos(prev_layer_end, ypos_acc);
|
this->scene_bind.addItem(curr_gnode);
|
||||||
ypos_acc += curr_gnode->boundingRect().height();
|
curr_gnode->setPos(prev_layer_end, data_node->sortNumber() * (this->node_span + this->font().pointSizeF()) * 7);
|
||||||
|
|
||||||
current_nodes_helper[curr_gnode] = data_node;
|
current_nodes_helper[curr_gnode] = data_node;
|
||||||
}
|
}
|
||||||
ypos_acc += this->node_span;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 对其当前层次节点宽度
|
// 对其当前层次节点宽度
|
||||||
|
@ -220,6 +221,7 @@ QList<IGraphNode*> DAGActiveView::layer_nodes_construction(
|
||||||
auto prev_data = prev_layer_helper[prev_gnode];
|
auto prev_data = prev_layer_helper[prev_gnode];
|
||||||
if (upstream_nodes.contains(prev_data)) {
|
if (upstream_nodes.contains(prev_data)) {
|
||||||
auto line_cmbn = new TransitionCurve(prev_gnode, curr_gnode, prev_layer_width);
|
auto line_cmbn = new TransitionCurve(prev_gnode, curr_gnode, prev_layer_width);
|
||||||
|
this->scene_bind.addItem(line_cmbn);
|
||||||
line_cmbn->layoutRefresh();
|
line_cmbn->layoutRefresh();
|
||||||
next_nodes << line_cmbn;
|
next_nodes << line_cmbn;
|
||||||
}
|
}
|
||||||
|
@ -232,17 +234,16 @@ QList<IGraphNode*> DAGActiveView::layer_nodes_construction(
|
||||||
}
|
}
|
||||||
|
|
||||||
void DAGActiveView::updateWithEdges(QList<graph_data::Arrow> arrows) {
|
void DAGActiveView::updateWithEdges(QList<graph_data::Arrow> arrows) {
|
||||||
|
// Çå³ýµ±Ç°ÊÓͼ
|
||||||
|
this->scene_bind.clear();
|
||||||
|
this->total_graph_nodes.clear();
|
||||||
|
|
||||||
DAGGraph tools;
|
DAGGraph tools;
|
||||||
tools.rebuildFromEdges(arrows);
|
tools.rebuildFromEdges(arrows);
|
||||||
tools.graphLayout();
|
tools.graphLayout();
|
||||||
|
|
||||||
auto total_nodes = tools.nodeWithLayout();
|
auto total_nodes = tools.nodeWithLayout();
|
||||||
|
total_graph_nodes = this->layer_nodes_construction(QHash<IGraphNode*, std::shared_ptr<DAGOrderHelper>>(), total_nodes);
|
||||||
auto gnodelist = this->layer_nodes_construction(QHash<IGraphNode*, std::shared_ptr<DAGOrderHelper>>(), total_nodes);
|
|
||||||
for (auto& gnode : gnodelist) {
|
|
||||||
this->scene_bind.addItem(dynamic_cast<QGraphicsItem*>(gnode));
|
|
||||||
total_graph_nodes << gnode;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DAGActiveView::highlightGraphLink(const QList<graph_data::Arrow> arrows) {
|
void DAGActiveView::highlightGraphLink(const QList<graph_data::Arrow> arrows) {
|
||||||
|
|
|
@ -109,15 +109,15 @@ namespace dags {
|
||||||
public:
|
public:
|
||||||
DAGActiveView(QWidget* parent = nullptr);
|
DAGActiveView(QWidget* parent = nullptr);
|
||||||
|
|
||||||
QList<IGraphNode*> layer_nodes_construction(
|
|
||||||
const QHash<IGraphNode*, std::shared_ptr<dags::DAGOrderHelper>>& prev_layer,
|
|
||||||
const QList<std::shared_ptr<dags::DAGOrderHelper>>& total_datas,
|
|
||||||
int layer_idx = 0, double prev_layer_end = 0);
|
|
||||||
|
|
||||||
void updateWithEdges(QList<graph_data::Arrow> arrows);
|
void updateWithEdges(QList<graph_data::Arrow> arrows);
|
||||||
void highlightGraphLink(const QList<graph_data::Arrow> color_path);
|
void highlightGraphLink(const QList<graph_data::Arrow> color_path);
|
||||||
|
|
||||||
|
// QGraphicsView
|
||||||
virtual void mousePressEvent(QMouseEvent *ev) override;
|
virtual void mousePressEvent(QMouseEvent *ev) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QList<IGraphNode*> layer_nodes_construction(const QHash<IGraphNode*, std::shared_ptr<dags::DAGOrderHelper>>& prev_layer,
|
||||||
|
const QList<std::shared_ptr<dags::DAGOrderHelper>>& total_datas, int layer_idx = 0, double prev_layer_end = 0);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,10 @@ int main(int argc, char* argv[]) {
|
||||||
cmdrec << help_mode;
|
cmdrec << help_mode;
|
||||||
(*help_mode) << std::make_shared<IndexParam>(u8"StoryPresent", u8"程序名") << make_shared<FloatOption>(u8"help", u8"打印帮助文档");
|
(*help_mode) << std::make_shared<IndexParam>(u8"StoryPresent", u8"程序名") << make_shared<FloatOption>(u8"help", u8"打印帮助文档");
|
||||||
|
|
||||||
|
auto test_mode = std::make_shared<MatchMode>(0x000bu, u8"开发过程内部测试");
|
||||||
|
cmdrec << test_mode;
|
||||||
|
(*test_mode) << std::make_shared<IndexParam>(u8"StoryPresent", u8"程序名") << make_shared<FloatOption>(u8"test", u8"打印帮助文档");
|
||||||
|
|
||||||
auto rst = cmdrec.parse(argc, argv);
|
auto rst = cmdrec.parse(argc, argv);
|
||||||
QTextEdit msg;
|
QTextEdit msg;
|
||||||
msg.setReadOnly(true);
|
msg.setReadOnly(true);
|
||||||
|
@ -37,6 +41,30 @@ int main(int argc, char* argv[]) {
|
||||||
msg.setPlainText(cmdrec.helperDoc());
|
msg.setPlainText(cmdrec.helperDoc());
|
||||||
msg.show();
|
msg.show();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0x000bu:
|
||||||
|
{
|
||||||
|
auto arrows = QList<graph_data::Arrow>() <<
|
||||||
|
graph_data::Arrow(u8"a中文测试", u8"b中文测试") <<
|
||||||
|
graph_data::Arrow(u8"c中文测试", u8"b中文测试") <<
|
||||||
|
graph_data::Arrow(u8"c中文测试", u8"d中文测试") <<
|
||||||
|
graph_data::Arrow(u8"b中文测试", u8"e中文测试") <<
|
||||||
|
graph_data::Arrow(u8"d中文测试", u8"e中文测试") <<
|
||||||
|
graph_data::Arrow(u8"a中文测试", u8"e中文测试");
|
||||||
|
auto view = new dags::DAGActiveView;
|
||||||
|
view->updateWithEdges(arrows);
|
||||||
|
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;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue