feature<Statistics>: show hovered sample tooltip in chart

This commit is contained in:
leo 2022-01-13 10:54:45 +08:00
parent e641deee5c
commit bc404de937

View file

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Windows; using System.Windows;
using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
namespace SourceGit.Views.Controls { namespace SourceGit.Views.Controls {
@ -34,8 +35,9 @@ namespace SourceGit.Views.Controls {
set { SetValue(ChartBrushProperty, value); } set { SetValue(ChartBrushProperty, value); }
} }
private int maxV = 0;
private List<Models.StatisticSample> samples = new List<Models.StatisticSample>(); private List<Models.StatisticSample> samples = new List<Models.StatisticSample>();
private List<Rect> hitboxes = new List<Rect>();
private int maxV = 0;
/// <summary> /// <summary>
/// 设置绘制数据 /// 设置绘制数据
@ -43,13 +45,19 @@ namespace SourceGit.Views.Controls {
/// <param name="samples">数据源</param> /// <param name="samples">数据源</param>
public void SetData(List<Models.StatisticSample> samples) { public void SetData(List<Models.StatisticSample> samples) {
this.samples = samples; this.samples = samples;
maxV = 0; this.hitboxes.Clear();
maxV = 0;
foreach (var s in samples) { foreach (var s in samples) {
if (maxV < s.Count) maxV = s.Count; if (maxV < s.Count) maxV = s.Count;
} }
maxV = (int)Math.Ceiling(maxV / 10.0) * 10; maxV = (int)Math.Ceiling(maxV / 10.0) * 10;
InvalidateVisual();
}
protected override void OnMouseMove(MouseEventArgs e) {
base.OnMouseMove(e);
InvalidateVisual(); InvalidateVisual();
} }
@ -78,18 +86,25 @@ namespace SourceGit.Views.Controls {
var dashHeight = i * stepV; var dashHeight = i * stepV;
var vy = Math.Max(0, dashHeight - vLabel.Height * 0.5); var vy = Math.Max(0, dashHeight - vLabel.Height * 0.5);
dc.PushOpacity(.1);
dc.DrawLine(gridPen, new Point(LABEL_UNIT + 1, dashHeight), new Point(ActualWidth, dashHeight)); dc.DrawLine(gridPen, new Point(LABEL_UNIT + 1, dashHeight), new Point(ActualWidth, dashHeight));
dc.Pop();
dc.DrawText(vLabel, new Point(0, vy)); dc.DrawText(vLabel, new Point(0, vy));
} }
var stepX = (ActualWidth - LABEL_UNIT) / samples.Count; var stepX = (ActualWidth - LABEL_UNIT) / samples.Count;
var shapeWidth = Math.Min(LABEL_UNIT, stepX - 4); if (hitboxes.Count == 0) {
for (int i = 0; i < samples.Count; i++) { var shapeWidth = Math.Min(LABEL_UNIT, stepX - 4);
var h = samples[i].Count * (ActualHeight - LABEL_UNIT) / maxV; for (int i = 0; i < samples.Count; i++) {
var x = LABEL_UNIT + 1 + stepX * i + (stepX - shapeWidth) * 0.5; var h = samples[i].Count * (ActualHeight - LABEL_UNIT) / maxV;
var y = ActualHeight - LABEL_UNIT - h; var x = LABEL_UNIT + 1 + stepX * i + (stepX - shapeWidth) * 0.5;
var rect = new Rect(x, y, shapeWidth, h); var y = ActualHeight - LABEL_UNIT - h;
hitboxes.Add(new Rect(x, y, shapeWidth, h));
}
}
var mouse = Mouse.GetPosition(this);
for (int i = 0; i < samples.Count; i++) {
var hLabel = new FormattedText( var hLabel = new FormattedText(
samples[i].Name, samples[i].Name,
CultureInfo.CurrentCulture, CultureInfo.CurrentCulture,
@ -98,7 +113,8 @@ namespace SourceGit.Views.Controls {
10.0, 10.0,
LineBrush, LineBrush,
VisualTreeHelper.GetDpi(this).PixelsPerDip); VisualTreeHelper.GetDpi(this).PixelsPerDip);
var xLabel = x - (hLabel.Width - shapeWidth) * 0.5; var rect = hitboxes[i];
var xLabel = rect.X - (hLabel.Width - rect.Width) * 0.5;
var yLabel = ActualHeight - LABEL_UNIT + 4; var yLabel = ActualHeight - LABEL_UNIT + 4;
dc.DrawRectangle(ChartBrush, null, rect); dc.DrawRectangle(ChartBrush, null, rect);
@ -111,7 +127,26 @@ namespace SourceGit.Views.Controls {
dc.Pop(); dc.Pop();
} else { } else {
dc.DrawText(hLabel, new Point(xLabel, yLabel)); dc.DrawText(hLabel, new Point(xLabel, yLabel));
} }
}
for (int i = 0; i < samples.Count; i++) {
var rect = hitboxes[i];
if (rect.Contains(mouse)) {
var tooltip = new FormattedText(
$"{samples[i].Count}",
CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
new Typeface(font, FontStyles.Normal, FontWeights.Normal, FontStretches.Normal),
12.0,
FindResource("Brush.FG1") as Brush,
VisualTreeHelper.GetDpi(this).PixelsPerDip);
var tx = rect.X - (tooltip.Width - rect.Width) * 0.5;
var ty = rect.Y - tooltip.Height - 4;
dc.DrawText(tooltip, new Point(tx, ty));
break;
}
} }
} }
} }