Scrollbar moving to right instead of left - c#

I have made a chart which dynamically draw a spike when data received.
In this chart I have made a scrollbar, so only 20 datapoints get shown at on time.
public void Chart()
{
ChartArea mov = SleepMovChar.ChartAreas["Movement"];
mov.AxisX.ScrollBar.Size = 12;
mov.AxisX.ScrollBar.ButtonStyle = ScrollBarButtonStyles.SmallScroll;
mov.AxisX.ScrollBar.ButtonStyle = ScrollBarButtonStyles.All ^ ScrollBarButtonStyles.ResetZoom;
mov.AxisX.ScrollBar.IsPositionedInside = true;
mov.AxisX.ScrollBar.Enabled = true;
mov.AxisX.ScaleView.Size = 20;
}
My problem is, that I want that scrollbar to move to right when data received. At the time now, it moves to left, so the first data is shown. I just want that the latest data is shown instead, so that the scrollbar follows the data receive.

If you want the visible area to follow the new data like in an oscilloscope, you can set the scroll position :
Series S1 = SleepMovChar.Series["yourSeriesByNameOrNumber"];
mov.AxisX.ScaleView.Position = S1.Points.Count - mov.AxisX.ScaleView.Size;
You will need to repeat this whenever you have added data points..

Related

PointToScreen not returning screen coordinates

I am using EyeShot 12. I am creating a rectangle using EyeShot Line Entity, it has 2 dimensions along length and breadth.
My functionality involves changing the Dimension Text by using the action->SelectByPick, then picking anyone of the dimension and changing its value by bringing up a TextBox so that user can add the value. Here the TextBox pops-up on the location of mouse pointer.
Going further I click on Tab (keypad button) to switch to next dimension and also making sure that particular Dimension gets highlighted. But my concern is I am unable to locate the TextBox next to that highlighted dimension.
I am able to locate the position of existing Line(corresponding to the selected dimension) in Eyeshot coordinates but TextBox requires screen coordinates value for Positioning it exactly.
So I am using control.PointToScreen to convert eyeshot coordinates into screen but it return a Point which is same as to the Eyeshot coordinates.
code:
foreach (Entity ent in model1.Entities)
{
if (ent.Selected)
{
Line lin = (Line)ent;
Point3D midpt = lin.MidPoint;
string newpt1X = midpt.X.ToString();
string newpt1Y = midpt.Y.ToString();
System.Drawing.Point startPtX = model1.PointToScreen(new
System.Drawing.Point(int.Parse(newpt1X) + 20, int.Parse(newpt1Y) + 20));
TextBox tb = new TextBox();
tb.Text = "some text";
tb.Width = 50;
tb.Location = startPtX;
model1.Controls.Add(tb);
}
I looked for other results but everyone triggers to PointToScreen to get this convertion.
Hoping somebody can point what I am doing.
Thanks in advance
Suraj
You made your object (TextBox) a child of the ViewportLayout therefore you need the point relative to it. But the controls are not in the world coordinate but screen coordinate based on their parent.
What you actually need is two (2) conversion.
// first grab the entity point you want
// this is a world point in 3D. I used your line entity
// of your loop here
var entityPoint = ((Line)ent).MidPoint;
// now use your Viewport to transform the world point to a screen point
// this screen point is actually a point on your real physical monitor(s)
// so it is very generic, it need further conversion to be local to the control
var screenPoint = model1.WorldToScreen(entityPoint);
// now create a window 2d point
var window2Dpoint = new System.Drawing.Point(screenPoint.X, screenPoint.Y);
// now the point is on the complete screen but you want to know
// relative to your viewport where that is window-wise
var pointLocalToViewport = model1.PointToClient(window2Dpoint);
// now you can setup the textbox position with this point as it's local
// in X, Y relative to the model control.
tb.Left = pointLocalToViewport.X;
tb.Top = pointLocalToViewport.Y;
// then you can add the textbox to the model1.Controls

Chart series are not shown until clicking on scrollbar

Here is my init method for the chart in my C# program.
private void initGraph()
{
chartTrend.Cursor = Cursors.Hand;
chartTrend.ChartAreas[0].CursorX.LineColor = Color.Red;
chartTrend.ChartAreas[0].CursorX.LineWidth = 2;
chartTrend.ChartAreas[0].CursorX.LineDashStyle = ChartDashStyle.Dot;
chartTrend.ChartAreas[0].CursorX.IsUserEnabled = true;
// let us select a portion of chart so then zoom that portion
chartTrend.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
chartTrend.ChartAreas[0].CursorX.Interval =1 ;
chartTrend.ChartAreas[0].CursorX.IntervalType = DateTimeIntervalType.Seconds;
chartTrend.ChartAreas[0].CursorX.AutoScroll = false;
chartTrend.ChartAreas[0].AxisY.IsStartedFromZero = true;
chartTrend.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
chartTrend.ChartAreas[0].AxisY.ScaleView.Zoomable = false;
// disable zoom-reset button (only scrollbar's arrows are available)
chartTrend.ChartAreas[0].AxisX.ScrollBar.ButtonStyle = ScrollBarButtonStyles.SmallScroll;
chartTrend.ChartAreas[0].AxisX.ScrollBar.IsPositionedInside = true;
chartTrend.ChartAreas[0].AxisX.ScrollBar.Enabled = true;
chartTrend.ChartAreas[0].AxisX.ScaleView.SizeType = DateTimeIntervalType.Seconds;
chartTrend.ChartAreas[0].AxisX.ScaleView.Size = 528;
}
The problem is that, when I add data to the chart, It will not be shown until I click on the scroll. I even tried to move the scroll by software but it didn't work. what can I do?
By the way, it is all for the last line of initGraph() method. when I comment it out, data will be shown, but in the way that I'm not interested.
The problem was the position of scroll. I understood that when I added data to the chart, It was depicting chart from a time which was far away from the start of my time range and after clicking on the scroll, it took it to the proper time. So I decided to move the scroll after adding my first points and finally, the problem solved by this line:
chartTrend.ChartAreas[0].AxisX.ScaleView.Position = chartTrend.ChartAreas[0].AxisX.Minimum;

Silverlight Event Handlers Respond Extremely Slow

I am creating a dynamic hexgrid, 8 columns of 10 hexes, with an ellipse centered in random hexes.
I had originally thought the event handlers were not loading. It now appears they are loading, but are reacting very slowly. As I mouse over the generated grid after a minute or two, the hexes start randomly filling and the tooltips start showing (but not until the event handler for that hex responds). It actually takes several minutes for the last hex to respond to the mouseover event.
private void CreateHexGrid(int columns, int rows, double length)
{
//I create a jagged array of points,
//hexpoint[# of columns, # of rows, 6 points]
//the base (0,0) hex is generated point by point
//mathematically based on the length of one side
//then each subsequent hex is mathematically
//created based on the points of the previous hex.
//Finally, I instantiate each Polygon hex and fill
//its points collection using the array.
PointCollection points = new PointCollection();
SolidColorBrush blackBrush = new SolidColorBrush(Colors.Black);
SolidColorBrush clearBrush = new SolidColorBrush(Colors.Transparent);
Polygon hex = new Polygon();
hex.Stroke = blackBrush;
hex.StrokeThickness = 1;
hex.Name = "Hex" + column.ToString() + row.ToString();
for (int point = 0; point < 6; point++)
{
points.Add(HexPoint[column, row, point]);
}
hex.Points = points;
ToolTipService.SetToolTip(hex, hex.Name);
hex.MouseEnter += new MouseEventHandler(hex_MouseEnter);
cnvsHexGrid.Children.Add(hex);
//....
}
Currently I have the handler simply trying to change the fill color of the polygon/ellipse to test. I would eventually like to generate an interactive pop-up window if a hex is clicked on.
void hex_MouseEnter(object sender, MouseEventArgs e)
{
var hex = sender as Polygon;
SolidColorBrush blueFill = new SolidColorBrush(Colors.Blue);
hex.Fill = blueFill;
}
What am I doing wrong to cause such slow, slow, slow reaction?
Adding a handler in the Load_Main seemed to help clear this up.

Get chart area bounds in C#

Just to explain what I'm doing, I draw two selectors on a chart, and the part that will not be selected should appear under that blue rectangle. The part that will be selected will appear in the white area, between the two selectors. The figure below shows only the left selector.
Now, what I'm trying to do is to draw a rectangle inside a chart that always remain inside the plotting area, even when the windows is resized.
To get the top, left and bottom bounds, to draw the rectangle as shown in the figure below, I do the following:
(...)
int top = (int)(Chart.Height * 0.07);
int bottom = (int)(Chart.Height - 1.83 * top);
int left = (int)(0.083 * Chart.Width);
Brush b = new SolidBrush(Color.FromArgb(128, Color.Blue));
e.Graphics.FillRectangle(b, left, top, marker1.X - left, bottom - top);
(...)
But that's far from perfect, and it isn't drawn in the right place when the window is resized. I want the blue rectangle to always be bound on the top, left and bottom by the plotting area grid. Is that possible?
You probably want to use StripLine to achieve this.
Look into the Stripline Class Documentation.
Also I recommend downloading the Charting Samples which are a great help to understand the various features.
StripLine stripLine = new StripLine();
stripLine.Interval = 0; // Set Strip lines interval to 0 for non periodic stuff
stripLine.StripWidth = 10; // the width of the highlighted area
stripline.IntervalOffset = 2; // the starting X coord of the highlighted area
// pick you color etc ... before adding the stripline to the axis
chart.ChartAreas["Default"].AxisX.StripLines.Add( stripLine );
This assumes you are wanting something that is not what Cursor already does (see CursorX), such as letting the user mark up areas of the plot which provides some persistence. Combining the Cursor events with the striplines above would be a good way to do that.
So to highlight the start and end of the cursor you could do this
// this would most likely be done through the designer
chartArea1.AxisX.ScaleView.Zoomable = false;
chartArea1.CursorX.IsUserEnabled = true;
chartArea1.CursorX.IsUserSelectionEnabled = true;
this.chart1.SelectionRangeChanged += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CursorEventArgs>(this.chart1_SelectionRangeChanged);
...
private void chart1_SelectionRangeChanged(object sender, CursorEventArgs e)
{
chart1.ChartAreas[0].AxisX.StripLines.Clear();
StripLine stripLine1 = new StripLine();
stripLine1.Interval = 0;
stripLine1.StripWidth = chart1.ChartAreas[0].CursorX.SelectionStart - chart1.ChartAreas[0].AxisX.Minimum;
stripLine1.IntervalOffset = chart1.ChartAreas[0].AxisX.Minimum;
// pick you color etc ... before adding the stripline to the axis
stripLine1.BackColor = Color.Blue;
chart1.ChartAreas[0].AxisX.StripLines.Add(stripLine1);
StripLine stripLine2 = new StripLine();
stripLine2.Interval = 0;
stripLine2.StripWidth = chart1.ChartAreas[0].AxisX.Maximum - chart1.ChartAreas[0].CursorX.SelectionEnd;
stripLine2.IntervalOffset = chart1.ChartAreas[0].CursorX.SelectionEnd;
// pick you color etc ... before adding the stripline to the axis
stripLine2.BackColor = Color.Blue;
chart1.ChartAreas[0].AxisX.StripLines.Add(stripLine2);
}
Somehow I suspect you may not have discovered the cursor yet, and doing so will make all this irrelevant. But anyway, the above code will do what you described.

Adding a scroll bar to MS Chart control C#

please understand that I know there are other threads concerning this issue, but my needs are different.
Basically before I seen people saying to implement a scroll bar with MSChart they use the
.Size = ...
or
.View = ...
But, this make a scroll bar automatically apprear, and this scroll bar contains a button that when clicked causes the bar to vanish, making the chart show all data, and no way of bringing back the scroll bar to the chart without restarting the app.
So I ask, please, Is there a way to incorportate a horizontal scroll bar on the X-axis of my Chart? I am needing on so that I can view my chart data on blocks of 100 second blocks.
i.e. 0 - 100, then click sroll bar will bring me to 100 - 200 block.
Thank you in advance guys!!!!! im coding in C# also
Here's an example of what you need:
(to try it, just create a form, add a mschart and call the following method)
private void FillChart()
{
int blockSize = 100;
// generates random data (i.e. 30 * blockSize random numbers)
Random rand = new Random();
var valuesArray = Enumerable.Range(0, blockSize * 30).Select(x => rand.Next(1, 10)).ToArray();
// clear the chart
chart1.Series.Clear();
// fill the chart
var series = chart1.Series.Add("My Series");
series.ChartType = SeriesChartType.Line;
series.XValueType = ChartValueType.Int32;
for (int i = 0; i < valuesArray.Length; i++)
series.Points.AddXY(i, valuesArray[i]);
var chartArea = chart1.ChartAreas[series.ChartArea];
// set view range to [0,max]
chartArea.AxisX.Minimum = 0;
chartArea.AxisX.Maximum = valuesArray.Length;
// enable autoscroll
chartArea.CursorX.AutoScroll = true;
// let's zoom to [0,blockSize] (e.g. [0,100])
chartArea.AxisX.ScaleView.Zoomable = true;
chartArea.AxisX.ScaleView.SizeType = DateTimeIntervalType.Number;
int position = 0;
int size = blockSize;
chartArea.AxisX.ScaleView.Zoom(position, size);
// disable zoom-reset button (only scrollbar's arrows are available)
chartArea.AxisX.ScrollBar.ButtonStyle = ScrollBarButtonStyles.SmallScroll;
// set scrollbar small change to blockSize (e.g. 100)
chartArea.AxisX.ScaleView.SmallScrollSize = blockSize;
}
Snapshot:
I would do it like this:
if (series1.Points.Count > 2 && chartArea1.AxisX.Maximum - chartArea1.AxisX.Minimum > chartArea1.AxisX.ScaleView.Size)
{
chartArea1.AxisX.ScrollBar.Enabled = true;
}
else
{
chartArea1.AxisX.ScrollBar.Enabled = false;
}
So when you added points more than your scaleview - scrollbar is appear
I worked out my own way for that. Hope it helps you:
Add your chart to a Panel.
Set the AutoScroll property of the panel to true with panelName.AutoScroll=true;
Size the chart properly in the panel.
You can now use the panel's scrollbar as if it were the chart's!
If data gets added continuously(e.g. with a timer or so), add this to the timer's tick event:
chartName.Size = new Size(width++, height++); where int width = chartName.Width; and int height = chartName.Height;

Categories

Resources