chart line with multi part [duplicate] - c#

I'm trying to figure out how to draw a discontinued (non-continous) series. This is the code for the series:
Chart.Series["Limit"].Points.AddXY(20000, 30);
Chart.Series["Limit"].Points.AddXY(1000000, 30);
//no plotting wanted here
Chart.Series["Limit"].Points.AddXY(1500000, 40);
Chart.Series["Limit"].Points.AddXY(2500000, 40);
How do I stop it from plotting certain points, like the diagonal line shown in the image below?

You can visually break up a line chart by inserting an invisible DataPoint:
Chart.Series["Limit"].Points.AddXY(20000, 30);
Chart.Series["Limit"].Points.AddXY(1000000, 30);
//no plotting wanted (from previous point to this one) here
int index = Chart.Series["Limit"].Points.AddXY(1500000, 40);
Chart.Series["Limit"].Points[index].Color = Color.Transparent;
Chart.Series["Limit"].Points.AddXY(2500000, 40);
This makes the line that leads to the DataPoint transparent.

I don't know any way to set different lines parameters for the same Series, but you can create two different lines
Chart.Series["Limit"].Points.AddXY(20000, 30);
Chart.Series["Limit"].Points.AddXY(1000000, 30);
Chart.Series["Limit"].BorderColor = Color.Red
//no plotting wanted here
Chart.Series["Limit2"].Points.AddXY(1500000, 40);
Chart.Series["Limit2"].Points.AddXY(2500000, 40);
Chart.Series["Limit2"].BorderColor = Color.Red

Related

iText 7 - Center align text and paragraphs

I'm trying to center align a block of text, however getting inconsistent results. Here is a rough idea of my code:
baseCanvas.ShowTextAligned("Header 1", 555, 839, TextAlignment.CENTER, 0);
baseCanvas.ShowTextAligned("Test test test ...", 240, 809, TextAlignment.CENTER, 0);
Here is the PDF Output:
However I'm trying to achieve the following:
I've checked the iText documentation, but is there a way to do this without having to create tables and cells?
When you do:
baseCanvas.ShowTextAligned("Some text", x, y, TextAlignment.CENTER, 0);
Then you want the coordinate (x, y) to coincide with the middle of the text "some text".
In your code snippet, you are centering some text around the coordinate (555, 839) and some text around the coordinate (40, 809) which explains the difference.
Since you are using iText 7, why don't you take advantage of the fact that you can now easily position Paragraph objects at absolute positions? The iText 7 jump-start tutorial for .NET already introduces some of the basic building blocks, but the Building blocks tutorial goes into more depth.
Take a look at the first example of chapter 2 and adapt it like this:
PdfPage page = pdf.AddNewPage();
PdfCanvas pdfCanvas = new PdfCanvas(page);
Rectangle rectangle = new Rectangle(36, 650, 100, 100);
Canvas canvas = new Canvas(pdfCanvas, pdf, rectangle);
PdfFont font = PdfFontFactory.createFont(FontConstants.TIMES_ROMAN);
PdfFont bold = PdfFontFactory.createFont(FontConstants.TIMES_BOLD);
Text title =
new Text("The Strange Case of Dr. Jekyll and Mr. Hyde").SetFont(bold);
Text author = new Text("Robert Louis Stevenson").SetFont(font);
Paragraph p = new Paragraph().Add(title).Add(" by ").Add(author);
p.SetTextAlignment(iText.Layout.Properties.TextAlignment.CENTER);
canvas.Add(p);
canvas.Close();
This should add the text inside the rectangle (36, 650, 100, 100) and center all content.
I do it like this. Where the document is created, get the width of the document.
var document = new Document(pdfDoc);
var pageSize = pdfDoc.GetDefaultPageSize();
var width = pageSize.GetWidth() - document.GetLeftMargin() - document.GetRightMargin();
Then create the paragraph with this function.
private Paragraph CenteredParagraph(Text text, float width)
{
var tabStops = new List<TabStop> { new TabStop(width / 2, TabAlignment.CENTER) };
var output = new Paragraph().AddTabStops(tabStops);
output.Add(new Tab())
.Add(text);
return output;
}
After that just add the paragraph to the document.
document.Add(CenteredParagraph("All the text to add that is centered.");
Div div2 = new Div();
div2.setPaddingLeft(35);
div2.setPaddingRight(35);
div2.setPaddingBottom(5);
div2.add(new Paragraph().add(new Paragraph("Hola Mundo")
.setFontSize(12)
.setTextAlignment(TextAlignment.JUSTIFIED)
.setPaddingLeft(10)
)
.setPaddingBottom(4));
document.add(div2);

C# MSChart - charts area limits

I have one Chart and three ChartArea that are aligned in view, zoom, cursor:
this is my related previous post. All things works well except that the three ChartArea are not aligned at the beginning. Following an image of the problem:
I think it depends from the digit's number of Y values axis. From some research I try the following configuration:
// selezione e zoom
dlChart.ChartAreas[VOLTAGE_AREA].CursorX.Interval = 1;
dlChart.ChartAreas[VOLTAGE_AREA].CursorX.IsUserEnabled = true;
dlChart.ChartAreas[VOLTAGE_AREA].CursorX.IsUserSelectionEnabled = true;
// generale
dlChart.ChartAreas[VOLTAGE_AREA].AxisX.LabelStyle.Format = "dd/MM/yy - HH:mm:ss.fff";
dlChart.ChartAreas[VOLTAGE_AREA].AxisX.ScaleView.Zoomable = true;
dlChart.ChartAreas[VOLTAGE_AREA].AxisY.LabelStyle.Format = "D5";
In witch the last row:
dlChart.ChartAreas[VOLTAGE_AREA].AxisY.LabelStyle.Format = "D5";
should specifies always five digits. This mitigate in some way the problem but it doesn't desappers. Furthermore with this row the program starts to throws very lots exceptions of form below any time I scroll the graph:
Generate exception: 'System.FormatException' in mscorlib.dll
Does anyone knows the solution for this problem? Thanks in advance.
You may want to take control of the size of the InnerPlotPosition.
(But Baddack's solution is simpler and more flexible!)
Here is an example:
After setting up a Chart with three CharAreas, setting Minima and Maxima as well as adding one DataPoint to each we get this :
Your issue is showing clearly.
After setting the InnerPlotPosition to a fixed percentage it looks like this:
Here is how to set the InnerPlotPosition size:
ca1.InnerPlotPosition = new ElementPosition(10, 5, 80, 90);
ca2.InnerPlotPosition = new ElementPosition(10, 5, 80, 90);
ca3.InnerPlotPosition = new ElementPosition(10, 5, 80, 90);
Note that both ChartArea.Position and ChartArea.InnerPlotPosition are called 'Position' but really are areas of percentages referring to the respective containers!
So my example has a Left distance of 10%, a Top space of 5% and Width of 80% and Height of 90%. Which leaves 10% space at the Bottom and 5% at the Right. Note: All are referring to the ChartAreas not the ClientArea of the Chart! (Which are still at Auto, which maximizes the size.)
This was my initial setup:
ChartArea ca1 = chart.ChartAreas[0];
ChartArea ca2 = chart.ChartAreas[1];
ChartArea ca3 = chart.ChartAreas[2];
Series s1 = chart.Series[0];
Series s2 = chart.Series.Add("Series2");
Series s3 = chart.Series.Add("Series3");
s2.ChartArea = ca2.Name;
s3.ChartArea = ca3.Name;
s1.Points.AddXY(1, 7);
s2.Points.AddXY(1, 777);
s3.Points.AddXY(1, Math.PI);
Have you tried using the chart area alignment options? I would try something like:
//define inner plot position of the chart areas
dlChart.ChartAreas[0].InnerPlotPosition.Auto = true;
dlChart.ChartAreas[1].InnerPlotPosition.Auto = true;
dlChart.ChartAreas[2].InnerPlotPosition.Auto = true;
//set our second chart area's alignments to match our first chart area
dlChart.ChartAreas[1].AlignmentOrientation = AreaAlignmentOrientations.Vertical;
dlChart.ChartAreas[1].AlignmentStyle = AreaAlignmentStyles.All;
dlChart.ChartAreas[1].AlignWithChartArea = dlChart.ChartAreas[0].Name;
//set our third chart area's alignments to match our first chart area
dlChart.ChartAreas[2].AlignmentOrientation = AreaAlignmentOrientations.Vertical;
dlChart.ChartAreas[2].AlignmentStyle = AreaAlignmentStyles.All;
dlChart.ChartAreas[2].AlignWithChartArea = dlChart.ChartAreas[0].Name;

How to draw rectangle over a plot?

Is it possible to draw rectangle using OxyPlot? Something like
:
or does OxyPlot not support this?
Why not just use RectangleAnnotation which is already there?
It provides fill , stroke , click detection , text.
Example :
model.Annotations.Add(new RectangleAnnotation { MinimumX = 20, MaximumX = 70, MinimumY = 10, MaximumY = 40, TextRotation = 10, Text = "RectangleAnnotation", Fill = OxyColor.FromAColor(99, OxyColors.Blue), Stroke = OxyColors.Black, StrokeThickness = 2 });
You can always create your own custom annotations if existing are not good enough.
You can indeed.
There's a couple of ways you can do it. I would prefer to use an annotation as this will also give you a highlighted background and give you the option to add click events on this area. There's probably a way to remove the highlight if you want to make it look like the image you've provided.
var Event = new PolygonAnnotation();
Event.Layer = AnnotationLayer.BelowAxes;
Event.StrokeThickness = 5;
Event.Stroke = OxyColor.FromRgb(0, 0, 255);
Event.LineStyle = LineStyle.Automatic;
Event.Points.Add(new DataPoint(X, Y));
Event.Points.Add(new DataPoint(X, Y));
Event.Points.Add(new DataPoint(X, Y));
Event.Points.Add(new DataPoint(X, Y));
Another more simplistic way is to create a line series and give it the corners of your rectangle.

How to draw a vertical line in a .NET chart

I would like to draw a vertical line along x=0. I've tried the code below, but instead of all the points being drawn with x=0, they are drawn with x values of 1, 2, 3, 4, 5, respectively. I am able to draw a vertical line at what appears to be any x value other than 0.
The code below also sort of works if I change the x value of any of the points to something other than 0. Is this some sort of bug with the Chart in .NET? Is there a way to draw a vertical line along x=0?
chart1.Series["Series1"].ChartType =
System.Windows.Forms.DataVisualization.Charting.SeriesChartType.FastLine;
chart1.Series["Series1"].Points.AddXY(0, 0);
chart1.Series["Series1"].Points.AddXY(0, 2.5);
chart1.Series["Series1"].Points.AddXY(0, 5);
chart1.Series["Series1"].Points.AddXY(0, 10);
chart1.Series["Series1"].Points.AddXY(0, 20);
Chart displays incorrectly when all x values are zero

Drawing an I-Beam based on two points

I have two Point structures and I need to draw an I-Beam based on those points, where each point represents the cross-section on either side of the I-Beam. The width of the end caps should be fixed and arbitrary.
Basically I need to draw three lines. First I'll DrawLine(Point1, Point2), then I need the math to figure out how to draw the next two lines on perpendicular angles so that they are centered on Point1 and Point2.
The image below shows what I need to draw based on the center line. However, this line can be at any angle. The Point1 and Point2 that connect the line can be anywhere in a 2D space.
You can try playing around with LineCaps:
protected void DrawIBeam(Graphics g, Point fromPoint, Point toPoint)
{
using (GraphicsPath hPath = new GraphicsPath())
{
hPath.AddLine(new Point(-5, 0), new Point(5, 0));
CustomLineCap myCap = new CustomLineCap(null, hPath);
myCap.SetStrokeCaps(LineCap.Round, LineCap.Round);
using (Pen myPen = new Pen(Color.Black, 2))
{
myPen.CustomStartCap = myCap;
myPen.CustomEndCap = myCap;
g.DrawLine(myPen, fromPoint, toPoint);
}
}
}
and call it:
DrawIBeam(e.Graphics, new Point(10, 10), new Point(60, 60));
From CustomLineCap Class
Assuming a width that's half the width of the I part of the I beam, first you find the slope of the first line you drew.
Next, you take the negative inverse of the slope, and draw a line from Point1 of length width in both directions. That's why width is half of the width you want to draw.
Finally you draw a line from Point 2 of length width in both directions.
Here's the mathematical formula for drawing a perpendicular line.

Categories