none
Create a MAC (marginal abatement cost) graph using .net charting control

    Question

  • hi i was wandering if i can create a very simple mac curve graph using the charting controls.

    i am using VS2010 with C#. below is an example of mac curve graph i need to build.

    thanks for your help.

    p.s. because i cannot insert a pic or link with this msg, you can google a mac curve graph and get the idea what i need.

    Thursday, January 31, 2013 5:31 PM

All replies

  • I found many kinds of graphs googling for a "MAC curve graph". I'm guessing you meant the one with a set of variable width columns?

    There is no built-in chart type to get that, but I think you can hack it with a Range chart. I modified some code from an older thread..

    Imports System.Windows.Forms.DataVisualization.Charting
    
    Public Class RangeBox
    
    	Private WithEvents Chart1 As New Chart()
    
    	Private Sub RangeBox_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    
    		Chart1.Size = Me.ClientSize
    		Me.Controls.Add(Chart1)
    
    		Dim area As New ChartArea("AREA")
    		area.AxisX.IsMarginVisible = False
    		Chart1.ChartAreas.Add(area)
    
    		Dim series As New Series("SERIES")
    		series.ChartType = SeriesChartType.Range
    		Chart1.Series.Add(series)
    
    		Dim xValues As Integer() = {0, 3, 5, 6, 8, 10, 13, 15}
    		Dim yValues As Double() = {-3, -1, 1, 2, 4, 5, 6} 'Note, one less Y value than there are X values
    
    		'Borders don't work well with this hack, so using alternating colors
    		Dim palette As Color() = {Color.FromArgb(255, 180, 220, 240), Color.FromArgb(255, 130, 170, 200)}
    
    		For i As Integer = 0 To yValues.Length - 1
    
    			Dim x1 As Double = xValues(i)
    			Dim y1 As Double = 0
    
    			Dim x2 As Double = xValues(Math.Min(i + 1, xValues.Length - 1))
    			Dim y2 As Double = yValues(i)
    
    			series.Points.AddXY(x1, y1, y2)
    			series.Points.AddXY(x2, y1, y2)
    			series.Points.AddXY(x2, Double.NaN, Double.NaN)	'This will add gaps to the Range series.
    
    			series.Points(i * 3 + 1).Color = palette(i Mod palette.Length)
    
    		Next
    
    	End Sub
    
    End Class

    ..to get this

    Friday, February 01, 2013 8:41 AM
    Moderator
  • hi Sipla, thanks soo much for your answer. its exactly what i am looking for. i copied the code and ran it. everything worked fine apart from the last code line (using c# in VS2010 in asp.net web application). errors i am getting are:

    Error 1 Non-invocable member 'System.Web.UI.DataVisualization.Charting.Series.Points' cannot be used like a method. 

    Error 2 'palette' is a 'variable' but is used like a method

    series.Points(i * 3 + 1).Color = palette(i Mod palette.Length)

    Please what can i do to correct the above errors, thanks

    Friday, February 01, 2013 8:15 PM
  • Series.Points is a Collection of data points, use like an array, with square brackets. The palette variable is just an array of Color objects.

    This is what it should look like in C#

    Color[] palette = { Color.FromArgb(255, 180, 220, 240), Color.FromArgb(255, 130, 170, 200) };
    
    //...
    
    series.Points[i].Color = palette[i % palette.Length];

    Saturday, February 02, 2013 9:27 AM
    Moderator
  • hi Sipla,

    I want to use an arraylist to feed data to the graph as such:

    ArrayList myArrayList = Session["MyArrayList"] as ArrayList;
                if (myArrayList != null)
                {
                    foreach (MAC mac in myArrayList)
                    {
                        string type = mac.MethodName;   //returns WindPower
                        double xCO2Value = mac.TotalCO2;  //returns 300
                        double yCostValue = mac.TotalCost; //returns -20
                    }
                    
                }

    the size of the array is 8 or more. the methodname is the different component. xco2value is the value for the x axis and ranges between 100-800 and ycostvalue is value for the yaxis and ranges between -50 to 50.

    how can i plot this graph using the arraylist as an input. thanks

    Sunday, February 03, 2013 8:22 PM
  • Here, let me code that for you.

    Dim sumCO2 As Double = 0
    
    For i As Integer = 0 To myArrayList.Count - 1
    
    	Dim mac As MAC = CType(myArrayList(i), MAC)
    
    	Dim x1 As Double = sumCO2
    	Dim y1 As Double = 0
    
    	Dim x2 As Double = mac.TotalCO2 + sumCO2
    	Dim y2 As Double = mac.TotalCost
    
    	sumCO2 += mac.TotalCO2
    
    	series.Points.AddXY(x1, y1, y2)
    	series.Points.AddXY(x2, y1, y2)
    	series.Points.AddXY(x2, Double.NaN, Double.NaN)
    
    	series.Points(i * 3 + 1).Color = palette(i Mod palette.Length)
    
    	'Add a label
    	Dim al As New CalloutAnnotation()
    	al.CalloutStyle = CalloutStyle.SimpleLine
    	al.Text = mac.MethodName
    	al.AxisX = area.AxisX
    	al.AxisY = area.AxisY
    	al.AnchorX = (x1 + x2) / 2
    	al.AnchorY = (y1 + y2) / 2
    	Chart1.Annotations.Add(al)
    
    Next
    Monday, February 04, 2013 8:20 AM
    Moderator
  • Hi Sipla,

    What do I need to change in the code to get different colors (can be random) for each point in the chart. currently we have 2 colors.

    Also how can I plot a legend on the chart showing the color and the Name (mac.methodName) for each point.

    thanks

     

    Tuesday, February 12, 2013 7:08 PM