I create a single contour and add it to the chart, add points with label text and also subscribe to the GetSeriesMark event, but the text is not displayed, and the event never gets fired
Contour contour1 = new Contour();
contour1.IrregularGrid = true;
//
// contour1
contour1.Brush.Color = Color.FromArgb(68, 102, 163);
contour1.ColorEach = false;
contour1.EndColor = Color.FromArgb(192, 0, 0);
contour1.FillLevels = checkEditFillLevels.Checked;
//
//
contour1.Marks.Style = MarksStyles.Label;
contour1.Marks.Visible = true;
//
//
contour1.NumLevels = 8;
contour1.PaletteMin = 0;
contour1.PaletteStep = 0;
contour1.PaletteStyle = PaletteStyles.Pale;
//
//
contour1.Pen.Color = Color.FromArgb(192, 192, 192);
contour1.Pen.Style = DashStyle.Dot;
//
//
contour1.Pointer.HorizSize = 2;
//
//
contour1.Pointer.Pen.Visible = false;
contour1.Pointer.Style = PointerStyles.Rectangle;
contour1.Pointer.VertSize = 2;
contour1.Pointer.Visible = true;
contour1.StartColor = Color.FromArgb(255, 255, 192);
contour1.Title = "contour1";
Adding points is done with this
contour1.Add(x, y, z, "My Point 1");
Is there a way to display marks on the exact points in the Contour, and moreover is there a way to display marks only on specific points in the Contour (some points are actual data, others are made using interpolation to be able to show the contour)?
I'm afraid not, Contour series calculates and displays isolines from a custom array of X, Y and Z points. Levels are calculated automatically from users data. What would you like to get exactly? You might be interested in using Annotation tools. Here you can find an example about custom annotation tool positioning.
Since it is not possible to mark single points in contour (see #Narcís Calvet's answer), I ended up adding one Points series with marks on them.
However, I still wanted only the Contour levels to be shown in the legend, and X axis to display it's values instead of Marks of the Points, so I needed to add following lines.
tChart1.Legend.LegendStyle = LegendStyles.Values;
tChart1.Legend.Series = _currentContour;
tChart1.Axes.Bottom.Labels.Style = AxisLabelStyle.Value;
Related
something is not working as it should. If you take alook at the screenshot you will see that the result is weird. The floor of the pavilion is rendered correctly, but the columns are kinda transparent, and the roof is completele weird. I used Assimp.NET to import his mesh from a .obj file. In other engines it looked correctly. Another thing was: if i set CullMode to Back - it will cull the front faces?! I think it could be 3 things: 1,the mesh was imported wrong, or the z Buffer is not working, or maybe i need multiple world matrices (im using only one).
Does maybe anybody know what this could be?!
Screenshot:
Here is some code:
DepthBuffer/DepthStencilView
var depthBufferDescription = new Texture2DDescription
{
Format = Format.D32_Float_S8X24_UInt,
ArraySize = 1,
MipLevels = 1,
Width = BackBuffer.Description.Width,
Height = BackBuffer.Description.Height,
SampleDescription = swapChainDescription.SampleDescription,
BindFlags = BindFlags.DepthStencil
};
var depthStencilViewDescription = new DepthStencilViewDescription
{
Dimension = SwapChain.Description.SampleDescription.Count > 1 || SwapChain.Description.SampleDescription.Quality > 0 ? DepthStencilViewDimension.Texture2DMultisampled : DepthStencilViewDimension.Texture2D
};
var depthStencilStateDescription = new DepthStencilStateDescription
{
IsDepthEnabled = true,
DepthComparison = Comparison.Always,
DepthWriteMask = DepthWriteMask.All,
IsStencilEnabled = false,
StencilReadMask = 0xff,
StencilWriteMask = 0xff,
FrontFace = new DepthStencilOperationDescription
{
Comparison = Comparison.Always,
PassOperation = StencilOperation.Keep,
FailOperation = StencilOperation.Keep,
DepthFailOperation = StencilOperation.Increment
},
BackFace = new DepthStencilOperationDescription
{
Comparison = Comparison.Always,
PassOperation = StencilOperation.Keep,
FailOperation = StencilOperation.Keep,
DepthFailOperation = StencilOperation.Decrement
}
};
Loading mesh files:
public static Mesh Stadafax_ModelFromFile(string path)
{
if (_importContext.IsImportFormatSupported(Path.GetExtension(path)))
{
var imported = _importContext.ImportFile(path, PostProcessSteps.Triangulate | PostProcessSteps.FindDegenerates | PostProcessSteps.FindInstances | PostProcessSteps.FindInvalidData | PostProcessSteps.JoinIdenticalVertices | PostProcessSteps.OptimizeGraph | PostProcessSteps.ValidateDataStructure | PostProcessSteps.FlipUVs);
Mesh engineMesh = new Mesh();
Assimp.Mesh assimpMesh = imported.Meshes[0];
foreach(Face f in assimpMesh.Faces)
{
engineMesh.Structure.Faces.Add(new Rendering.Triangle((uint)f.Indices[0], (uint)f.Indices[1], (uint)f.Indices[2]));
}
List<Vector3D>[] uv = assimpMesh.TextureCoordinateChannels;
for(int i = 0; i < assimpMesh.Vertices.Count; i++)
{
engineMesh.Structure.Vertices.Add(new Vertex(new Vector4(assimpMesh.Vertices[i].X, assimpMesh.Vertices[i].Y, assimpMesh.Vertices[i].Z, 1), RenderColorRGBA.White, new Vector2(uv[0][i].X, uv[0][i].Y)));
}
return engineMesh;
}
else
NoëlEngine.Common.Output.Log("Model format not supported!", "Importeur", true); return null;
}
}
If anybody only has the smallest idea what this could be please just write a comment.
What you see are polygons actually behind others still being drawn above them.
When you configure the depth buffer via DepthStencilStateDescription, you set up the DepthComparison to Comparison.Always. This is not what you want, you want to use Comparison.Less.
What's the logic behind it? Every depth value for a pixel is checked whether it can actually write to the depth buffer. This check is configured with the Comparison you specified.
Comparison.Always always allows the new value to be written. So no matter if a polygon is actually behind others or above them or whatever, it will always override ("draw above") what's already there - even if it's behind it spatially.
Comparison.Less only writes the value if it is less than the current value in the depth buffer. Don't forget that smaller depth values are closer to the viewer. So a polygon closer to an existing one will override ("draw above") the old one. But if it is behind it, it won't draw. That's exactly what you want.
You can also guess what the other Comparison enumerations now do, and play around with them :)
I had added Polyline annotation to graph control. But it is not aligned properly in given datapoint in Addline() method.
PolylineAnnotation annotation = new PolylineAnnotation();
annotation.AxisX = chart1.ChartAreas[0].AxisX;
annotation.AxisY = chart1.ChartAreas[0].AxisY;
annotation.AnchorX = 0;
annotation.AnchorY = 0;
annotation.Height = 30;
annotation.Width = -30;
annotation.LineWidth = 3;
annotation.StartCap = LineAnchorCapStyle.None;
annotation.EndCap = LineAnchorCapStyle.None;
annotation.Alignment = ContentAlignment.BottomLeft;
annotation.AnchorAlignment = ContentAlignment.BottomRight;
annotation.AnchorDataPoint = new DataPoint(this.chart1.Series[0]);
annotation.AllowAnchorMoving = true;
annotation.AllowMoving = true;
annotation.AllowPathEditing = true;
annotation.AllowResizing = true;
annotation.AllowSelecting = true;
annotation.GraphicsPath.AddLine(10, 20, 30, 30);
chart1.Annotations.Add(annotation);
Annotations are complex and anchoring them is too.
It starts rather simple: To anchor an Annotation you need to set its AnchorDataPoint to an existing DataPoint.
This line does nothing like that:
annotation.AnchorDataPoint = new DataPoint(this.chart1.Series[0]);
as the newly created DataPoint is empty. Its has been added and it has values of (0d, 0d), but you probably want to keep the Annotation aligned to a real DataPoint, maybe like this..:
annotation.AnchorDataPoint = chart1.Series[0].Points[someIndex];
But there is more: There actually are two ways to anchor an Annotation:
Anchor it to a DataPoint or
Anchor it with fixed AnchorX and AnchorY values.
(And then you can set them to fixed X & Y values, too.)
Your code actually does both! But: anchoring the coordinates takes precedence over anchoring to a DataPoint.
This is nice as you can combine them and first anchor to a DataPoint and then anchor one of the coordinates to a fixed value: say, x-value stays with the point but the y-value is maybe always at 0..
Also note that you are adding only one line to your polyline and you don't start it at (0,0) but at (10,20) which may be quite some way off the anchor..
And then there is the issue of size and alignment of the polyline itself!
It has a size which MSDN claims is given in pixels. This is nonsense. Instead it is given in value units of the two respective Axes. You can see this when you resize the Chart the Annotation will resize as well; see the screenshot!
Now for the GraphicsPath and its points: Those are given in percent of the Size of the Annotation. To get a feeling for this add a test annotation path that encloses the whole area:
annotation.GraphicsPath.AddRectangle(new Rectangle(0, 0, 100, 100));
Here is a screenshot of what we have got:
As you can see the most logical alignment is TopLeft and after translating the line to (0,0) it would stick right into the point.
Note that I have added a 2nd Series to make the anchor data point stand out.. - Also note that while the Annotation size is a square (10,10) is is stretched horizontally along with the whole chart.
This is the full code I used:
PolylineAnnotation annotation = new PolylineAnnotation();
annotation.AxisX = chart1.ChartAreas[0].AxisX;
annotation.AxisY = chart1.ChartAreas[0].AxisY;
annotation.Height = 10;
annotation.Width = 10;
annotation.LineWidth = 3;
annotation.StartCap = LineAnchorCapStyle.None;
annotation.EndCap = LineAnchorCapStyle.None;
annotation.Alignment = ContentAlignment.TopLeft;
annotation.AnchorAlignment = ContentAlignment.TopLeft;
annotation.X = annotation.Y = annotation.AnchorX = annotation.AnchorY = double.NaN;
DataPoint dp = chart1.Series[0].Points[33];
annotation.AnchorDataPoint = dp;
chart1.Series[1].Points.AddXY(dp.XValue, dp.YValues[0]); // my red points series
annotation.AllowAnchorMoving = true;
annotation.AllowMoving = true;
annotation.AllowPathEditing = true;
annotation.AllowResizing = true;
annotation.AllowSelecting = true;
annotation.GraphicsPath.AddLine(10, 20, 30, 30);
Rectangle r = new Rectangle(0, 0, 100, 100);
annotation.GraphicsPath.AddRectangle(r);
chart1.Annotations.Add(annotation);
Also note that just to make sure no wrong anchors are active I have reset the X/Y and the AnchorX/Y values by setting them to double.NaN! This is not really needed here, as those are the defaults anyway..
Here btw is another post on the topic!
I'm trying to create in c# in Visual studio a nice way to show the minimum, maximum and actual value of a "variable" (Variable is a class). I was trying to use the charts to do that but I have two problems.
1) It shows in 2D and I only need 1 dimension.
2) I can't write tags on the values, in this case to show which is the minimum, the maximum and the current value.
Is there a SeriesChartType that does that?
I would appreciate ideas. Thanks!
It is not so much the chart type but the various styling options you need to play with.
Here is an example using ChartType.Point:
// no legend:
chart.Legends.Clear();
// a couple of short references:
ChartArea ca = chart.ChartAreas[0];
Series S1 = chart.Series[0];
// no y-axis:
ca.AxisY.Enabled = AxisEnabled.False;
ca.AxisY.Minimum = 0;
ca.AxisY.Maximum = 1;
// use your own values:
ca.AxisX.Minimum = 0;
ca.AxisX.Maximum = 100;
// style the ticks, use your own values:
ca.AxisX.MajorTickMark.Size = 7;
ca.AxisX.MajorTickMark.Interval = 10;
ca.AxisX.MinorTickMark.Enabled = true;
ca.AxisX.MinorTickMark.Size = 3;
ca.AxisX.MinorTickMark.Interval = 2;
// I turn the axis labels off.
ca.AxisX.LabelStyle.Enabled = false;
// If you want to show them pick a reasonable Interval!
ca.AxisX.Interval = 1;
// no gridlines
ca.AxisY.MajorGrid.Enabled = false;
ca.AxisX.MajorGrid.Enabled = false;
// the most logical type
// note that you can change colors, sizes, shaps and markerstyles..
S1.ChartType = SeriesChartType.Point;
// display x-value above; make sure you have enough room!
S1.Label = "#VALX";
// a few test data:
S1.Points.AddXY(1, 0.1);
S1.Points.AddXY(11, 0.1);
S1.Points.AddXY(17, 0.1);
S1.Points.AddXY(81, 0.1);
Note that you can play with the Series.SmartLabelStyle to display values when they are too dense!
I add the DataPoints at an y-value of 0.1. You can change it to move the points up or down a little..
I am trying to plot a file's byte count over a C# WinForms bar graph. As such, the X-axis will have values 0-255 (if greater than zero) and the Y-axis varies upon the length of the file and the byte distribution. The code is as follows:
for (int i = 0; i < byteDistribution.Count; i++)
{
if (byteDistribution[i] > 0)
{
Series series = new Series(i.ToString());
series.Points.AddXY(i, byteDistribution[i]);
// PointWidth has no affect?
series.SetCustomProperty("PointWidth", "1");
this.crtBytes.Series.Add(series);
}
Questions:
This works well but the way the chart is shown is not to my liking.
I would like each bar to fill in as much space as possible (ie. no
margin / border). From what I've read elsewhere it was suggested to
use PointWidth or PixelPointWidth but none of these approaches is
working.
Is there a way to remove the inner black grid lines from
showing? Ideally, I would like the bottom X-axis numbering to remain just the same, but remove the grid lines.
For removing the gaps:
series["PointWidth"] = "1";
For removing the gridlines:
chartArea.AxisX.MajorGrid = new FChart.Grid {Enabled = false};
chartArea.AxisY.MajorGrid = new FChart.Grid { Enabled = false };
UPDATE:
I think your problem is that you create a new series for each data point. So you also get the "color effect". Just create ONE series, add it to the chart area and add all data points to this series.
Series series = new Series();
this.crtBytes.Series.Add(series);
series.SetCustomProperty("PointWidth", "1");
for (int i = 0; i < byteDistribution.Count; i++)
{
if (byteDistribution[i] > 0)
{
series.Points.AddXY(i, byteDistribution[i]);
// PointWidth has no affect?
}
}
PointWidth property is a relative amount, try something like series["PointWidth"] = 1.25.
The black lines are called MajorGrid, use chartArea.MajorGrid.Enabled = False.
So basically I have a graph as below in the image, I am going to be implementing some check boxes to enable and disable each line graph.
My main question is:
As you can see on the graphs there is dips in the data down to ZERO - How do I get these to automatically highlight for the user to see!
I.e. Set a point on the X Axis that displays interval!
One way would be to add a another Series of ChartType Point and add only those Zero Points as red dots..:
// add a new Series:
Series sz = chart1.Series.Add("Zeroes");
sz.ChartType = SeriesChartType.Point;
sz.Color = Color.Red;
sz.BorderWidth = 3;
// add Points wherever the other series is zero or less
foreach (DataPoint dp in chart1.Series[0].Points )
{
if (dp.YValues[0] <= 0) sz.Points.AddXY(dp.XValue, 0);
}
If you need to check on more Series you can repeat the loop for them..