我們試圖從基於Silverlight的圖表控件轉移到更多無插件控件。我們喜歡HighCharts,現在正在測試將其實施到我們現有的代碼庫中。 我們發現DotNet.HighCharts是一個可能的競爭者,可以快速創建圖表而不必解析所有的javascript。使用DotNet.HighCharts庫從Webservice創建基於DataTable結果的圖表
我的問題是如何在圖表中使用數據,當它包含在DataTable
內?以下連同回答here我已經看到Linq可能是要走的路。但是我很難獲得代碼來實際構建。 DotNet.HighCharts的文檔沒有顯示任何拉動非靜態數據的例子,所以沒有運氣。這是我的代碼片段至今:
Dim da3 As New SqlDataAdapter(sql3, conn3)
da3.Fill(dt3)
da3.Dispose()
conn3.Close()
Dim chart3 As Highcharts = New Highcharts("chart").InitChart(New Chart() With { _
.PlotShadow = False _
}).SetTitle(New Title() With { _
.Text = "Browser market shares at a specific website, 2010" _
}).SetTooltip(New Tooltip() With { _
.Formatter = "function() { return '<b>'+ this.point.name +'</b>: '+ this.percentage +' %'; }" _
}).SetPlotOptions(New PlotOptions() With { _
.Column = New PlotOptionsColumn With { _
.AllowPointSelect = True, _
.Cursor = Cursors.Pointer, _
.DataLabels = New PlotOptionsColumnDataLabels() With { _
.Color = ColorTranslator.FromHtml("#000000"), _
.Formatter = "function() { return '<b>'+ this.point.name +'</b>: '+ this.percentage +' %'; }" _
} _
} _
}).SetSeries(New Series() With { _
.Type = ChartTypes.Column, _
.Name = "Browser share", _
.Data = New Helpers.Data(dt3.Select(Function(x) New Options.Point() With {.X = x.periodyear, .Y = x.rate}).ToArray()) _
})
ltrChart3.Text = chart3.ToHtmlString()
我輸入以下內容:
Imports DotNet.Highcharts
Imports DotNet.Highcharts.Options
Imports System.Data
Imports System.Data.SqlClient
Imports DotNet.Highcharts.Enums
Imports System.Drawing
Imports System.Collections.Generic
Imports System.Linq
我得到的錯誤是在.Data = New Helpers.Data(dt3.Select(Function(x) New Options.Point() With {.X = x.periodyear, .Y = x.rate}).ToArray()) _
線。我得到Lambda expression cannot be converted to 'String' because 'String' is not a delegate type
作爲我在Function....rate}
位上的錯誤。
編輯: 在修改現有的代碼首先嚐試
Dim chart1 As Highcharts = New DotNet.Highcharts.Highcharts("test")
Dim series As Series = New Series()
series.Name = "CO Rates"
For i As Integer = 0 To dt.Rows.Count - 1
series.Data = New Helpers.Data(New Object() {dt.Rows(i)("periodyear"), dt.Rows(i)("rate")})
Next
chart1.SetSeries(series).InitChart(New Chart() With { _
.Type = ChartTypes.Column})
這只是產生2列中的第一個是在x位置0,它的值是2011,而另一個是在x位置1和它的值是8.3。這是非常奇怪的,因爲它看起來像它正在取數據表中的最後一點,然後將其{x,y}值({2011,8.3})變爲2個不同的點,其中x和y值都是y值如{0,x}和{1,y}。 我需要得到:
- 帶有{periodyear,rate}的單個系列取自dataTable。
- 未來,我希望爲每個位置提供一個系列,其中包含從dataTable獲取的 {periodyear,rate}。
編輯2: 好的,我將其轉換結果,以一個數據字典和我正在圖表來顯示所有的點。現在只有問題是將dt.Rows(i)("periodyear")
轉換爲DateTime值。這是到目前爲止的代碼(其失敗的PaseExact法):
Dim series As Series = New Series()
series.Name = "CO Rates"
Dim xDate As DateTime
Dim data As New Dictionary(Of DateTime, Decimal)
For i As Integer = 0 To dt.Rows.Count - 1
xDate = DateTime.ParseExact(dt.Rows(i)("periodyear").ToString, "YYYY", Globalization.CultureInfo.InvariantCulture)
data.Add(xDate, dt.Rows(i)("rate"))
Next
Dim chartData As Object(,) = New Object(data.Count - 1, 1) {}
Dim x As Integer = 0
For Each pair As KeyValuePair(Of DateTime, Decimal) In data
chartData.SetValue(pair.Key, x, 0)
chartData.SetValue(pair.Value, x, 1)
x += 1
Next
Dim chart1 As Highcharts = New Highcharts("chart1").InitChart(New Chart() With { _
.Type = ChartTypes.Column _
}).SetTitle(New Title() With { _
.Text = "Chart 1" _
}).SetXAxis(New XAxis() With { _
.Type = AxisTypes.Linear _
}).SetSeries(New Series() With { _
.Data = New Helpers.Data(chartData) _
})
如果我改變了只是字符串值(例如1980),然後改變AxisTypes線性爲x軸我做顯示數據。不知何故 - 1980年看起來像1980年。嬰兒的步驟...
編輯N: 這是最終的工作解決方案。這似乎可以使用一些清理。例如,我不知道我需要創建一個字典來放入我的X/Y值,然後遍歷字典以將數據添加到我的chartData對象。這似乎是雙重工作。
Dim stfipsList = (From r In dt.AsEnumerable() Select r("stfips")).Distinct().ToList()
Dim SeriesList As New List(Of Series)(stfipsList.Count)
Dim seriesItem(stfipsList.Count) As Series
Dim xDate As DateTime
Dim fakeDate As String
Dim sX As Integer
sX = 1
For Each state In stfipsList
Dim data As New Dictionary(Of DateTime, Decimal)
Dim stateVal As String = state.ToString
Dim recCount As Integer = dt.Rows.Count - 1
For i As Integer = 0 To recCount
If dt.Rows(i)("stfips").ToString = stateVal Then
fakeDate = "1/1/" + dt.Rows(i)("periodyear").ToString
xDate = DateTime.Parse(fakeDate)
data.Add(xDate.Date, dt.Rows(i)("unemprate"))
End If
Next
Dim chartData As Object(,) = New Object(data.Count - 1, 1) {}
Dim x As Integer = 0
For Each pair As KeyValuePair(Of DateTime, Decimal) In data
chartData.SetValue(pair.Key, x, 0)
chartData.SetValue(pair.Value, x, 1)
x += 1
Next
seriesItem(sX) = New Series With {
.Name = state.ToString, _
.Data = New Helpers.Data(chartData)
}
SeriesList.Add(seriesItem(sX))
sX = sX + 1
Next
Dim chart1 As Highcharts = New Highcharts("chart1").InitChart(New Chart() With { _
.Type = ChartTypes.Line _
}).SetTitle(New Title() With { _
.Text = "Annual Unemployment Rate" _
}).SetTooltip(New Tooltip() With { _
.Formatter = "function() { return '<b>'+ this.series.name + ': ' + Highcharts.dateFormat('%Y', this.x) +'</b>: '+ this.y +' %'; }" _
}).SetXAxis(New XAxis() With { _
.Type = AxisTypes.Datetime _
}).SetYAxis(New YAxis() With { _
.Min = 0, _
.Title = New YAxisTitle() With { _
.Text = "Unemployment Rate", _
.Align = AxisTitleAligns.High _
} _
}).SetSeries(SeriesList.[Select](Function(s) New Series() With { _
.Name = s.Name, _
.Data = s.Data _
}).ToArray())
ltrChart1.Text = chart1.ToHtmlString()
看着討論貼這種我在做什麼。嘗試這只是爲每個數據點導致不同系列的x數量?我得到了爲什麼你想這樣做,因爲當你有多個系列要繪製的時候,我只是想把periodyear和rate值作爲一個集合傳遞給結果集中每一行的圖表。我認爲拋出我的是With {}語法。我會更深入地看看我的代碼。我用我的非工作嘗試更新了我的問題。 – wergeld 2012-04-06 01:31:58