data/RelationGraphStar.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "RelationGraphStar.h" | ||
| 2 | |||
| 3 | #include <QSet> | ||
| 4 | #include <QStringList> | ||
| 5 | #include <algorithm> | ||
| 6 | #include <cmath> | ||
| 7 | |||
| 8 | namespace RelationGraphStar { | ||
| 9 | |||
| 10 | namespace { | ||
| 11 | |||
| 12 | const QStringList kSectorOrder{QStringLiteral("family"), QStringLiteral("work"), | ||
| 13 | QStringLiteral("friends"), QStringLiteral("other"), | ||
| 14 | QStringLiteral("introductions"), QStringLiteral("suggestions")}; | ||
| 15 | |||
| 16 | 1314 | int sectorRank(const QString §or) { | |
| 17 | 1314 | const int index = int(kSectorOrder.indexOf(sector)); | |
| 18 |
1/2✗ Branch 3 → 4 not taken.
✓ Branch 3 → 6 taken 1314 times.
|
1314 | return index < 0 ? int(kSectorOrder.size()) : index; |
| 19 | } | ||
| 20 | |||
| 21 | } // namespace | ||
| 22 | |||
| 23 | 32 | RelationGraph::Graph gist(const RelationGraph::Graph &ego, const QHash<qint64, int> &kinship, int maxPeople, | |
| 24 | int *omitted) { | ||
| 25 | 32 | RelationGraph::Graph out; | |
| 26 | 32 | int centre = -1; | |
| 27 |
5/6✓ Branch 8 → 9 taken 64 times.
✗ Branch 8 → 11 not taken.
✓ Branch 9 → 10 taken 32 times.
✓ Branch 9 → 11 taken 32 times.
✓ Branch 12 → 3 taken 32 times.
✓ Branch 12 → 13 taken 32 times.
|
64 | for (int i = 0; i < ego.nodes.size() && centre < 0; ++i) |
| 28 |
1/2✓ Branch 4 → 5 taken 32 times.
✗ Branch 4 → 6 not taken.
|
32 | if (ego.nodes.at(i).center) |
| 29 | 32 | centre = i; | |
| 30 |
1/2✓ Branch 13 → 14 taken 32 times.
✗ Branch 13 → 15 not taken.
|
32 | if (omitted) |
| 31 | 32 | *omitted = 0; | |
| 32 |
1/2✗ Branch 15 → 16 not taken.
✓ Branch 15 → 17 taken 32 times.
|
32 | if (centre < 0) |
| 33 | ✗ | return out; | |
| 34 | // Each person's first line to the centre (ego() puts stored lines before inferred ones). | ||
| 35 | 32 | QHash<int, int> lineOf; // node → edge | |
| 36 | 32 | QList<int> candidates; | |
| 37 |
2/2✓ Branch 46 → 18 taken 605 times.
✓ Branch 46 → 47 taken 32 times.
|
637 | for (int e = 0; e < ego.edges.size(); ++e) { |
| 38 | 605 | const RelationGraph::Edge &edge = ego.edges.at(e); | |
| 39 |
8/8✓ Branch 21 → 22 taken 599 times.
✓ Branch 21 → 24 taken 6 times.
✓ Branch 22 → 23 taken 477 times.
✓ Branch 22 → 25 taken 122 times.
✓ Branch 23 → 24 taken 388 times.
✓ Branch 23 → 25 taken 89 times.
✓ Branch 26 → 27 taken 394 times.
✓ Branch 26 → 28 taken 211 times.
|
605 | if (edge.kind == QLatin1String("member") || (edge.from != centre && edge.to != centre)) |
| 40 | 406 | continue; | |
| 41 |
2/2✓ Branch 28 → 29 taken 122 times.
✓ Branch 28 → 30 taken 89 times.
|
211 | const int other = edge.from == centre ? edge.to : edge.from; |
| 42 | 211 | const RelationGraph::Node &node = ego.nodes.at(other); | |
| 43 |
6/8✓ Branch 32 → 33 taken 211 times.
✗ Branch 32 → 36 not taken.
✓ Branch 33 → 34 taken 211 times.
✗ Branch 33 → 36 not taken.
✓ Branch 35 → 36 taken 12 times.
✓ Branch 35 → 37 taken 199 times.
✓ Branch 38 → 39 taken 12 times.
✓ Branch 38 → 40 taken 199 times.
|
211 | if (node.family || node.moreCount > 0 || lineOf.contains(other)) |
| 44 | 12 | continue; | |
| 45 |
1/1✓ Branch 40 → 41 taken 199 times.
|
199 | lineOf.insert(other, e); |
| 46 |
1/1✓ Branch 41 → 42 taken 199 times.
|
199 | candidates.append(other); |
| 47 | } | ||
| 48 |
3/3✓ Branch 47 → 48 taken 32 times.
✓ Branch 48 → 49 taken 32 times.
✓ Branch 49 → 50 taken 32 times.
|
32 | std::stable_sort(candidates.begin(), candidates.end(), [&](int a, int b) { |
| 49 | 503 | const RelationGraph::Node &na = ego.nodes.at(a), &nb = ego.nodes.at(b); | |
| 50 |
2/2✓ Branch 6 → 7 taken 154 times.
✓ Branch 6 → 10 taken 349 times.
|
503 | if (sectorRank(na.sector) != sectorRank(nb.sector)) |
| 51 | 154 | return sectorRank(na.sector) < sectorRank(nb.sector); | |
| 52 | 349 | const int ka = kinship.value(na.cardId, 1000), kb = kinship.value(nb.cardId, 1000); | |
| 53 | 349 | return ka < kb; | |
| 54 | }); | ||
| 55 |
1/1✓ Branch 51 → 52 taken 32 times.
|
32 | const QList<int> kept = candidates.mid(0, std::max(0, maxPeople)); |
| 56 |
1/2✓ Branch 52 → 53 taken 32 times.
✗ Branch 52 → 65 not taken.
|
32 | if (omitted) { |
| 57 | 32 | int people = 0; | |
| 58 |
2/2✓ Branch 61 → 55 taken 238 times.
✓ Branch 61 → 62 taken 32 times.
|
270 | for (const RelationGraph::Node &node : ego.nodes) |
| 59 |
3/4✓ Branch 56 → 57 taken 206 times.
✓ Branch 56 → 59 taken 32 times.
✓ Branch 57 → 58 taken 206 times.
✗ Branch 57 → 59 not taken.
|
238 | if (!node.center && !node.family) |
| 60 | 206 | people += node.moreCount > 0 ? node.moreCount : 1; | |
| 61 | 32 | *omitted = std::max(0, people - int(kept.size())); | |
| 62 | } | ||
| 63 |
1/1✓ Branch 66 → 67 taken 32 times.
|
32 | out.nodes.append(ego.nodes.at(centre)); |
| 64 |
2/2✓ Branch 74 → 69 taken 180 times.
✓ Branch 74 → 75 taken 32 times.
|
212 | for (int index : kept) |
| 65 |
1/1✓ Branch 71 → 72 taken 180 times.
|
180 | out.nodes.append(ego.nodes.at(index)); |
| 66 |
2/2✓ Branch 90 → 76 taken 180 times.
✓ Branch 90 → 91 taken 32 times.
|
212 | for (int k = 0; k < kept.size(); ++k) { |
| 67 | 180 | RelationGraph::Edge edge = ego.edges.at(lineOf.value(kept.at(k))); | |
| 68 | 180 | const bool outward = edge.from == centre; | |
| 69 |
2/2✓ Branch 80 → 81 taken 103 times.
✓ Branch 80 → 82 taken 77 times.
|
180 | edge.from = outward ? 0 : k + 1; |
| 70 |
2/2✓ Branch 83 → 84 taken 103 times.
✓ Branch 83 → 85 taken 77 times.
|
180 | edge.to = outward ? k + 1 : 0; |
| 71 |
1/1✓ Branch 86 → 87 taken 180 times.
|
180 | out.edges.append(edge); |
| 72 | 180 | } | |
| 73 | 32 | return out; | |
| 74 | 32 | } | |
| 75 | |||
| 76 | 32 | RelationGraphLayout::Layout layout(const RelationGraph::Graph &graph, double aspect) { | |
| 77 | 32 | RelationGraphLayout::Layout out; | |
| 78 | 32 | const int people = int(graph.nodes.size()) - 1; | |
| 79 |
1/1✓ Branch 3 → 4 taken 32 times.
|
32 | const double wide = Radius * std::clamp(aspect, 1.0, 2.4); |
| 80 |
1/1✓ Branch 5 → 6 taken 32 times.
|
32 | out.positions.append(QPointF(0, 0)); |
| 81 |
2/2✓ Branch 11 → 7 taken 180 times.
✓ Branch 11 → 12 taken 32 times.
|
212 | for (int i = 0; i < people; ++i) { |
| 82 | 180 | const double angle = -M_PI / 2 + 2 * M_PI * i / std::max(1, people); | |
| 83 |
1/1✓ Branch 9 → 10 taken 180 times.
|
180 | out.positions.append(QPointF(std::round(wide * std::cos(angle)), std::round(Radius * std::sin(angle)))); |
| 84 | } | ||
| 85 |
2/2✓ Branch 26 → 14 taken 180 times.
✓ Branch 26 → 27 taken 32 times.
|
212 | for (const RelationGraph::Edge &edge : graph.edges) |
| 86 |
1/1✓ Branch 19 → 20 taken 180 times.
|
540 | out.routes.append({QStringLiteral("line"), {out.positions.value(edge.from), out.positions.value(edge.to)}}); |
| 87 | 32 | return out; | |
| 88 | 720 | } | |
| 89 | |||
| 90 | } // namespace RelationGraphStar | ||
| 91 |