mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2024-11-01 13:13:21 -07: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() {
|
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) {
|
public override void Render(DrawingContext context) {
|
||||||
|
@ -75,6 +79,9 @@ namespace SourceGit.Views {
|
||||||
var width = Bounds.Width;
|
var width = Bounds.Width;
|
||||||
var height = Bounds.Height;
|
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
|
// Draw coordinate
|
||||||
var maxLabel = new FormattedText($"{maxV}", CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, 12.0, LineBrush);
|
var maxLabel = new FormattedText($"{maxV}", CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, 12.0, LineBrush);
|
||||||
var horizonStart = maxLabel.Width + 8;
|
var horizonStart = maxLabel.Width + 8;
|
||||||
|
@ -108,13 +115,14 @@ namespace SourceGit.Views {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate hit boxes
|
// Calculate hit boxes
|
||||||
var shapeWidth = Math.Min(32, stepX - 4);
|
if (_hitBoxes.Count == 0) {
|
||||||
var hitboxes = new List<Rect>();
|
var shapeWidth = Math.Min(32, stepX - 4);
|
||||||
for (int i = 0; i < samples.Count; i++) {
|
for (int i = 0; i < samples.Count; i++) {
|
||||||
var h = samples[i].Count * (height - labelHeight) / maxV;
|
var h = samples[i].Count * (height - labelHeight) / maxV;
|
||||||
var x = horizonStart + 1 + stepX * i + (stepX - shapeWidth) * 0.5;
|
var x = horizonStart + 1 + stepX * i + (stepX - shapeWidth) * 0.5;
|
||||||
var y = height - labelHeight - h;
|
var y = height - labelHeight - h;
|
||||||
hitboxes.Add(new Rect(x, y, shapeWidth, h));
|
_hitBoxes.Add(new Rect(x, y, shapeWidth, h - 1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw shapes
|
// Draw shapes
|
||||||
|
@ -126,7 +134,7 @@ namespace SourceGit.Views {
|
||||||
typeface,
|
typeface,
|
||||||
10.0,
|
10.0,
|
||||||
LineBrush);
|
LineBrush);
|
||||||
var rect = hitboxes[i];
|
var rect = _hitBoxes[i];
|
||||||
var xLabel = rect.X - (hLabel.Width - rect.Width) * 0.5;
|
var xLabel = rect.X - (hLabel.Width - rect.Width) * 0.5;
|
||||||
var yLabel = height - labelHeight + 4;
|
var yLabel = height - labelHeight + 4;
|
||||||
|
|
||||||
|
@ -145,32 +153,45 @@ namespace SourceGit.Views {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw labels on hover
|
// Draw labels on hover
|
||||||
for (int i = 0; i < samples.Count; i++) {
|
if (_lastHitIdx >= 0 && _lastHitIdx < samples.Count) {
|
||||||
var rect = hitboxes[i];
|
var rect = _hitBoxes[_lastHitIdx];
|
||||||
if (rect.Contains(_mousePos)) {
|
var tooltip = new FormattedText(
|
||||||
var tooltip = new FormattedText(
|
$"{samples[_lastHitIdx].Count}",
|
||||||
$"{samples[i].Count}",
|
|
||||||
CultureInfo.CurrentCulture,
|
CultureInfo.CurrentCulture,
|
||||||
FlowDirection.LeftToRight,
|
FlowDirection.LeftToRight,
|
||||||
typeface,
|
typeface,
|
||||||
12.0,
|
12.0,
|
||||||
LineBrush);
|
LineBrush);
|
||||||
|
|
||||||
var tx = rect.X - (tooltip.Width - rect.Width) * 0.5;
|
var tx = rect.X - (tooltip.Width - rect.Width) * 0.5;
|
||||||
var ty = rect.Y - tooltip.Height - 4;
|
var ty = rect.Y - tooltip.Height - 4;
|
||||||
context.DrawText(tooltip, new Point(tx, ty));
|
context.DrawText(tooltip, new Point(tx, ty));
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnPointerMoved(PointerEventArgs e) {
|
protected override void OnPointerMoved(PointerEventArgs e) {
|
||||||
base.OnPointerMoved(e);
|
base.OnPointerMoved(e);
|
||||||
_mousePos = e.GetPosition(this);
|
|
||||||
InvalidateVisual();
|
var p = e.GetPosition(this);
|
||||||
|
for (int i = 0; i < _hitBoxes.Count; i++) {
|
||||||
|
if (_hitBoxes[i].Contains(p)) {
|
||||||
|
if (_lastHitIdx != i) {
|
||||||
|
_lastHitIdx = i;
|
||||||
|
InvalidateVisual();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_lastHitIdx != -1) {
|
||||||
|
_lastHitIdx = -1;
|
||||||
|
InvalidateVisual();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Point _mousePos = new Point(0, 0);
|
private List<Rect> _hitBoxes = new List<Rect>();
|
||||||
|
private int _lastHitIdx = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public partial class Statistics : Window {
|
public partial class Statistics : Window {
|
||||||
|
|
Loading…
Reference in a new issue