• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 398
  • Last Modified:

How do I "honor the date range" on a chart in my visual studio windows application?

I have a chart that graphs results from a table.  Sometimes there are a lot of data points for a year, and some times there are none.  An engineer wants me to "honor the date range" and have the years in equal distribution along the x-axis.  I have been playing with the interval under Chart, ChartAreas.  To include the Cursor X section and the Axes, X axis section.  I can't seem to get them to be equal distances apart.  I have changed every possibility to Year that I can.  Any help with these setting would be greatly appreciated...  as I fear I've just made a hot mess.

Thanks!
0
Karen Wilson
Asked:
Karen Wilson
  • 16
  • 11
1 Solution
 
AndyAinscowCommented:
If nothing else works then the only way I can think is to add artificial datapoints to pad the data out.
eg.
Year 1 you have 1 Jan, 1 July and 1 Dec.
Year 2 you have only 1 Dec.

So you add two extra points for year 2, 1 Jan and 1 July calculating the y value based on a straight line between 1 Dec (year1) and 1 Dec (year 2).  (I assume you have a line chart - if it is just points then you have no need to calculate a y value for the padding, just use the same value of y that the x-axis is using to cross the y-axis)
0
 
Karen WilsonAuthor Commented:
He can produce this chart in Excel.  It's called an x-y scatter chart.  A scatter chart isn't one of the choices.  I thought of adding the extra points but wanted to see if there was a setting with the chart that would do it.  If Excel can do it, I know the chart can do it too.  It has too!
0
 
Robert SchuttSoftware EngineerCommented:
There are different scatter charts in Excel. If you want something like this:
capture 1then you can come close with this code:
    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Dim dt As New DataTable
        dt.Columns.AddRange({New DataColumn("Date", GetType(Date)), New DataColumn("Value", GetType(Integer))})
        dt.Rows.Add({Date.Parse("2013-01-01"), 70})
        dt.Rows.Add({Date.Parse("2013-07-01"), 120})
        dt.Rows.Add({Date.Parse("2013-12-01"), 80})
        dt.Rows.Add({Date.Parse("2014-12-01"), 110})

        Chart1.DataSource = dt
        Chart1.Series(0).ChartType = DataVisualization.Charting.SeriesChartType.Line
        Chart1.Series(0).XValueMember = "Date"
        Chart1.Series(0).YValueMembers = "Value"
        Chart1.Series(0).MarkerStyle = DataVisualization.Charting.MarkerStyle.Diamond
        Chart1.Series(0).MarkerSize = 10
        Chart1.Series(0).BorderWidth = 3
        Chart1.Series(0).Color = Color.SteelBlue

        Chart1.ChartAreas(0).AxisX.IntervalType = DataVisualization.Charting.DateTimeIntervalType.Months
        Chart1.ChartAreas(0).AxisX.Interval = 1
        Chart1.ChartAreas(0).AxisX.LabelStyle.Angle = -90

    End Sub

Open in new window

The output:
capture 2
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
Karen WilsonAuthor Commented:
Thanks for the response.  This is what the chart needs to look like...  The date ranges are the same length in the x-axis and the data points are located inside the year.  One year is really squishy (like my tech-talk) because it had a lot of data points but it still remains within the length.  

Chart honoring the date range.
0
 
Karen WilsonAuthor Commented:
This is what the chart is looking like so far in my windows application.  
Capture2.PNG
0
 
Robert SchuttSoftware EngineerCommented:
Can you try this:
        Chart1.Series(0).ChartType = DataVisualization.Charting.SeriesChartType.Line
        Chart1.Series(0).XValueMember = "Date"
        Chart1.Series(0).YValueMembers = "Value"
        Chart1.Series(0).MarkerStyle = DataVisualization.Charting.MarkerStyle.Diamond
        Chart1.Series(0).MarkerSize = 10
        Chart1.Series(0).BorderWidth = 1
        Chart1.Series(0).Color = Color.Blue

        Chart1.ChartAreas(0).AxisX.IntervalType = DataVisualization.Charting.DateTimeIntervalType.Years
        Chart1.ChartAreas(0).AxisX.Interval = 1
        Chart1.ChartAreas(0).AxisX.IntervalOffset = 2
        Chart1.ChartAreas(0).AxisX.IntervalOffsetType = DataVisualization.Charting.DateTimeIntervalType.Months
        Chart1.ChartAreas(0).AxisX.Minimum = Date.Parse("1988-03-01").ToOADate
        Chart1.ChartAreas(0).AxisX.IsMarginVisible = False
        Chart1.ChartAreas(0).AxisX.LabelStyle.Angle = 90
        Chart1.ChartAreas(0).AxisX.LabelStyle.Format = "MMM-yy"

Open in new window

0
 
Karen WilsonAuthor Commented:
I set up what I could in the setting and then hard coded your definition for the AxisX.Minimum and the chart came up empty.  Here are my settings.  The entry requirement for the AxisX.Minimum is a double.  
Capture3.PNG
0
 
Robert SchuttSoftware EngineerCommented:
If the chart is empty then that's probably due to Series settings. How are you binding the data?
The entry requirement for the AxisX.Minimum is a double
Yes, in code this is done with Date(...).ToOADate:
Chart1.ChartAreas(0).AxisX.Minimum = Date.Parse("1988-03-01").ToOADate

Open in new window

this calculates as: 32203.0
0
 
Karen WilsonAuthor Commented:
Here is my code:
Dim dTable As New DataTable

            dTable.Columns.Add("Date", GetType(Date))
            dTable.Columns.Add("Result", GetType(Decimal))
            dTable.Columns.Add("Cleanup Level", GetType(String))
            dTable.Columns.Add("QA Flag", GetType(String))

            For i As Integer = 0 To selectedWell.Count - 1

                If CDec(selectedWell.Item(i).det_limit) > 0 Then

                    Dim datarow As DataRow = dTable.NewRow

                    datarow.Item(0) = CDate(selectedWell.Item(i).event_date)
                    datarow.Item(1) = CDec(selectedWell.Item(i).result)
                    datarow.Item(2) = CStr(selectedWell.Item(i).rlc)
                    datarow.Item(3) = CStr(selectedWell.Item(i).qa_flag)

                    dTable.Rows.Add(datarow)
                End If


            Next

            Me.DataGridView1.DataSource = dTable.AsDataView
            Me.chtPMR.DataSource = dTable

            Me.chtPMR.DataBind()

            '====== I put this code before and after the databind with the same result =================

            Me.chtPMR.ChartAreas("ChartArea1").AxisX.Minimum = Date.Parse("1988-03-01").ToOADate
            '============================================================================================

            'set up the title
            Me.chtPMR.Titles("Title1").Text = ("Well ID:  " & CStr(Me.ComboBox1.Text) & ":  " & "Cas No:  " & CStr(selectedWell.Item(0).casno) & " " & CStr(selectedWell.Item(0).analyte))
            Me.chtPMR.Titles("Title2").Text = (CStr(getWellGroup.Item(0).tcWellGroup) & " -- Cleanup Level:  " & CStr(selectedWell.Item(0).rlc) & " " & CStr(selectedWell.Item(0).units) & " " & CStr(selectedWell.Item(0).rlc_source))
0
 
Robert SchuttSoftware EngineerCommented:
Ok, if you want me to get it working with this code, I'm gonna need to know what's in "selectedWell" and preferably how your form is set up (from your form's .Designer.vb file for example).

Alternatively we could first try getting the chart right working off the code that was working relatively well when you posted the screen capture of your chart.
0
 
Karen WilsonAuthor Commented:
I'll get that for you.  Meanwhile, I was playing with the Minimum setting on the X axis.  I discovered that when I converted the date 3-01-1988 to a number, 32203 in Excel and pasted that number in here, the setting changed to the date.  Capture4.PNG
Dim getWellGroup = (From id In d.tblWellInformationNews _
                          Where id.wellname = CStr(Me.ComboBox1.SelectedItem) _
                          Select id.wellname, id.tcWellGroup).ToList


        Dim x = CStr(Me.ComboBox2.SelectedItem)
        Dim y = x.Split(";")

        Dim tcIDNo As Integer = y(0).Trim
        Dim tcAnal As String = y(1).Trim

        Dim getAnal = (From id In plot.TC_Parameters _
                      Where id.tcID = tcIDNo _
                      Select id).ToList

        Dim selectedWell = (From id In plot.TC_Datas _
             Where id.wellname = CStr(Me.ComboBox1.SelectedItem) _
             AndAlso id.event_date > CDate("1-1-1988") _
             AndAlso id.casno = CStr(getAnal.Item(0).casno) _
             AndAlso id.analysis = CStr(getAnal.Item(0).analysis) _
             Join tcp In plot.TC_Parameters _
             On id.casno Equals tcp.casno _
             Where tcp.units = CStr("ug/l") _
             Order By id.event_date Ascending _
             Select id.wellname, id.event_date, id.casno, id.analysis, id.analyte, id.result, id.rep_limit, id.extract_efficiency, id.det_limit, tcp.units, tcp.rlc, tcp.rlc_source, id.qa_flag).ToList

        If selectedWell.Count > 0 Then

            Dim dTable As New DataTable

            dTable.Columns.Add("Date", GetType(Date))
            dTable.Columns.Add("Result", GetType(Decimal))
            dTable.Columns.Add("Cleanup Level", GetType(String))
            dTable.Columns.Add("QA Flag", GetType(String))

            For i As Integer = 0 To selectedWell.Count - 1

                If CDec(selectedWell.Item(i).det_limit) > 0 Then

                    Dim datarow As DataRow = dTable.NewRow

                    datarow.Item(0) = CDate(selectedWell.Item(i).event_date)
                    datarow.Item(1) = CDec(selectedWell.Item(i).result)
                    datarow.Item(2) = CStr(selectedWell.Item(i).rlc)
                    datarow.Item(3) = CStr(selectedWell.Item(i).qa_flag)

                    dTable.Rows.Add(datarow)
                End If


            Next

            Me.DataGridView1.DataSource = dTable.AsDataView
            Me.chtPMR.DataSource = dTable

            Me.chtPMR.DataBind()

            '====== I put this code before and after the databind with the same result =================

            Me.chtPMR.ChartAreas("ChartArea1").AxisX.Minimum = Date.Parse("1988-03-01").ToOADate
            '============================================================================================

            'set up the title
            Me.chtPMR.Titles("Title1").Text = ("Well ID:  " & CStr(Me.ComboBox1.Text) & ":  " & "Cas No:  " & CStr(selectedWell.Item(0).casno) & " " & CStr(selectedWell.Item(0).analyte))
            Me.chtPMR.Titles("Title2").Text = (CStr(getWellGroup.Item(0).tcWellGroup) & " -- Cleanup Level:  " & CStr(selectedWell.Item(0).rlc) & " " & CStr(selectedWell.Item(0).units) & " " & CStr(selectedWell.Item(0).rlc_source))

        Else
            Me.DataGridView1.DataSource = Nothing
            Me.chtPMR.DataSource = Nothing
            Me.chtPMR.DataBind()


        End If

I will convert my chart back to when it was working and send the designer code to you.
0
 
Karen WilsonAuthor Commented:
0
 
Karen WilsonAuthor Commented:
Figured you might need some data.
chartData.xlsx
0
 
Robert SchuttSoftware EngineerCommented:
Hmm, for that "get well" code to be useful to me, I'd need your database so let's not go there. I've constructed some temporary test data to work with and after setting the Series properties have no problem showing a datagridview and chart with the data.

I will have a look at the Designer code and see if I can find anything missing.
0
 
Karen WilsonAuthor Commented:
This just in... I was able to grab the old code from that chart...  Capture5.PNG
0
 
Karen WilsonAuthor Commented:
What the engineer wants is to have the spacing flipped.  The results in the chart are evenly spaced out and he wants the years evenly spaced out.  Sorry for the scribble but my regular snipping tool is not available on this computer.  Capture6.PNG
0
 
Robert SchuttSoftware EngineerCommented:
Could be useful, it's a different environment so I guess a different (older) version of the chart component but maybe something jumps out.

I have been comparing .Designer.vb files but my eyes are turning square ;-)

But do I understand correctly that at least you're seeing data again? Because the chart in your form (as I'm trying to recreate it) is blank at the moment...
0
 
Karen WilsonAuthor Commented:
Thanks so much for your efforts.  I have been trying this for two days and can't seem to find the setting.  If you need to head to bed, I see you're in the Netherlands, feel free.

And yes, I am seeing data again.  I think it has to do with the min max settings.  The old code has the max setting as the y_axis.  I think that's just to set the top number on the y-axis.  I'll keep playing and hopefully push the right button!
0
 
Robert SchuttSoftware EngineerCommented:
Well bed-time is still a few hours away here but I'm in the kitchen at the moment.

Well, I may have a stab at getting your data linked into my test project but the link is not clear to me at the moment. I have a completely clear x axis so that's a problem but seems unrelated.

About evenly spacing the x axis: the earlier code "...AxisX.Interval = 1" was meant to do just that and I believe the capture of my test chart shows that it should work. Is it possible that some other code changes that later on?
0
 
Karen WilsonAuthor Commented:
I think that the Axis.Interval = 1 means that a line is drawn at every start of a new year and that works for me.  Notice how 1997 and 1998 are not drawn on the chart.  In doing more research and looking at old code, it appears that the secondary x-axis gets called into play to even things out.  

I sent you all the code I'm using.  Nothing else behind the scenes is happening.
0
 
Robert SchuttSoftware EngineerCommented:
secondary axis? In the Designer code you posted earlier I don't see anything related to a secondary axis (AxisX2), I do see settings regarding ScaleView (ChartArea1.AxisX.ScaleView), maybe that's a clue.
0
 
Karen WilsonAuthor Commented:
I was referring to the the old vb.classic code picture.  I was wrong there anyway.  He was putting in ug/L as the title.  I'm mapping my way to his way and figuring it out.  Old school guys...  they leave and we have this to figure out!!  He did his chart in Access.
0
 
Robert SchuttSoftware EngineerCommented:
Yeah, like I said, I'm afraid that might not help much because it's a different component. Not sure how different but still.

But about those evenly spaced points, if you look at my initial post you can see that that is not the default setting. There is different spacing between the points and I have just slapped a chart on a form and used the code I posted to fill the data and set some series and axis properties. It seems to me that should be the way to go, maybe even just add a new chart to your form (make the current one invisible for example).
0
 
Karen WilsonAuthor Commented:
Too funny, I was just doing that!!  I thought, screw this, I'm going to put a basic chart on here and use his code.  I'll let you know if it works.
0
 
Karen WilsonAuthor Commented:
I am so sorry for all the difficulty!!  I need to remember to KISS (keep it simple, stupid).  It worked!!  I will just pretty it up and call this thing OVER.  

Thanks so much for all of your time.  I sincerely appreciate it.  


0
 
Robert SchuttSoftware EngineerCommented:
Ah, nice! Well we might wake up in the near future in the middle of the night, still wondering what happened, but if you can live with that, so can I ;-)
0
 
Karen WilsonAuthor Commented:
I found it.  I had IsXValueIndexed set to True.  It needs to be False.  My other charts that I need to do this are working without me having to reinvent the wheel.  

Thanks again Robert!
0
 
Robert SchuttSoftware EngineerCommented:
Thanks for posting this, very good for future visitors of this page. Not to mention for my sleep ;-)
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 16
  • 11
Tackle projects and never again get stuck behind a technical roadblock.
Join Now