mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2024-12-23 20:47:25 -08:00
optimize<Statistics>: only redraw chart when mouse hovered on a new sample box
This commit is contained in:
parent
ad9cf615ab
commit
ade43ed988
1 changed files with 43 additions and 22 deletions
|
@ -42,7 +42,11 @@ namespace SourceGit.Views {
|
|||
}
|
||||
|
||||
static Chart() {
|
||||
AffectsRender<Chart>(SamplesProperty);
|
||||
SamplesProperty.Changed.AddClassHandler<Chart>((c, e) => {
|
||||
c._hitBoxes.Clear();
|
||||
c._lastHitIdx = -1;
|
||||
c.InvalidateVisual();
|
||||
});
|
||||
}
|
||||
|
||||
public override void Render(DrawingContext context) {
|
||||
|
@ -75,6 +79,9 @@ namespace SourceGit.Views {
|
|||
var width = Bounds.Width;
|
||||
var height = Bounds.Height;
|
||||
|
||||
// Transparent background to block mouse move events.
|
||||
context.DrawRectangle(Brushes.Transparent, null, new Rect(0, 0, Bounds.Width, Bounds.Height));
|
||||
|
||||
// Draw coordinate
|
||||
var maxLabel = new FormattedText($"{maxV}", CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, 12.0, LineBrush);
|
||||
var horizonStart = maxLabel.Width + 8;
|
||||
|
@ -108,13 +115,14 @@ namespace SourceGit.Views {
|
|||
}
|
||||
|
||||
// Calculate hit boxes
|
||||
if (_hitBoxes.Count == 0) {
|
||||
var shapeWidth = Math.Min(32, stepX - 4);
|
||||
var hitboxes = new List<Rect>();
|
||||
for (int i = 0; i < samples.Count; i++) {
|
||||
var h = samples[i].Count * (height - labelHeight) / maxV;
|
||||
var x = horizonStart + 1 + stepX * i + (stepX - shapeWidth) * 0.5;
|
||||
var y = height - labelHeight - h;
|
||||
hitboxes.Add(new Rect(x, y, shapeWidth, h));
|
||||
_hitBoxes.Add(new Rect(x, y, shapeWidth, h - 1));
|
||||
}
|
||||
}
|
||||
|
||||
// Draw shapes
|
||||
|
@ -126,7 +134,7 @@ namespace SourceGit.Views {
|
|||
typeface,
|
||||
10.0,
|
||||
LineBrush);
|
||||
var rect = hitboxes[i];
|
||||
var rect = _hitBoxes[i];
|
||||
var xLabel = rect.X - (hLabel.Width - rect.Width) * 0.5;
|
||||
var yLabel = height - labelHeight + 4;
|
||||
|
||||
|
@ -145,11 +153,10 @@ namespace SourceGit.Views {
|
|||
}
|
||||
|
||||
// Draw labels on hover
|
||||
for (int i = 0; i < samples.Count; i++) {
|
||||
var rect = hitboxes[i];
|
||||
if (rect.Contains(_mousePos)) {
|
||||
if (_lastHitIdx >= 0 && _lastHitIdx < samples.Count) {
|
||||
var rect = _hitBoxes[_lastHitIdx];
|
||||
var tooltip = new FormattedText(
|
||||
$"{samples[i].Count}",
|
||||
$"{samples[_lastHitIdx].Count}",
|
||||
CultureInfo.CurrentCulture,
|
||||
FlowDirection.LeftToRight,
|
||||
typeface,
|
||||
|
@ -159,18 +166,32 @@ namespace SourceGit.Views {
|
|||
var tx = rect.X - (tooltip.Width - rect.Width) * 0.5;
|
||||
var ty = rect.Y - tooltip.Height - 4;
|
||||
context.DrawText(tooltip, new Point(tx, ty));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPointerMoved(PointerEventArgs e) {
|
||||
base.OnPointerMoved(e);
|
||||
_mousePos = e.GetPosition(this);
|
||||
|
||||
var p = e.GetPosition(this);
|
||||
for (int i = 0; i < _hitBoxes.Count; i++) {
|
||||
if (_hitBoxes[i].Contains(p)) {
|
||||
if (_lastHitIdx != i) {
|
||||
_lastHitIdx = i;
|
||||
InvalidateVisual();
|
||||
}
|
||||
|
||||
private Point _mousePos = new Point(0, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (_lastHitIdx != -1) {
|
||||
_lastHitIdx = -1;
|
||||
InvalidateVisual();
|
||||
}
|
||||
}
|
||||
|
||||
private List<Rect> _hitBoxes = new List<Rect>();
|
||||
private int _lastHitIdx = -1;
|
||||
}
|
||||
|
||||
public partial class Statistics : Window {
|
||||
|
|
Loading…
Reference in a new issue