community,
this is my first question here. to all the other problems i had there was often a answer on this side. for this i did not find one. here is my problem:
i have a chart and i want to add a vertical starpline at the point i click the mouse on the chart. this i working so far with that code:
chartSettlingCurve.ChartAreas[0].CursorX.SetCursorPixelPosition(new Point(e.X, e.Y), true);
double pX = chartSettlingCurve.ChartAreas[0].CursorX.Position; //X Axis coordinate Mouse
DataPoint dataPoint = chartSettlingCurve.Series[0].Points.FindByValue(nearestPreceedingValue(nearestPreceedingValue(pX)), "X");
labelTab3Test.Text = Convert.ToString(dataPoint);
DataPoint maxValuePoint = chartSettlingCurve.Series[0].Points.FindMaxByValue();
StripLine stripLineEnd = new StripLine();
stripLineEnd.BorderColor = Color.Blue;
stripLineEnd.IntervalOffset = dataPoint.XValue;
stripLineEnd.Text = "End";
this code generates a stripline at every point i click on the graph but i want just one line. so if ther still is a strip line it shopud be replaced by the new one at a other position.
woud be nice if you can help me. if you dont get my problem pleas ask.
thanks
a working solution is:
for (int j = 0; j < chartSettlingCurve.ChartAreas[0].AxisX.StripLines.Count; j++)
{
if (chartSettlingCurve.ChartAreas[0].AxisX.StripLines[j].Tag.ToString() == "end")
{
chartSettlingCurve.ChartAreas[0].AxisX.StripLines.RemoveAt(j);
j--;
}
}
or as an alternative:
bool loop = true;
while (loop)
{
loop = false;
foreach (var element in chartSettlingCurve.ChartAreas[0].AxisX.StripLines)
{
if (element.Tag.ToString() == "end")
{
chartSettlingCurve.ChartAreas[0].AxisX.StripLines.Remove(element);
loop = true;
break;
}
}
}
You can remove all striplines using code below;
while (chartSettlingCurve.ChartAreas[0].AxisX.StripLines.Count > 0)
{
chartSettlingCurve.ChartAreas[0].AxisX.StripLines.Remove(hartSettlingCurve.ChartAreas[0].AxisX.StripLines.Last());
}
than you can add some code.
Related
I'm working on a program in windows forms that generate random coordinate points to draw fish. I need the fish to stop intersecting with each other but the code I wrote doesn't work. The coordinates generated should be put into rectangles and then checked against all the other points rectangles. The fish keep intersecting. Any idea why?
Code I wrote to stop the intersection.
for (int i = 0; i < fishNumber; i++)
{
// Checks for overlapping
fishX = x.Next(200, 3100);
fishY = y.Next(100, 1620);
fishPoints.Add(new Point(fishX, fishY));
for (int j = 0; j < i; j++)
{
while (i != 0 && new Rectangle(fishPoints[i], new Size(200, 134)).IntersectsWith(new Rectangle(fishPoints[j], new Size(200, 134))))
{
fishPoints.RemoveAt(i);
fishX = x.Next(200, 3100);
fishY = y.Next(100, 1620);
fishPoints.Add(new Point(fishX, fishY));
}
}
}
Try something more like the below out. It only adds the point AFTER it has been determined that it doesn't intersect with any of the other fish:
Size fishSize = new Size(200, 134);
for (int i = 0; i < fishNumber;i++)
{
Point pt;
bool collided;
do
{
collided = false;
pt = new Point(x.Next(200, 3100), y.Next(100, 1620));
Rectangle rcNewFish = new Rectangle(pt, fishSize);
foreach(Point otherPt in fishPoints)
{
if (rcNewFish.IntersectsWith(new Rectangle(otherPt, fishSize)))
{
collided = true;
break;
}
}
} while (collided);
fishPoints.Add(pt);
}
By using ColorBand tool I am scoping the axis to chart, so separate chart area is assigned to that axis and signal, but when cursor is enabled then cursor is not visible for whole chart(refer attached image) and axis titles are overlapped with each other(refer attached image).
Dictionary<int, AxisScope> list = new Dictionary<int, AxisScope>();
foreach (AxisScope axis in this.Chart.Axes.Custom)
{
axis.Visible = axis.Scope;
totalWeight += axis.Weight;
while (list.Keys.Contains(axis.Ordinal))
axis.ordinal++;
list.Add(axis.Ordinal, axis);
}
int ord = 0;
double start = 0;
int pos = 0;
int[] array = list.Keys.ToArray();
Array.Sort(array);
foreach (int i in array)
{
AxisScope scope = list[i];
scope.Ordinal = ord++;
if (scope.Scope && scope.Weight > 0)
{
if (scope.AxisColorBackground == null)
scope.AxisColorBackground = new ColorBand(this.Chart);
this.Chart.Tools.Add(scope.AxisColorBackground);
scope.AxisColorBackground.Axis = scope;
Color pen = Color.DarkRed;
Color back = Color.FromArgb(253, 253, 233);
if ((pos++ % 2) == 0)
{
pen = Color.DarkBlue;
back = Color.FromArgb(233, 253, 253);
}
scope.StartPosition = start;
start += (scope.Weight / totalWeight) * 100;
scope.EndPosition = start;
scope.AxisPen.Color = pen;
scope.AxisColorBackground.Pen.Color = back;
scope.AxisColorBackground.Brush.Color = back;
scope.AxisColorBackground.Brush.Transparency = 33;
scope.AxisColorBackground.Transparency = 33;
scope.AxisColorBackground.Start = double.MinValue;// scope.Minimum;
scope.AxisColorBackground.End = double.MaxValue;// scope.Maximum;
scope.AxisColorBackground.ResizeEnd = false;
scope.AxisColorBackground.ResizeStart = false;
scope.AxisColorBackground.Tag = "Axis -" + scope.Title.ToString();
scope.AxisColorBackground.Active = true;
}
else if (scope.Scope && scope.Weight == 0)
{
scope.Visible = false;
}
}
Could you please produce a Minimal, Reproducible Example I could run here to immediately reproduce your problem? If you feel your code is too long to post here, maybe you could consider zipping up your Visual Studio project and posting it to Steema's upload page.
i am trying to do scroll and mousewheel, and dragging in a panel with textboxes in it. I have to let some of the textboxes with fixed position, but doing this, i have some problem with pixels, while Wheeling or dragging or scrolling. I do not know if there is some sort of way of doing this without this problem. If anyone know an answer and he/she are willing to help, please, feel free.
I will put the code i use for this:
This code is Inside a function that is called from Dynamics NAV and will create the operations:
#region PROPRIETES DU PANEL
pnOperation.Name = idOperationL.ToString();
pnOperation.BorderStyle = BorderStyle.FixedSingle;
pnOperation.BackColor = Color.LightGray;
pnOperation.Size = new Size(220, 40);
pnOperation.Top = posOperationL * 40;
pnOperation.AllowDrop = true;
if (nRolesG > 6)
{
//I fixed the operation here so they will stay at position 0
pnOperation.Top = posOperationL * 40;
pnOperation.Left = 0;
MainPanel.MouseWheel += (senderL, eL) =>
{
pnOperation.Left = 0;
pnOperation.Invalidate();
};
MainPanel.Scroll += (senderL, eL) =>
{
pnOperation.Left = 0;
pnOperation.Invalidate();
};
}
#endregion
Screenshot
Screenshot
Thanks in advance
This code is just changing location, not sliding.
I am using this at the moment:
for (int i = 740; i == 740; i++)
{
panel2.Location = new Point(panel2.Location.X - i, panel2.Location.Y);
}
How can I slide the panel slowly?
Now, as I stated in my comment you really need to use float values, so you really need to draw it. However, the current implementation only makes a single iteration. The current loop could have been translated into this:
panel2.Location = new Point(panel2.Location.X - 740, panel2.Location.Y);
Consider a loop like this to slide it out:
for (int i = -(panel2.Width); i < 0; i++)
{
panel2.Location = new Point(i, panel2.Location.Y);
}
That algorithm is assuming that you've set the Location to the - of it's width (e.g. -740x) so that it's simply not visible on the screen. The reverse would hide it.
This will still be a little choppy, but it won't just hide it like your current code.
If you are just going to slide the panel try to do this
Try this code:
Panel panelArray = new Panel[];
Panel panel2 = panelArray[0];
for (int i = 0; i <= 100; i++)
{
panel2.Location = new Point(panel2.Location.X - i, panel2.Location.Y);
System.Threading.Thread.Sleep(10);
}
I have a charting application that has an overlay function which reassigns the 'from' chart series to the 'to' chart using this code :
chTo.Series.Add(chFrom.Series[s]); //Reassign series to new chart
chTo.Legends.Add(chFrom.Legends[s]); //Reassign legend to new chart
Works great. However, I am trying to implement tooltips for the legends and am running into an issue where only the first legend in the chart will show tooltips. When I do a hittest only the first legend is recognized. All subsequent legends, while visible on the chart, aren't 'seen' to the hittest method. I'm thinking this is why the tooltips aren't showing as there is no object to trigger the mouseover event for the tooltip.
I have been unable to find a way to 'expand' the legend area (as detected by the hittest method) to make this work.
Does anyone have any ideas? Thanks!
Responding to King King --
The original legend is created in the same method as the chart thus:
//Create the series legend
chartSel.Series[ySeries.Name].ChartArea = "ChartArea1";
chartSel.Legends.Remove(chartSel.Legends.FindByName("Legend1"));
chartSel.Legends.Add(ySeries.Name);
chartSel.Legends[0].Name = ySeries.Name;
//Format the series legend
chartSel.Legends[ySeries.Name].Docking = Docking.Right;
chartSel.Legends[ySeries.Name].DockedToChartArea = "ChartArea1";
chartSel.Legends[ySeries.Name].Alignment = StringAlignment.Near;
chartSel.Legends[ySeries.Name].IsDockedInsideChartArea = false;
chartSel.Legends[ySeries.Name].LegendStyle = LegendStyle.Table; //.Row;
chartSel.Legends[ySeries.Name].TableStyle = LegendTableStyle.Tall;
chartSel.Legends[ySeries.Name].IsEquallySpacedItems = false;
chartSel.Legends[ySeries.Name].Font = new Font("Segoe UI", 7, FontStyle.Bold);
//chartSel.Legends[ySeries.Name].TextWrapThreshold = 17; // 19;
chartSel.Legends[ySeries.Name].Position.Auto = false;
chartSel.Legends[ySeries.Name].Position.X = 80;
chartSel.Legends[ySeries.Name].Position.Y = 2;
chartSel.Legends[ySeries.Name].Position.Width = 18;
chartSel.Legends[ySeries.Name].Position.Height = 12;
//Format series data point value cell
chartSel.Legends[ySeries.Name].CellColumns.Add(new LegendCellColumn("", LegendCellColumnType.Text, ""));
chartSel.Legends[ySeries.Name].CellColumns[0].Alignment = ContentAlignment.MiddleLeft; //.TopLeft;
chartSel.Legends[ySeries.Name].CellColumns[0].Margins = new System.Windows.Forms.DataVisualization.Charting.Margins(10, 10, 1, 1);
chartSel.Legends[ySeries.Name].CellColumns[0].MinimumWidth = 500;
chartSel.Legends[ySeries.Name].CellColumns[0].MaximumWidth = 500;
chartSel.Legends[ySeries.Name].CellColumns[0].BackColor = Color.FromArgb(120, chartSel.Series[ySeries.Name].Color);
//Format legend cell spacer
chartSel.Legends[ySeries.Name].CellColumns.Add(new LegendCellColumn("", LegendCellColumnType.Text, ""));
chartSel.Legends[ySeries.Name].CellColumns[1].Alignment = ContentAlignment.TopLeft;
chartSel.Legends[ySeries.Name].CellColumns[1].Margins = new System.Windows.Forms.DataVisualization.Charting.Margins(0, 0, 0, 0);
chartSel.Legends[ySeries.Name].CellColumns[1].MinimumWidth = 25;
chartSel.Legends[ySeries.Name].CellColumns[1].MaximumWidth = 25;
chartSel.Legends[ySeries.Name].CellColumns[1].BackColor = Color.Black;
//Format series title cell
chartSel.Legends[ySeries.Name].CellColumns.Add(new LegendCellColumn("", LegendCellColumnType.Text, ySeries.Name));
chartSel.Legends[ySeries.Name].CellColumns[2].Alignment = ContentAlignment.MiddleLeft;
chartSel.Legends[ySeries.Name].CellColumns[2].Margins = new System.Windows.Forms.DataVisualization.Charting.Margins(0, 0, 1, 1);
chartSel.Legends[ySeries.Name].CellColumns[2].MinimumWidth = 1475; //1500;
chartSel.Legends[ySeries.Name].CellColumns[2].MaximumWidth = 1475; //1500;
chartSel.Legends[ySeries.Name].CellColumns[2].ToolTip = ySeries.Name;
After the series and legends have been reassigned (using the code in my original post) I then set the legend values based on the cursor position located by the following hittest in response to a mouse-down event:
pt = activePanel.PointToClient(Control.MousePosition);
ch = activePanel.GetChildAtPoint(pt) as Chart;
if (ch != null)
{
HitTestResult ht = ch.HitTest(e.X, e.Y, false);
if (ht.ChartElementType == ChartElementType.PlottingArea)
{
SetLegendValueText(ht, ch);
}
}
private void SetLegendValueText(HitTestResult ht, Chart ch)
{
//Get the datapoint 'x' index value
int dpIndex = 0;
if (ht != null)
{
switch (ht.ChartElementType)
{
case ChartElementType.DataPoint: //Cursor is on a series line
DataPoint dp = ht.Object as DataPoint;
if (dp != null)
{
dpIndex = ht.PointIndex;
}
break;
case ChartElementType.PlottingArea: //Cursor is somewhere in the plot area of the chart
dpIndex = (int)ht.ChartArea.CursorX.Position;
break;
}
}
//Set legend value and legend tooltip
for (int x = 0; x < ch.Legends.Count; x++) //foreach (Series s in ch.Series)
{
if (dpIndex > 0)
{
ch.Legends[x].Name = "Legend_" + x;
ch.Legends[x].CellColumns[0].Text = ch.Series[x].Points[dpIndex - 1].YValues[0].ToString();
ch.Legends[x].CellColumns[0].ToolTip = ch.Legends[x].CellColumns[0].Text;
}
}
}
So, I end up with the legends looking the way I want them, but the tooltips only show for the first legend item. I've tried to do custom items as well. With them I get the tooltips, but I lose the formatting. This has been driving me crazy for weeks (off and on) and I would really like to move on to other issues. Clearly (to me anyway), I am not doing something right simply because I don't know everything there is to know about the charts, and the MSChart Samples are of very limited benefit.
I'd be most grateful if I could be pointed in the right direction.