I am trying to display daily production data on a line chart in pounds of product produced per hour. We have 2 departments that appear on this chart however, some days 1 of the 2 departments may not be scheduled for production. On these days in my chart, I don't want to show a zero value for pounds per hour because it shows as a sharp dip in productivity. I need the line chart to skip that day for the zero value.Can anyone shed some light on how I can accomplish this?My datasource is a datatable with decimal values for the points on the line.Thanks in advance for your help,Trevor BraunThe Stirling Creamery Ltd.
assuming the "not scheduled" data in your datasource is null or DBNull,
UltraChart1.LineChart.NullHandling = DontPlot;
I have the same issue as Trevor and would like to have the line continue from the point for which a value exists on to the next point for which a value exists as if the columns (for which a particular row has no value) weren't even being graphed for that item.
In other words, if I weigh myself on 3 of 7 days and I weigh Foo Bar 5 of 7 days then I don't want my weight to dip down to zero on those other 2 days if I try to plot coordinates for both Foo Bar and myself in the same chart for that week.
I tried the line above just to see what the effect would be but I get an error message when I try to compile (C#): The name 'DontPlot' does not exist in the class or namespace
Fairly new to Infragistics. Using UltraWinChart.v7.1 and VS2003 (Version 7.1.6030 .NET Framework 1.1) as I have to write to a system (Eclipsys SCM v. 4.5) that requires it.
Would sure appreciate some code samples.
Thanks.
allen
You didn't answer the question about how to post code nicely like you do. Is that not possible?
I understand how to plot a point. My problem is that I don't understand the inheritance for the component well enough to determine that I've got a single point to map (that I have one significant value amongst nulls for that particular item). If I knew how to access the value for each day (in my example) to determine that only one of the days has a value to plot, I could then proceed to instantiate and plot an ellipse at that location.
Thanks,
Allen
allenovereem said:You didn't answer the question about how to post code nicely like you do. Is that not possible?
whoops. i just paste directly from visual studio into firefox, which doesn't really come out nicely. i think it works a lot better if you use IE.
allenovereem said:If I knew how to access the value for each day...
if you're using the Series collection as a datasource, it is easy, you can just loop through the DataPoints in each series.
if you're using the DataSource property of the chart, it's better to just go back to your data structure to find the isolated point.
if you can't do that for some reason, you can use the IChartData interface in FillSceneGraph...
IChartData chartData = e.ChartCore.GetChartLayer().ChartData;
// use chartData.GetRowCount(), GetColumnCount(), and GetValue(row, column) to iterate through your data.
As I've indicated, I'm using 7.1 and had to create a custom interface for FillSceneGraph.
I don't have the e.ChartCore available in that implementation.
Whatever values I cycle through are going to need to be accessed from my scene or by some other means of which I'm hoping you'll make me aware.
Copying source code in doesn't work any better in IE than in Firefox. All formatting is lost. I know there is something I'm missing because I see nicely formatted code all over this site.
Sure would make it easier if I could post some code along with my questions in order to qualify/elucidate what I'm asking.
Here is the source code zipped. Let's see if that can be accessed...
Here is an image of the program output produced by the zipped source code...
There is a point in the source where I indicate I'll comment this out until I determine how to determine there is only one significant value for a particluar item... As you can see from that bit of code, I'm telling it to plot the ellipse based on the value of that point since I know what it is and since I've intentionally made sure there are no other points with that value.
If I could replace that with a piece of code that returns a boolean value (perhaps) indicating whether my item has one and only one significant point to plot then I could replace that if statement and be done. Unfortunately I'm not sure how to do that.
Other than that, I think all the issues with inaccurate line plotting using UltraChart is basically addressed by this code.
Trevor, I think this is the solution you were looking for with your original post BTW.
Thoughts? Suggestions for how this idiot (me) can identify whether a point is the only significant point for that item (like Purple in my example)?
this "GetIsolatedPoints" method should get you what you need, so in FillSceneGraph you can just use code like this:
Point[] isolatedPoints = this.GetIsolatedPoints(); foreach (Point isolatedPoint in isolatedPoints) { // draw an ellipse Ellipse plotPoint = new Ellipse(isolatedPoint, 4); plotPoint.PE.Fill = Color.Purple; plotPoint.Layer = this; // add the ellipse to the scene. scene.Add(plotPoint); }
private Point[] GetIsolatedPoints() { IAdvanceAxis xAxis = this.Grid["X"] as IAdvanceAxis; IAdvanceAxis yAxis = this.Grid["Y"] as IAdvanceAxis; int rowCount = this.ChartData.GetRowCount(); int colCount = this.ChartData.GetColumnCount(); List<Point> result = new List<Point>(); for (int r = 0; r < rowCount; r++) { int indexOfNonNullPoint = -1; bool isolated = true; for (int c = 0; c < colCount; c++) { object objectValue = this.ChartData.GetObjectValue(r, c); if (objectValue != null && !(objectValue is DBNull)) { if (indexOfNonNullPoint != -1) { isolated = false; break; } indexOfNonNullPoint = c; } } if (isolated) { object objectValue = this.ChartData.GetObjectValue(r, indexOfNonNullPoint); double dataValue = Convert.ToDouble(objectValue); int xPosition = Convert.ToInt32(xAxis.Map(indexOfNonNullPoint)); int yPosition = Convert.ToInt32(yAxis.Map(dataValue)); result.Add(new Point(xPosition, yPosition)); } } return result.ToArray(); }
Thanks David. I finally got to attempt this yesterday. I'm new to C# and not very good at it. I ended up creating a few more arraylists to capture the row and column and data values for passing to the getFillColor method and it did work. Maybe I'll figure out how to use a jagged array to make it more efficient. Will post some code later. Wanted to thank you and say that it worked. Thanks again!
allenovereem said:Now if I could just synch the color of the ellipse with the color that is going to be displayed for that point in the legend...any ideas?
The legend icons should also be in your SceneGraph, and their Path properties should all include the string "Legend." they will also have their Row and Column properties set... so you should be able to change the color of the legend items as needed.
or, you could try finding the correct color for your ellipse using this.ChartColorModel.getFillColor(...).
I modified slightly for my implementation and this works great.
Now if I could just synch the color of the ellipse with the color that is going to be displayed for that point in the legend...any ideas?
Your idea for posting code appears to work well too. Here I'm using Firefox and I've copied the code from VS2003 into WordPad and then copied that to here. At least at this point the formatting appears intact!
Thanks!
added to the end of FillSceneGraph...
IAdvanceAxis xAxis = this.Grid["X"] as IAdvanceAxis; IAdvanceAxis yAxis = this.Grid["Y"] as IAdvanceAxis; int rowCount = this.ChartData.GetRowCount(); int colCount = this.ChartData.GetColumnCount(); ArrayList iPointsOut = new ArrayList(); for (int r = 0; r < rowCount; r++) { int indexOfNonNullPoint = -1; bool isolated = true; for (int c = 0; c < colCount; c++) { object objectValue = this.ChartData.GetObjectValue(r, c); if (objectValue != null && !(objectValue is System.DBNull)) { if (indexOfNonNullPoint != -1) { isolated = false; break; } indexOfNonNullPoint = c; } } if (isolated) { object objectValue = this.ChartData.GetObjectValue(r, indexOfNonNullPoint); double dataValue = System.Convert.ToDouble(objectValue); int xPosition = System.Convert.ToInt32(xAxis.Map(indexOfNonNullPoint)); int yPosition = System.Convert.ToInt32(yAxis.Map(dataValue)); iPointsOut.Add(new Point(xPosition, yPosition)); } } //Point[] isolatedPoints = this.GetIsolatedPoints(); foreach (Point isolatedPoint in iPointsOut) { // draw an ellipse Ellipse plotPoint = new Ellipse(isolatedPoint, 4); plotPoint.PE.Fill = Color.Black; plotPoint.Layer = this; // add the ellipse to the scene. scene.Add(plotPoint); }
Thanks. This looks like it has the potential to do it. Unfortunately I'm using VS2003 (writing to SCM4.5) so I'll have to figure out how to implement it differently than you have here before I bless it. Again thanks and I'll be back.