From d416efb5b5673ab2d15563b4e80e3fe1bea6c1b1 Mon Sep 17 00:00:00 2001 From: codeboss <2422523675@qq.com> Date: Fri, 4 Oct 2024 18:58:34 +0800 Subject: [PATCH] 1 --- StoryPresent/StoryPresent.vcxproj.user | 2 +- StoryPresent/dag_layout.cpp | 59 +++++++++++++++++++------- StoryPresent/dag_present.cpp | 51 +++++++++++----------- StoryPresent/dag_present.h | 10 ++--- StoryPresent/main.cpp | 28 ++++++++++++ 5 files changed, 103 insertions(+), 47 deletions(-) diff --git a/StoryPresent/StoryPresent.vcxproj.user b/StoryPresent/StoryPresent.vcxproj.user index 2349169..655e87c 100644 --- a/StoryPresent/StoryPresent.vcxproj.user +++ b/StoryPresent/StoryPresent.vcxproj.user @@ -1,7 +1,7 @@  - --help + --test WindowsLocalDebugger diff --git a/StoryPresent/dag_layout.cpp b/StoryPresent/dag_layout.cpp index 71181a3..1094cf8 100644 --- a/StoryPresent/dag_layout.cpp +++ b/StoryPresent/dag_layout.cpp @@ -228,21 +228,22 @@ QList> DAGGraph::tidy_graph_nodes() { } void DAGGraph::graph_layer_nodes_sort(int layer_index, QList> nodes) { - QList> target_nodes_within_layer; + QList> 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 prev_sorts; + for (auto target_node : nodes_within_current_layer) { + QList prev_sorts; auto upstream_list = target_node->getUpstreamNodes(); std::transform(upstream_list.begin(), upstream_list.end(), std::back_inserter(prev_sorts), [](std::shared_ptr inst) { @@ -250,21 +251,47 @@ void DAGGraph::graph_layer_nodes_sort(int layer_index, QListsetSortNumber(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 a, std::shared_ptr 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> sorting_nodes; + std::copy_if(nodes.begin(), nodes.end(), std::back_inserter(sorting_nodes), + [&](std::shared_ptr n) { return n->layerNumber() <= layer_index; }); + + // ÅÅÐòÖµÌáÈ¡ÓëÖØÅÅ + QList sort_values; + std::transform(sorting_nodes.begin(), sorting_nodes.end(), std::back_inserter(sort_values), + [](std::shared_ptr 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(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); } } diff --git a/StoryPresent/dag_present.cpp b/StoryPresent/dag_present.cpp index dbe22f4..dcc9df3 100644 --- a/StoryPresent/dag_present.cpp +++ b/StoryPresent/dag_present.cpp @@ -1,4 +1,5 @@ #include "dag_present.h" +#include 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 DAGActiveView::layer_nodes_construction( - const QHash>& prev_layer_helper, +QList DAGActiveView::layer_nodes_construction(const QHash>& prev_layer_helper, const QList>& total_datas, int layer_idx, double prev_layer_end) { // ÌôÑ¡µ±Ç°²ã´Î½Úµã QList> current_layer_datas; @@ -166,14 +169,13 @@ QList 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 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 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 DAGActiveView::layer_nodes_construction( } void DAGActiveView::updateWithEdges(QList 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>(), total_nodes); - for (auto& gnode : gnodelist) { - this->scene_bind.addItem(dynamic_cast(gnode)); - total_graph_nodes << gnode; - } + total_graph_nodes = this->layer_nodes_construction(QHash>(), total_nodes); } void DAGActiveView::highlightGraphLink(const QList arrows) { diff --git a/StoryPresent/dag_present.h b/StoryPresent/dag_present.h index 974cbcd..59c6aee 100644 --- a/StoryPresent/dag_present.h +++ b/StoryPresent/dag_present.h @@ -109,15 +109,15 @@ namespace dags { public: DAGActiveView(QWidget* parent = nullptr); - QList layer_nodes_construction( - const QHash>& prev_layer, - const QList>& total_datas, - int layer_idx = 0, double prev_layer_end = 0); - void updateWithEdges(QList arrows); void highlightGraphLink(const QList color_path); + // QGraphicsView virtual void mousePressEvent(QMouseEvent *ev) override; + + private: + QList layer_nodes_construction(const QHash>& prev_layer, + const QList>& total_datas, int layer_idx = 0, double prev_layer_end = 0); }; }; diff --git a/StoryPresent/main.cpp b/StoryPresent/main.cpp index 9a4a3bb..73b048d 100644 --- a/StoryPresent/main.cpp +++ b/StoryPresent/main.cpp @@ -22,6 +22,10 @@ int main(int argc, char* argv[]) { cmdrec << help_mode; (*help_mode) << std::make_shared(u8"StoryPresent", u8"³ÌÐòÃû") << make_shared(u8"help", u8"´òÓ¡°ïÖúÎĵµ"); + auto test_mode = std::make_shared(0x000bu, u8"¿ª·¢¹ý³ÌÄÚ²¿²âÊÔ"); + cmdrec << test_mode; + (*test_mode) << std::make_shared(u8"StoryPresent", u8"³ÌÐòÃû") << make_shared(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(u8"aÖÐÎIJâÊÔ", u8"bÖÐÎIJâÊÔ") << + graph_data::Arrow(u8"cÖÐÎIJâÊÔ", u8"bÖÐÎIJâÊÔ") << + graph_data::Arrow(u8"cÖÐÎIJâÊÔ", u8"dÖÐÎIJâÊÔ") << + graph_data::Arrow(u8"bÖÐÎIJâÊÔ", u8"eÖÐÎIJâÊÔ") << + graph_data::Arrow(u8"dÖÐÎIJâÊÔ", u8"eÖÐÎIJâÊÔ") << + graph_data::Arrow(u8"aÖÐÎIJâÊÔ", u8"eÖÐÎIJâÊÔ"); + 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; }