comparison grapher.cpp @ 52:384420567575

* Use the date when laying out rows
author Chris Cannam
date Fri, 12 Nov 2010 11:32:01 +0000
parents bf3ab0ffb559
children 3c46b2ac45d3
comparison
equal deleted inserted replaced
51:bf3ab0ffb559 52:384420567575
64 row = parentItem->row(); 64 row = parentItem->row();
65 haveRow = true; 65 haveRow = true;
66 } 66 }
67 } 67 }
68 row = row - 1; 68 row = row - 1;
69 }
70
71 // row is now an upper bound on our eventual row (because we want
72 // to be above all parents). But we also want to ensure we are
73 // above all nodes that have earlier dates (to the nearest day).
74 // m_rowDates maps each row to a date: use that.
75
76 QString date = cs->date();
77
78 // n.b. this relies on the fact that the date component of an ISO
79 // date/time sorts correctly in a dictionary sort
80 while (m_rowDates.contains(row) && m_rowDates[row] < date) {
81 --row;
82 }
83
84 // We have already laid out all nodes that have earlier timestamps
85 // than this one, so we know (among other things) that we can
86 // safely fill in this row has having this date, if it isn't in
87 // the map yet (it cannot have an earlier date)
88
89 if (!m_rowDates.contains(row)) {
90 m_rowDates[row] = date;
69 } 91 }
70 92
71 std::cerr << "putting " << cs->id().toStdString() << " at row " << row 93 std::cerr << "putting " << cs->id().toStdString() << " at row " << row
72 << std::endl; 94 << std::endl;
73 95
176 foreach (QString childId, cs->children()) { 198 foreach (QString childId, cs->children()) {
177 if (!m_changesets.contains(childId)) continue; 199 if (!m_changesets.contains(childId)) continue;
178 Changeset *child = m_changesets[childId]; 200 Changeset *child = m_changesets[childId];
179 if (child->parents().size() > 1) { 201 if (child->parents().size() > 1) {
180 int childRow = m_items[childId]->row(); 202 int childRow = m_items[childId]->row();
181 std::cerr << "I'm at " << row << ", child with >1 parents is at " << childRow << std::endl;
182 for (int r = row; r > childRow; --r) { 203 for (int r = row; r > childRow; --r) {
183 std::cerr << "setting row " << r << ", col " << col << std::endl;
184 m_alloc[r].insert(col); 204 m_alloc[r].insert(col);
185 } 205 }
186 } 206 }
187 } 207 }
188 208
199 child->parents().size() == 1) { 219 child->parents().size() == 1) {
200 special.push_back(childId); 220 special.push_back(childId);
201 } 221 }
202 } 222 }
203 if (special.size() == 2) { 223 if (special.size() == 2) {
204 m_items[special[0]]->setColumn 224 for (int i = 0; i < 2; ++i) {
205 (findAvailableColumn(item->row() - 1, col - 1, true)); 225 int off = i * 2 - 1; // 0 -> -1, 1 -> 1
206 m_items[special[1]]->setColumn 226 ChangesetItem *it = m_items[special[i]];
207 (findAvailableColumn(item->row() - 1, col + 1, true)); 227 it->setColumn(findAvailableColumn(it->row(), col + off, true));
208 m_handled.insert(special[0]); 228 m_alloc[it->row()].insert(it->column());
209 m_handled.insert(special[1]); 229 m_handled.insert(special[i]);
230 }
210 } 231 }
211 } 232 }
212 } 233 }
213 234
214 bool 235 bool
269 foreach (QString branch, m_branchRanges.keys()) { 290 foreach (QString branch, m_branchRanges.keys()) {
270 std::cerr << branch.toStdString() << ": " << m_branchRanges[branch].first << " - " << m_branchRanges[branch].second << ", home " << m_branchHomes[branch] << std::endl; 291 std::cerr << branch.toStdString() << ": " << m_branchRanges[branch].first << " - " << m_branchRanges[branch].second << ", home " << m_branchHomes[branch] << std::endl;
271 } 292 }
272 } 293 }
273 294
295 static bool
296 compareChangesetsByDate(Changeset *const &a, Changeset *const &b)
297 {
298 return a->timestamp() < b->timestamp();
299 }
300
274 void 301 void
275 Grapher::layout(Changesets csets) 302 Grapher::layout(Changesets csets)
276 { 303 {
277 m_changesets.clear(); 304 m_changesets.clear();
278 m_items.clear(); 305 m_items.clear();
312 conn->setParent(m_items[parentId]); 339 conn->setParent(m_items[parentId]);
313 m_scene->addItem(conn); 340 m_scene->addItem(conn);
314 } 341 }
315 } 342 }
316 343
317 // Layout in reverse order, i.e. forward chronological order. 344 // We need to lay out the changesets in forward chronological
318 // This ensures that parents will normally be laid out before 345 // order. We have no guarantees about the order in which
319 // their children -- though we can recurse from layout() if we 346 // changesets appear in the list -- in a simple repository they
320 // find any weird exceptions 347 // will generally be reverse chronological, but that's far from
321 348 // guaranteed. So, sort explicitly using the date comparator
322 //!!! changesets are not in any chronological order, necessarily: 349 // above
323 // we need to sort by datetime() [or, better, numerical date] 350
324 // and then use m_rowDateMap 351 qStableSort(csets.begin(), csets.end(), compareChangesetsByDate);
325 352
326 m_handled.clear(); 353 m_handled.clear();
327 for (int i = csets.size() - 1; i >= 0; --i) { 354 for (int i = csets.size() - 1; i >= 0; --i) {
328 layoutRow(csets[i]->id()); 355 layoutRow(csets[i]->id());
329 } 356 }