This commit is contained in:
parent
37e3119934
commit
d416efb5b5
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LocalDebuggerCommandArguments>--help</LocalDebuggerCommandArguments>
|
||||
<LocalDebuggerCommandArguments>--test</LocalDebuggerCommandArguments>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<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) {
|
||||
QList<std::shared_ptr<DAGOrderHelper>> target_nodes_within_layer;
|
||||
QList<std::shared_ptr<DAGOrderHelper>> nodes_within_current_layer;
|
||||
for (auto n : nodes)
|
||||
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) {
|
||||
for (auto idx = 0; idx < target_nodes_within_layer.size(); ++idx) {
|
||||
target_nodes_within_layer[idx]->setSortNumber(idx + 1);
|
||||
for (auto idx = 0; idx < nodes_within_current_layer.size(); ++idx) {
|
||||
nodes_within_current_layer[idx]->setSortNumber(idx + 1);
|
||||
}
|
||||
}
|
||||
else if (layer_index > 0) {
|
||||
for (auto target_node : target_nodes_within_layer) {
|
||||
QList<float> prev_sorts;
|
||||
for (auto target_node : nodes_within_current_layer) {
|
||||
QList<double> prev_sorts;
|
||||
auto upstream_list = target_node->getUpstreamNodes();
|
||||
std::transform(upstream_list.begin(), upstream_list.end(),
|
||||
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()) {
|
||||
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) {
|
||||
return a->sortNumber() < b->sortNumber();
|
||||
});
|
||||
|
||||
for (auto idx = 0; idx < target_nodes_within_layer.size(); ++idx) {
|
||||
auto target_item = target_nodes_within_layer[idx];
|
||||
target_item->setSortNumber(idx + 1);
|
||||
// 当前层次节点排序值修正
|
||||
for (auto idx = 1; idx < nodes_within_current_layer.size(); ++idx) {
|
||||
auto prev = nodes_within_current_layer[idx - 1];
|
||||
auto curr = nodes_within_current_layer[idx];
|
||||
if (prev->sortNumber() == curr->sortNumber())
|
||||
curr->setSortNumber(curr->sortNumber() + DBL_MIN);
|
||||
}
|
||||
}
|
||||
|
||||
// 提取所有已知节点
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "dag_present.h"
|
||||
#include <QDebug>
|
||||
|
||||
using namespace dags;
|
||||
|
||||
|
@ -12,6 +13,7 @@ QString ActivePresentNode::nodeName() const {
|
|||
|
||||
QRectF ActivePresentNode::boundingRect() const {
|
||||
auto rect = this->measure_base.boundingRect(this->node_name);
|
||||
rect.moveTo(0, 0);
|
||||
return rect += QMarginsF(0, 0, 10, 10);
|
||||
}
|
||||
|
||||
|
@ -28,7 +30,7 @@ void ActivePresentNode::paint(QPainter* painter, const QStyleOptionGraphicsItem*
|
|||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -60,9 +62,9 @@ void PenetrateNode::paint(QPainter* painter, const QStyleOptionGraphicsItem* opt
|
|||
painter->save();
|
||||
|
||||
if (this->isHighlighted())
|
||||
painter->fillRect(QRectF(0, -2, outline.width(), 4), Qt::red);
|
||||
painter->fillRect(QRectF(0, 2, outline.width(), 4), Qt::red);
|
||||
else
|
||||
painter->fillRect(QRectF(0, -2, outline.width(), 4), Qt::black);
|
||||
painter->fillRect(QRectF(0, 2, outline.width(), 4), Qt::black);
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
@ -75,10 +77,10 @@ void TransitionCurve::layoutRefresh() {
|
|||
auto orect = this->start_node->boundingRect();
|
||||
auto erect = this->end_node->boundingRect();
|
||||
|
||||
auto xpos = this->start_node->pos().x() + this->start_node->boundingRect().width();
|
||||
auto width_value = this->end_node->pos().x() - this->start_node->pos().x() - orect.width();
|
||||
|
||||
auto xpos = this->start_node->pos().x() + orect.width();
|
||||
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());
|
||||
|
||||
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) {
|
||||
auto outline = this->boundingRect();
|
||||
|
||||
auto start_rect = this->start_node->boundingRect();
|
||||
auto end_rect = this->end_node->boundingRect();
|
||||
auto aj_start_pos = this->start_node->pos() + QPointF(start_rect.width(), 0);
|
||||
auto aj_end_pos = this->end_node->pos();
|
||||
start_rect.moveTo(this->start_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();
|
||||
|
||||
painter->save();
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
auto start_pos = aj_start_pos - QGraphicsItem::pos();
|
||||
auto end_pos = aj_end_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() + QPointF(0, end_rect.height() / 2);
|
||||
|
||||
auto line_epos = start_pos + QPointF(line_span, 0);
|
||||
auto control_pos0 = line_epos + QPointF((outline.width() - line_span) / 3, 0);
|
||||
|
@ -148,8 +152,7 @@ DAGActiveView::DAGActiveView(QWidget* parent)
|
|||
this->setFont(f);
|
||||
}
|
||||
|
||||
QList<IGraphNode*> DAGActiveView::layer_nodes_construction(
|
||||
const QHash<IGraphNode*, std::shared_ptr<DAGOrderHelper>>& prev_layer_helper,
|
||||
QList<IGraphNode*> DAGActiveView::layer_nodes_construction(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) {
|
||||
// 挑选当前层次节点
|
||||
QList<std::shared_ptr<DAGOrderHelper>> current_layer_datas;
|
||||
|
@ -166,14 +169,13 @@ QList<IGraphNode*> DAGActiveView::layer_nodes_construction(
|
|||
return current_nodes_helper.keys();
|
||||
|
||||
// 构建当前层次图形节点
|
||||
double ypos_acc = 0;
|
||||
for (auto& data_node : current_layer_datas) {
|
||||
if (data_node->isFakeNode()) {
|
||||
auto from = data_node->relateNode()->bindPoint().name();
|
||||
auto to = data_node->towardsNode()->bindPoint().name();
|
||||
auto curr_gnode = new PenetrateNode(20, from, to);
|
||||
curr_gnode->setPos(prev_layer_end, ypos_acc);
|
||||
ypos_acc += curr_gnode->boundingRect().height();
|
||||
this->scene_bind.addItem(curr_gnode);
|
||||
curr_gnode->setPos(prev_layer_end, data_node->sortNumber() * (this->node_span + this->font().pointSizeF()) * 7);
|
||||
|
||||
current_nodes_helper[curr_gnode] = data_node;
|
||||
}
|
||||
|
@ -183,12 +185,11 @@ QList<IGraphNode*> DAGActiveView::layer_nodes_construction(
|
|||
node_type_vx = PrsnType::StartNode;
|
||||
}
|
||||
auto curr_gnode = new ActivePresentNode(data_node->layerNode()->bindPoint().name(), node_type_vx, this->font());
|
||||
curr_gnode->setPos(prev_layer_end, ypos_acc);
|
||||
ypos_acc += curr_gnode->boundingRect().height();
|
||||
this->scene_bind.addItem(curr_gnode);
|
||||
curr_gnode->setPos(prev_layer_end, data_node->sortNumber() * (this->node_span + this->font().pointSizeF()) * 7);
|
||||
|
||||
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];
|
||||
if (upstream_nodes.contains(prev_data)) {
|
||||
auto line_cmbn = new TransitionCurve(prev_gnode, curr_gnode, prev_layer_width);
|
||||
this->scene_bind.addItem(line_cmbn);
|
||||
line_cmbn->layoutRefresh();
|
||||
next_nodes << line_cmbn;
|
||||
}
|
||||
|
@ -232,17 +234,16 @@ QList<IGraphNode*> DAGActiveView::layer_nodes_construction(
|
|||
}
|
||||
|
||||
void DAGActiveView::updateWithEdges(QList<graph_data::Arrow> arrows) {
|
||||
// Çå³ýµ±Ç°ÊÓͼ
|
||||
this->scene_bind.clear();
|
||||
this->total_graph_nodes.clear();
|
||||
|
||||
DAGGraph tools;
|
||||
tools.rebuildFromEdges(arrows);
|
||||
tools.graphLayout();
|
||||
|
||||
auto total_nodes = tools.nodeWithLayout();
|
||||
|
||||
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;
|
||||
}
|
||||
total_graph_nodes = this->layer_nodes_construction(QHash<IGraphNode*, std::shared_ptr<DAGOrderHelper>>(), total_nodes);
|
||||
}
|
||||
|
||||
void DAGActiveView::highlightGraphLink(const QList<graph_data::Arrow> arrows) {
|
||||
|
|
|
@ -109,15 +109,15 @@ namespace dags {
|
|||
public:
|
||||
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 highlightGraphLink(const QList<graph_data::Arrow> color_path);
|
||||
|
||||
// QGraphicsView
|
||||
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;
|
||||
(*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);
|
||||
QTextEdit msg;
|
||||
msg.setReadOnly(true);
|
||||
|
@ -37,6 +41,30 @@ int main(int argc, char* argv[]) {
|
|||
msg.setPlainText(cmdrec.helperDoc());
|
||||
msg.show();
|
||||
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:
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue