Fixed label positions to begin at Margins not just bottom left of screen (#1488)

* Fixed label positions to begin at Margins not just bottom left of screen

* Tidied up Axis GetLabels and added margin control to GraphViewExample

* Added tests for very large margins
This commit is contained in:
Thomas Nind
2021-10-25 20:30:39 +01:00
committed by GitHub
parent 9d767a4171
commit b5799c3ded
4 changed files with 185 additions and 33 deletions

View File

@@ -256,7 +256,7 @@ namespace Terminal.Gui.Graphs {
int labels = 0;
int y = GetAxisYPosition (graph);
var start = graph.ScreenToGraphSpace (0, y);
var start = graph.ScreenToGraphSpace ((int)graph.MarginLeft, y);
var end = graph.ScreenToGraphSpace (bounds.Width, y);
// don't draw labels below the minimum
@@ -270,24 +270,22 @@ namespace Terminal.Gui.Graphs {
int screenX = graph.GraphSpaceToScreen (new PointF (current.X, current.Y)).X;
// Ensure the axis point does not draw into the margin
if (screenX >= graph.MarginLeft) {
// The increment we will render (normally a top T unicode symbol)
var toRender = new AxisIncrementToRender (Orientation, screenX, current.X);
// The increment we will render (normally a top T unicode symbol)
var toRender = new AxisIncrementToRender (Orientation, screenX, current.X);
// Not every increment has to have a label
if (ShowLabelsEvery != 0) {
// Not every increment has to have a label
if (ShowLabelsEvery != 0) {
// if this increment does also needs a label
if (labels++ % ShowLabelsEvery == 0) {
toRender.Text = LabelGetter (toRender);
};
}
// Label or no label definetly render it
yield return toRender;
// if this increment does also needs a label
if (labels++ % ShowLabelsEvery == 0) {
toRender.Text = LabelGetter (toRender);
};
}
// Label or no label definetly render it
yield return toRender;
current.X += Increment;
}
}
@@ -426,7 +424,7 @@ namespace Terminal.Gui.Graphs {
// remember screen space is top down so the lowest graph
// space value is at the bottom of the screen
var start = graph.ScreenToGraphSpace (x, bounds.Height - 1);
var start = graph.ScreenToGraphSpace (x, bounds.Height - (1 + (int)graph.MarginBottom));
var end = graph.ScreenToGraphSpace (x, 0);
// don't draw labels below the minimum
@@ -435,30 +433,27 @@ namespace Terminal.Gui.Graphs {
}
var current = start;
var dontDrawBelowScreenY = bounds.Height - graph.MarginBottom;
while (current.Y < end.Y) {
int screenY = graph.GraphSpaceToScreen (new PointF (current.X, current.Y)).Y;
// if the axis label is above the bottom margin (screen y starts at 0 at the top)
if (screenY < dontDrawBelowScreenY) {
// Create the axis symbol
var toRender = new AxisIncrementToRender (Orientation, screenY, current.Y);
// Create the axis symbol
var toRender = new AxisIncrementToRender (Orientation, screenY, current.Y);
// and the label (if we are due one)
if (ShowLabelsEvery != 0) {
// and the label (if we are due one)
if (ShowLabelsEvery != 0) {
// if this increment also needs a label
if (labels++ % ShowLabelsEvery == 0) {
toRender.Text = LabelGetter (toRender);
};
}
// draw the axis symbol (and label if it has one)
yield return toRender;
// if this increment also needs a label
if (labels++ % ShowLabelsEvery == 0) {
toRender.Text = LabelGetter (toRender);
};
}
// draw the axis symbol (and label if it has one)
yield return toRender;
current.Y += Increment;
}
}

View File

@@ -114,6 +114,15 @@ namespace Terminal.Gui {
return;
}
// The drawable area of the graph (anything that isn't in the margins)
var graphScreenWidth = Bounds.Width - ((int)MarginLeft);
var graphScreenHeight = Bounds.Height - (int)MarginBottom;
// if the margins take up the full draw bounds don't render
if (graphScreenWidth < 0 || graphScreenHeight < 0) {
return;
}
// Draw 'before' annotations
foreach (var a in Annotations.ToArray().Where (a => a.BeforeSeries)) {
a.Render (this);
@@ -137,8 +146,9 @@ namespace Terminal.Gui {
SetDriverColorToGraphColor ();
// The drawable area of the graph (anything that isn't in the margins)
Rect drawBounds = new Rect((int)MarginLeft,0, Bounds.Width - ((int)MarginLeft), Bounds.Height - (int)MarginBottom);
Rect drawBounds = new Rect((int)MarginLeft,0, graphScreenWidth, graphScreenHeight);
RectangleF graphSpace = ScreenToGraphSpace (drawBounds);
foreach (var s in Series.ToArray ()) {

View File

@@ -52,6 +52,10 @@ namespace UICatalog.Scenarios {
new MenuBarItem ("_View", new MenuItem [] {
new MenuItem ("Zoom _In", "", () => Zoom(0.5f)),
new MenuItem ("Zoom _Out", "", () => Zoom(2f)),
new MenuItem ("MarginLeft++", "", () => Margin(true,true)),
new MenuItem ("MarginLeft--", "", () => Margin(true,false)),
new MenuItem ("MarginBottom++", "", () => Margin(false,true)),
new MenuItem ("MarginBottom--", "", () => Margin(false,false)),
}),
});
@@ -676,6 +680,17 @@ namespace UICatalog.Scenarios {
graphView.SetNeedsDisplay ();
}
private void Margin (bool left, bool increase)
{
if (left) {
graphView.MarginLeft = (uint)Math.Max(0,graphView.MarginLeft + (increase ? 1 : -1));
}
else {
graphView.MarginBottom = (uint)Math.Max (0, graphView.MarginBottom + (increase ? 1 : -1));
}
graphView.SetNeedsDisplay ();
}
private void Quit ()
{

View File

@@ -1398,6 +1398,138 @@ namespace Terminal.Gui.Views {
Application.Shutdown ();
}
[Fact]
public void YAxisLabels_With_MarginBottom ()
{
GraphViewTests.InitFakeDriver ();
var gv = new GraphView {
ColorScheme = new ColorScheme (),
Bounds = new Rect (0, 0, 10, 7)
};
gv.CellSize = new PointF (1, 0.5f);
gv.AxisY.Increment = 1;
gv.AxisY.ShowLabelsEvery = 1;
gv.Series.Add (new ScatterSeries {
Points = { new PointF (1, 1), new PointF (5, 0) }
});
// reserve 3 cells of the console for the margin
gv.MarginBottom = 3;
gv.MarginLeft = 1;
gv.Redraw (gv.Bounds);
var expected =
@"
1┤x
0┼┬┬┬┬x┬┬┬
0 5
";
GraphViewTests.AssertDriverContentsAre (expected, output);
// Shutdown must be called to safely clean up Application if Init has been called
Application.Shutdown ();
}
[Fact]
public void XAxisLabels_With_MarginLeft()
{
GraphViewTests.InitFakeDriver ();
var gv = new GraphView {
ColorScheme = new ColorScheme (),
Bounds = new Rect (0, 0, 10, 7)
};
gv.CellSize = new PointF (1, 0.5f);
gv.AxisY.Increment = 1;
gv.AxisY.ShowLabelsEvery = 1;
gv.Series.Add (new ScatterSeries {
Points = { new PointF (1, 1), new PointF (5, 0) }
});
// reserve 3 cells of the left for the margin
gv.MarginLeft = 3;
gv.MarginBottom = 1;
gv.Redraw (gv.Bounds);
var expected =
@"
2┤
1┤x
0┼┬┬┬┬x┬
0 5
";
GraphViewTests.AssertDriverContentsAre (expected, output);
// Shutdown must be called to safely clean up Application if Init has been called
Application.Shutdown ();
}
[Fact]
public void MarginBottom_BiggerThanHeight_ExpectBlankGraph ()
{
var gv = GraphViewTests.GetGraph ();
gv.Height = 10;
gv.MarginBottom = 20;
gv.Series.Add (new ScatterSeries {
Points = { new PointF (1, 1), new PointF (5, 0) }
});
gv.Redraw (gv.Bounds);
var expected =
@"
";
GraphViewTests.AssertDriverContentsAre (expected, output);
// Shutdown must be called to safely clean up Application if Init has been called
Application.Shutdown ();
}
[Fact]
public void MarginLeft_BiggerThanWidth_ExpectBlankGraph ()
{
var gv = GraphViewTests.GetGraph ();
gv.Width = 10;
gv.MarginLeft = 20;
gv.Series.Add (new ScatterSeries {
Points = { new PointF (1, 1), new PointF (5, 0) }
});
gv.Redraw (gv.Bounds);
var expected =
@"
";
GraphViewTests.AssertDriverContentsAre (expected, output);
// Shutdown must be called to safely clean up Application if Init has been called
Application.Shutdown ();
}
[Fact]
public void PathAnnotation_Diamond ()
{