Search code examples
c#zedgraph

ZedGraph stacked bar with multiple points in C#


What I have is a configuration file that looks like this:

Item|Size|Directory|Data  
A|12|D_01|11/28/10  
C|13|D_01|11/28/10  
B|12|D_01|11/28/10  
Back|122|D_02|11/28/10  
Body|112|D_02|11/28/10  
A|12|D_01|11/29/10  
C|13|D_01|11/29/10  
B|12|D_01|11/29/10  
Back|122|D_01|11/29/10  
Body|112|D_01|11/29/10  
Arm|20|D_01|11/29/10  

My x-axis is date, which I have no problem with, and if I only have a static number of instances to make up my Y I would be fine, but how do I create a single stacked bar graph that automatically make points for each item for each directory?

So stacked bar 1 would be A.B.C, Body, Back, Arm and the example shows on 29 I added an Arm item. So bar 1 on the 28th has 5 points, the stacked bar 2 on the 29th shows 6 points.

I hope that makes sense.. I don't need help with anything but how to display the bars appropriately.


Solution

  • alt text

    It wasn't clear in the question how the directories would affect the display of data so, assuming that only two bars are needed (1 for each of 2 dates), here's an example. There are two ways to format the date axis and handle the null data: 1 using AxisType.Date=DateAsOrdinal and add values of zero for dates where data is null or [2] using AxisType.Date=Date and don't add values for dates where data is null. DateAsOrdinal seems to apply data to the wrong date if there is null data - which seems to be a bug or at least unintuitive. The example uses the AxisType.Date=Date approach which required extra formatting of the date axis.

         using ZedGraph;
    
         ...
    
         GraphPane myPane = zg1.GraphPane; // zg1 is a ZedGraph control.
    
         // Set the title and axis label
         myPane.Title.Text = "Stacked Bar, ZedGraph ver 5.1.5.28844";
         myPane.YAxis.Title.Text = "Value";
    
         // Create two dates.
         XDate date1 = new XDate(2010, 11, 28); // First date.
         XDate date2 = new XDate(2010, 11, 29); // Second date.
    
         // Create data lists and bars for A, B, C, Back, Body and Arm (6 total).
    
         ZedGraph.PointPairList listA = new ZedGraph.PointPairList();
         listA.Add( date1, 12 );
         listA.Add( date2, 13);
    
         BarItem barA = zg1.GraphPane.AddBar("A", listA, Color.Red );
         barA.Bar.Fill = new Fill( Color.Red );
    
         ZedGraph.PointPairList listB = new ZedGraph.PointPairList();
         listB.Add(date1, 12);
         listB.Add(date2, 12);
    
         BarItem barB = zg1.GraphPane.AddBar("B", listB, Color.Blue);
         barB.Bar.Fill = new Fill(Color.Blue);
    
         ZedGraph.PointPairList listC = new ZedGraph.PointPairList();
         listC.Add(date1, 13);
         listC.Add(date2, 12);
    
         BarItem barC = zg1.GraphPane.AddBar("C", listC, Color.Green);
         barC.Bar.Fill = new Fill(Color.Green);
    
         ZedGraph.PointPairList listBack = new ZedGraph.PointPairList();
         listBack.Add(date1, 122);
         listBack.Add(date2, 122);
         BarItem barBack = zg1.GraphPane.AddBar("Back", listBack, Color.Red);
         barBack.Bar.Fill = new Fill(Color.Red, Color.White, Color.Red);
    
         ZedGraph.PointPairList listBody = new ZedGraph.PointPairList();
         listBody.Add(date1, 112);
         listBody.Add(date2, 112);
         BarItem barBody = zg1.GraphPane.AddBar("Body", listBody, Color.Blue);
         barBody.Bar.Fill = new Fill(Color.Blue, Color.White, Color.Blue);
    
         ZedGraph.PointPairList listArm = new ZedGraph.PointPairList();
         // listArm.Add(date1, 0); // Not needed for XAxis.Type = AxisType.Date.
         listArm.Add(date2, 20);
         BarItem barArm = zg1.GraphPane.AddBar("Arm", listArm, Color.Green);
         barArm.Bar.Fill = new Fill(Color.Green, Color.White, Color.Green);
    
         // Done creating bars.
    
         myPane.BarSettings.Type = BarType.Stack;  // stacks bar rather than side-by-side.
         myPane.BarSettings.ClusterScaleWidth = 1; // Widen bars somewhat.
    
         // Format the X axis.
         XAxis x = myPane.XAxis;
    
         x.Type = AxisType.Date;
         x.Scale.Format = "yyyy-mm-dd";
         x.Scale.BaseTic = date1; // Puts the first major tic at the first date.
         x.Scale.Min = date1 - 0.5; // Manually set the left of the graph window just prior to the first date.
         x.Scale.Max = date2 + 0.5; // Manually set the right of the graph window just after the last date.
    
         // Setting the step size...
         // Isn't required if AxisType.Date is DateAsOrdinal.
         // Docs says that MinorStep is ignore for AxisType.Date but seems inaccurate.
         // Step value of 24 was derived by trial and error. Seems it should be 1 if Unit = DateUnit.Day.
         // A value of 24 implies that the Units are acting like DateUnit.Hour.
         x.Scale.MajorUnit = DateUnit.Day; 
         x.Scale.MinorUnit = DateUnit.Day;
         x.Scale.MinorStep = 24; 
         x.Scale.MajorStep = 24;
    
         zg1.AxisChange(); // Update graph.