private GraphView GetGraph(out FakeBarSeries series, out FakeHAxis axisX, out FakeVAxis axisY) { GraphViewTests.InitFakeDriver(); var gv = new GraphView(); gv.ColorScheme = new ColorScheme(); // y axis goes from 0.1 to 1 across 10 console rows // x axis goes from 0 to 10 across 20 console columns gv.Bounds = new Rect(0, 0, 20, 10); gv.CellSize = new PointF(0.5f, 0.1f); gv.Series.Add(series = new FakeBarSeries()); // don't show axis labels that means any labels // that appaer are explicitly from the bars gv.AxisX = axisX = new FakeHAxis() { Increment = 0 }; gv.AxisY = axisY = new FakeVAxis() { Increment = 0 }; return(gv); }
private TableView SetUpMiniTable() { var tv = new TableView(); tv.Bounds = new Rect(0, 0, 10, 4); var dt = new DataTable(); var colA = dt.Columns.Add("A"); var colB = dt.Columns.Add("B"); dt.Rows.Add(1, 2); tv.Table = dt; tv.Style.GetOrCreateColumnStyle(colA).MinWidth = 1; tv.Style.GetOrCreateColumnStyle(colA).MinWidth = 1; tv.Style.GetOrCreateColumnStyle(colB).MaxWidth = 1; tv.Style.GetOrCreateColumnStyle(colB).MaxWidth = 1; GraphViewTests.InitFakeDriver(); tv.ColorScheme = new ColorScheme() { Normal = Application.Driver.MakeAttribute(Color.White, Color.Black), HotFocus = Application.Driver.MakeAttribute(Color.White, Color.Black) }; return(tv); }
/// <summary> /// Returns a basic very small graph (10 x 5) /// </summary> /// <returns></returns> public static GraphView GetGraph() { GraphViewTests.InitFakeDriver(); var gv = new GraphView(); gv.ColorScheme = new ColorScheme(); gv.MarginBottom = 1; gv.MarginLeft = 1; gv.Bounds = new Rect(0, 0, 10, 5); return(gv); }
private GraphView GetGraph(out FakeHAxis axisX, out FakeVAxis axisY) { GraphViewTests.InitFakeDriver(); var gv = new GraphView(); gv.ColorScheme = new ColorScheme(); gv.Bounds = new Rect(0, 0, 50, 30); // graph can't be completely empty or it won't draw gv.Series.Add(new ScatterSeries()); axisX = new FakeHAxis(); axisY = new FakeVAxis(); gv.AxisX = axisX; gv.AxisY = axisY; return(gv); }
public void Series_GetsPassedCorrectBounds_AllAtOnce_LargeCellSize() { GraphViewTests.InitFakeDriver(); var gv = new GraphView(); gv.ColorScheme = new ColorScheme(); gv.Bounds = new Rect(0, 0, 50, 30); // the larger the cell size the more condensed (smaller) the graph space is gv.CellSize = new PointF(2, 5); RectangleF fullGraphBounds = RectangleF.Empty; Rect graphScreenBounds = Rect.Empty; var series = new FakeSeries((v, s, g) => { graphScreenBounds = s; fullGraphBounds = g; }); gv.Series.Add(series); gv.Redraw(gv.Bounds); // Since each cell of the console is 2x5 of graph space the graph // bounds to be rendered are larger Assert.Equal(new RectangleF(0, 0, 100, 150), fullGraphBounds); Assert.Equal(new Rect(0, 0, 50, 30), graphScreenBounds); // Graph should not spill into the margins gv.MarginBottom = 2; gv.MarginLeft = 5; // Even with a margin the graph should be drawn from // the origin, we just get less visible width/height gv.Redraw(gv.Bounds); Assert.Equal(new RectangleF(0, 0, 90, 140), fullGraphBounds); // The screen space the graph will be rendered into should // not overspill the margins Assert.Equal(new Rect(5, 0, 45, 28), graphScreenBounds); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown(); }
public void Series_GetsPassedCorrectBounds_AllAtOnce() { GraphViewTests.InitFakeDriver(); var gv = new GraphView(); gv.ColorScheme = new ColorScheme(); gv.Bounds = new Rect(0, 0, 50, 30); RectangleF fullGraphBounds = RectangleF.Empty; Rect graphScreenBounds = Rect.Empty; var series = new FakeSeries((v, s, g) => { graphScreenBounds = s; fullGraphBounds = g; }); gv.Series.Add(series); gv.Redraw(gv.Bounds); Assert.Equal(new RectangleF(0, 0, 50, 30), fullGraphBounds); Assert.Equal(new Rect(0, 0, 50, 30), graphScreenBounds); // Now we put a margin in // Graph should not spill into the margins gv.MarginBottom = 2; gv.MarginLeft = 5; // Even with a margin the graph should be drawn from // the origin, we just get less visible width/height gv.Redraw(gv.Bounds); Assert.Equal(new RectangleF(0, 0, 45, 28), fullGraphBounds); // The screen space the graph will be rendered into should // not overspill the margins Assert.Equal(new Rect(5, 0, 45, 28), graphScreenBounds); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown(); }
public void ScrollRight_WithoutSmoothScrolling() { GraphViewTests.InitFakeDriver(); var tableView = new TableView(); tableView.ColorScheme = Colors.TopLevel; // 3 columns are visibile tableView.Bounds = new Rect(0, 0, 7, 5); tableView.Style.ShowHorizontalHeaderUnderline = false; tableView.Style.ShowHorizontalHeaderOverline = false; tableView.Style.AlwaysShowHeaders = true; tableView.Style.SmoothHorizontalScrolling = false; var dt = new DataTable(); dt.Columns.Add("A"); dt.Columns.Add("B"); dt.Columns.Add("C"); dt.Columns.Add("D"); dt.Columns.Add("E"); dt.Columns.Add("F"); dt.Rows.Add(1, 2, 3, 4, 5, 6); tableView.Table = dt; // select last visible column tableView.SelectedColumn = 2; // column C tableView.Redraw(tableView.Bounds); string expected = @" │A│B│C│ │1│2│3│"; GraphViewTests.AssertDriverContentsAre(expected, output); // Scroll right tableView.ProcessKey(new KeyEvent() { Key = Key.CursorRight }); tableView.Redraw(tableView.Bounds); // notice that without smooth scrolling we just update the first column // rendered in the table to the newly exposed column (D). This is fast // since we don't have to worry about repeatedly measuring the content // area as we scroll until the new column (D) is exposed. But it makes // the view 'jump' to expose all new columns expected = @" │D│E│F│ │4│5│6│"; GraphViewTests.AssertDriverContentsAre(expected, output); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown(); }
public void ScrollRight_SmoothScrolling() { GraphViewTests.InitFakeDriver(); var tableView = new TableView(); tableView.ColorScheme = Colors.TopLevel; // 3 columns are visibile tableView.Bounds = new Rect(0, 0, 7, 5); tableView.Style.ShowHorizontalHeaderUnderline = false; tableView.Style.ShowHorizontalHeaderOverline = false; tableView.Style.AlwaysShowHeaders = true; tableView.Style.SmoothHorizontalScrolling = true; var dt = new DataTable(); dt.Columns.Add("A"); dt.Columns.Add("B"); dt.Columns.Add("C"); dt.Columns.Add("D"); dt.Columns.Add("E"); dt.Columns.Add("F"); dt.Rows.Add(1, 2, 3, 4, 5, 6); tableView.Table = dt; // select last visible column tableView.SelectedColumn = 2; // column C tableView.Redraw(tableView.Bounds); string expected = @" │A│B│C│ │1│2│3│"; GraphViewTests.AssertDriverContentsAre(expected, output); // Scroll right tableView.ProcessKey(new KeyEvent() { Key = Key.CursorRight }); tableView.Redraw(tableView.Bounds); // Note that with SmoothHorizontalScrolling only a single new column // is exposed when scrolling right. This is not always the case though // sometimes if the leftmost column is long (i.e. A is a long column) // then when A is pushed off the screen multiple new columns could be exposed // (not just D but also E and F). This is because TableView never shows // 'half cells' or scrolls by console unit (scrolling is done by table row/column increments). expected = @" │B│C│D│ │2│3│4│"; GraphViewTests.AssertDriverContentsAre(expected, output); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown(); }
public void TestRendering_MultibarSeries() { GraphViewTests.InitFakeDriver(); var gv = new GraphView(); gv.ColorScheme = new ColorScheme(); // y axis goes from 0.1 to 1 across 10 console rows // x axis goes from 0 to 20 across 20 console columns gv.Bounds = new Rect(0, 0, 20, 10); gv.CellSize = new PointF(1f, 0.1f); gv.MarginBottom = 1; gv.MarginLeft = 1; var multibarSeries = new MultiBarSeries(2, 4, 1); //nudge them left to avoid float rounding errors at the boundaries of cells foreach (var sub in multibarSeries.SubSeries) { sub.Offset -= 0.001f; } gv.Series.Add(multibarSeries); FakeHAxis fakeXAxis; // don't show axis labels that means any labels // that appaer are explicitly from the bars gv.AxisX = fakeXAxis = new FakeHAxis() { Increment = 0 }; gv.AxisY = new FakeVAxis() { Increment = 0 }; gv.Redraw(gv.Bounds); // Since bar series has no bars yet no labels should be displayed Assert.Empty(fakeXAxis.LabelPoints); multibarSeries.AddBars("hey", 'M', 0.5001f, 0.5001f); fakeXAxis.LabelPoints.Clear(); gv.Redraw(gv.Bounds); Assert.Equal(4, fakeXAxis.LabelPoints.Single()); multibarSeries.AddBars("there", 'M', 0.24999f, 0.74999f); multibarSeries.AddBars("bob", 'M', 1, 2); fakeXAxis.LabelPoints.Clear(); gv.Redraw(gv.Bounds); Assert.Equal(3, fakeXAxis.LabelPoints.Count); Assert.Equal(4, fakeXAxis.LabelPoints[0]); Assert.Equal(8, fakeXAxis.LabelPoints[1]); Assert.Equal(12, fakeXAxis.LabelPoints [2]); string looksLike = @" │ MM │ M MM │ M MM │ MM M MM │ MM M MM │ MM M MM │ MM MM MM │ MM MM MM ┼──┬M──┬M──┬M────── heytherebob "; GraphViewTests.AssertDriverContentsAre(looksLike); }
public void ScrollIndicators() { GraphViewTests.InitFakeDriver(); var tableView = new TableView(); tableView.ColorScheme = Colors.TopLevel; // 3 columns are visibile tableView.Bounds = new Rect(0, 0, 7, 5); tableView.Style.ShowHorizontalHeaderUnderline = true; tableView.Style.ShowHorizontalHeaderOverline = false; tableView.Style.AlwaysShowHeaders = true; tableView.Style.SmoothHorizontalScrolling = true; var dt = new DataTable(); dt.Columns.Add("A"); dt.Columns.Add("B"); dt.Columns.Add("C"); dt.Columns.Add("D"); dt.Columns.Add("E"); dt.Columns.Add("F"); dt.Rows.Add(1, 2, 3, 4, 5, 6); tableView.Table = dt; // select last visible column tableView.SelectedColumn = 2; // column C tableView.Redraw(tableView.Bounds); // user can only scroll right so sees right indicator // Because first column in table is A string expected = @" │A│B│C│ ├─┼─┼─► │1│2│3│"; GraphViewTests.AssertDriverContentsAre(expected, output); // Scroll right tableView.ProcessKey(new KeyEvent() { Key = Key.CursorRight }); // since A is now pushed off screen we get indicator showing // that user can scroll left to see first column tableView.Redraw(tableView.Bounds); expected = @" │B│C│D│ ◄─┼─┼─► │2│3│4│"; GraphViewTests.AssertDriverContentsAre(expected, output); // Scroll right twice more (to end of columns) tableView.ProcessKey(new KeyEvent() { Key = Key.CursorRight }); tableView.ProcessKey(new KeyEvent() { Key = Key.CursorRight }); tableView.Redraw(tableView.Bounds); expected = @" │D│E│F│ ◄─┼─┼─┤ │4│5│6│"; GraphViewTests.AssertDriverContentsAre(expected, output); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown(); }
public void LongColumnTest() { GraphViewTests.InitFakeDriver(); var tableView = new TableView(); tableView.ColorScheme = Colors.TopLevel; // 25 characters can be printed into table tableView.Bounds = new Rect(0, 0, 25, 5); tableView.Style.ShowHorizontalHeaderUnderline = true; tableView.Style.ShowHorizontalHeaderOverline = false; tableView.Style.AlwaysShowHeaders = true; tableView.Style.SmoothHorizontalScrolling = true; var dt = new DataTable(); dt.Columns.Add("A"); dt.Columns.Add("B"); dt.Columns.Add("Very Long Column"); dt.Rows.Add(1, 2, new string('a', 500)); dt.Rows.Add(1, 2, "aaa"); tableView.Table = dt; tableView.Redraw(tableView.Bounds); // default behaviour of TableView is not to render // columns unless there is sufficient space string expected = @" │A│B │ ├─┼─────────────────────► │1│2 │ │1│2 │ "; GraphViewTests.AssertDriverContentsAre(expected, output); // get a style for the long column var style = tableView.Style.GetOrCreateColumnStyle(dt.Columns[2]); // one way the API user can fix this for long columns // is to specify a max width for the column style.MaxWidth = 10; tableView.Redraw(tableView.Bounds); expected = @" │A│B│Very Long │ ├─┼─┼───────────────────┤ │1│2│aaaaaaaaaa │ │1│2│aaa │ "; GraphViewTests.AssertDriverContentsAre(expected, output); // revert the style change style.MaxWidth = TableView.DefaultMaxCellWidth; // another way API user can fix problem is to implement // RepresentationGetter and apply max length there style.RepresentationGetter = (s) => { return(s.ToString().Length < 15 ? s.ToString() : s.ToString().Substring(0, 13) + "..."); }; tableView.Redraw(tableView.Bounds); expected = @" │A│B│Very Long Column │ ├─┼─┼───────────────────┤ │1│2│aaaaaaaaaaaaa... │ │1│2│aaa │ "; GraphViewTests.AssertDriverContentsAre(expected, output); // revert style change style.RepresentationGetter = null; // Both of the above methods rely on having a fixed // size limit for the column. These are awkward if a // table is resizeable e.g. Dim.Fill(). Ideally we want // to render in any space available and truncate the content // of the column dynamically so it fills the free space at // the end of the table. // We can now specify that the column can be any length // (Up to MaxWidth) but the renderer can accept using // less space down to this limit style.MinAcceptableWidth = 5; tableView.Redraw(tableView.Bounds); expected = @" │A│B│Very Long Column │ ├─┼─┼───────────────────┤ │1│2│aaaaaaaaaaaaaaaaaaa│ │1│2│aaa │ "; GraphViewTests.AssertDriverContentsAre(expected, output); // Now test making the width too small for the MinAcceptableWidth // the Column won't fit so should not be rendered Application.Shutdown(); GraphViewTests.InitFakeDriver(); tableView.Bounds = new Rect(0, 0, 9, 5); tableView.Redraw(tableView.Bounds); expected = @" │A│B │ ├─┼─────► │1│2 │ │1│2 │ "; GraphViewTests.AssertDriverContentsAre(expected, output); // setting width to 10 leaves just enough space for the column to // meet MinAcceptableWidth of 5. Column width includes terminator line // symbol (e.g. ┤ or │) tableView.Bounds = new Rect(0, 0, 10, 5); tableView.Redraw(tableView.Bounds); expected = @" │A│B│Very│ ├─┼─┼────┤ │1│2│aaaa│ │1│2│aaa │ "; GraphViewTests.AssertDriverContentsAre(expected, output); Application.Shutdown(); }