data/RelationGraphClusters.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "RelationGraph.h" | ||
| 4 | #include "RelationGraphRoutes.h" | ||
| 5 | |||
| 6 | #include <QHash> | ||
| 7 | #include <QList> | ||
| 8 | #include <QPointF> | ||
| 9 | #include <QSizeF> | ||
| 10 | |||
| 11 | // The clusters of the relationship graph's overview (*Everyone*): pure and | ||
| 12 | // deterministic, used by RelationGraphLayout::overviewLayout. | ||
| 13 | // | ||
| 14 | // A cluster is a family (an overview block of people joined by family | ||
| 15 | // relationships or one family card, RelationGraphBlocks) together with the | ||
| 16 | // people who are not in a family and reach it first through their other | ||
| 17 | // relationships (a breadth-first search from all families at once): the | ||
| 18 | // Webers' friends stand beside the Webers. People who reach no family form | ||
| 19 | // clusters of their own, one per group joined by relationships. Each | ||
| 20 | // cluster is laid out on its own — the family as its tree, its people in | ||
| 21 | // columns beside it on the side of the person they are joined to; a | ||
| 22 | // cluster without a family by a small force layout — and the clusters are | ||
| 23 | // packed in rows as wide as the screen (larger clusters first), so lines | ||
| 24 | // stay inside clusters and the overview has no tangle. The lines between | ||
| 25 | // two clusters run as one bundle: from their people to a hub just outside | ||
| 26 | // each cluster, along one trunk between the hubs. | ||
| 27 | namespace RelationGraphLayout { | ||
| 28 | |||
| 29 | struct Cluster { | ||
| 30 | QList<int> tree; // the family's people (empty: a cluster without a family) | ||
| 31 | QList<int> satellites; // everyone else, in the order they were reached | ||
| 32 | QHash<int, int> parent; // satellite → the person it was reached from | ||
| 33 | bool family = false; // a family area is drawn around its tree | ||
| 34 | ✗ | QList<int> members() const { return tree + satellites; } | |
| 35 | }; | ||
| 36 | |||
| 37 | // The clusters in a deterministic order (by their first person's key); | ||
| 38 | // `clusterOf` receives each shown node's cluster (-1 for family cards and | ||
| 39 | // "+N more" nodes). | ||
| 40 | QList<Cluster> overviewClusters(const RelationGraph::Graph &graph, QList<int> *clusterOf); | ||
| 41 | |||
| 42 | // The members' positions around the middle of the cluster's bounds, and the | ||
| 43 | // room the cluster takes (people with their names, its family area). | ||
| 44 | QHash<int, QPointF> clusterLayout(const RelationGraph::Graph &graph, const Cluster &cluster, QSizeF *size); | ||
| 45 | |||
| 46 | // The centres of rectangles `sizes` packed in rows (the largest first by | ||
| 47 | // area, ties in index order) about `aspect` (width ÷ height) wide, `gap` | ||
| 48 | // between them, each row centred, the whole around (0, 0). | ||
| 49 | QList<QPointF> pack(const QList<QSizeF> &sizes, double aspect, double gap); | ||
| 50 | |||
| 51 | // Lines between two clusters that share the pair with another line become | ||
| 52 | // "bundle" routes (start, hub, hub, end; Route::bundle the number of lines | ||
| 53 | // in it); `centres`/`sizes` are the clusters' rectangles. | ||
| 54 | void bundleRoutes(const RelationGraph::Graph &graph, const QList<QPointF> &positions, const QList<int> &clusterOf, | ||
| 55 | const QList<QPointF> ¢res, const QList<QSizeF> &sizes, QList<Route> *routes); | ||
| 56 | |||
| 57 | } // namespace RelationGraphLayout | ||
| 58 |