使用HighCharts和DotNet.HighCharts来“播放”多个系列 [英] Using HighCharts and DotNet.HighCharts to "Play" Multiple Series

查看:90
本文介绍了使用HighCharts和DotNet.HighCharts来“播放”多个系列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一套使用VB.NET和DotNet.HighCharts创建的系列:

  Dim SeriesList4As新列表(系列)(stfipsList4.Count)

我想要发生的事情类似于 http://jsfiddle.net/8M2fF/ 。 / p>

创建上述示例的VB代码如下:

  Dim stfipsList4 =(From r In dt4.AsEnumerable()Select r(areaname))。Distinct()。ToList()
Dim SeriesList4 As New List(Of Series)(stfipsList4.Count)
Dim seriesItem4(stfipsList4.Count)As Series
Dim xDate4 As DateTime
Dim fakeDate4 As String
Dim sX4 As Integer

sX4 = 1
For Each state在stfipsList4
中Dim data As New Dictionary(Of DateTime,Decimal)
D im stateVal As String = state.ToString
Dim recCount As Integer = dt4.Rows.Count - 1
Dim seriesPointCount As Integer = dt4.Compute(Count(population),areaname ='+ stateVal +')
Dim xData As As Object(,)= New Object(seriesPointCount - 1,1){}
Dim x As Integer = 0
For i As Integer = 0 To recCount
如果dt4.Rows(i)(areaname)。ToString = stateVal Then
fakeDate4 =1/1 /+ dt4.Rows(i)(periodyear)。ToString
xDate4 = DateTime.Parse(fakeDate4)
chartData.SetValue(xDate4.Date,x,0)
chartData.SetValue(dt4.Rows(i)(population),x,1)
x + = 1
结束如果

下一个

seriesItem4(sX4)=新系列With {
.Name = state.ToString, _
.Data =新助手.Data(chartData)
}

SeriesList4.Add(seriesItem4(sX4))

sX4 = sX4 + 1
Next

Dim iterateData As String = JsonSerializer.Serialize(seriesItem4(1))

Dim chart4 As Highcharts = New Highcharts(chart4)。SetOptions(New Helpers.GlobalOptions()With {_
。[Global] = New [Global]()With {_
.UseUTC = False _
} _
})。InitChart(New Chart()With {_
.DefaultSeriesType = ChartTypes.Column,_
.MarginRight = 10,_
.Events = New ChartEvents()With {_
.Load =ChartEventsLoad_
} ($ _
.Text =Population_
})。SetTooltip(New Tooltip()With {_
.Formatter =function(){r eturn'< b>'+ this.series.name +'< br />'+ Highcharts.dateFormat('%Y',this.x)+'< / b>'+ Highcharts.numberFormat this.y,0,','); SetXAxis(New XAxis()With {_
.Type = AxisTypes.Datetime,_
.TickPixelInterval = 150 _
}}。SetYAxis(New YAxis()With {_
.Min = 0,_
.Title = New YAxisTitle()With {_
.Text =Population,_
.Align = AxisTitleAligns (New Series()with {_
.Data = New Helpers.Data(New Object(){})_
}。 )_
.SetOptions(New Helpers.GlobalOptions()With {_
.Colors = palette_colors _
})_
.AddJavascripVariable(iterated,iterateData.ToString)_
.AddJavascripFunction(ChartEventsLoad,//设置每秒更新图表& vbCr& vbLf& _
var result = iterated.data;& vbCr& vbLf& _
var counter = 0; &安培; vbCr& vbLf& _
var series = this.series [0]; &安培; vbCr& vbLf& _
var loopseries = function(){& vbCr& vbLf& _
if(counter< = result.length){& vbCr& vbLf& _
var p = String(result [counter]); &安培; vbCr& vbLf& _
var splitp = p.split(,); &安培; vbCr& vbLf& _
var x = Number(splitp [0]); &安培; vbCr& vbLf& _
var y = Number(splitp [1]); &安培; vbCr& vbLf& _
series.addPoint([x,y],true,series.points.length> 10,true); &安培; vbCr& vbLf& _
counter ++; &安培; vbCr& vbLf& _
} else {& vbCr& vbLf& _
clearInterval(loopseries); &安培; vbCr& vbLf& _
}}; &安培; vbCr& vbLf& _
setInterval(loopseries,300);)

ltrChart4.Text = chart4.ToHtmlString()

这仅适用于单个系列。我想通过一个列表(系列)。
需要参与的事情:
创建n个系列
为每个系列添加点数
为每个系列命名



我可以处理这些物品,它只是通过我无法完成的主要系列清单。



编辑:
似乎有一些混淆我在问什么。我可以通过DotNet.HighCharts API将N个系列传递给HighCharts。我目前无法做到的是将这一系列相同的系列文件传递给javascript函数以循环播放该系列文件。请参阅:

  .AddJavascripVariable(iterated,iterateData.ToString)_ 
.AddJavascripFunction(ChartEventsLoad, //设置每秒更新图表& vbCr& vbLf& _
var result = iterated.data;& vbCr& vbLf& _
var计数器= 0;& vbCr& vbLf& _
var series = this.series [0];& vbCr& vbLf& _
var loopseries = function() {& vbCr& vbLf& _
if(counter< = result.length){& vbCr& vbLf& _
var p = String(result [counter ]);& vbCr& vbLf& _
var splitp = p.split(,);& vbCr& vbLf& _
var x = Number(splitp [0]);& vbCr &安培; vbLf& _
var y = Number(splitp [1]); &安培; vbCr& vbLf& _
series.addPoint([x,y],true,series.points.length> 10,true); &安培; vbCr& vbLf& _
counter ++; &安培; vbCr& vbLf& _
} else {& vbCr& vbLf& _
clearInterval(loopseries); &安培; vbCr& vbLf& _
}}; &安培; vbCr& vbLf& _
setInterval(loopseries,300);)

.AddJavaScriptVariable需要一个字符串并在内部代码给我无效的对象引用。

解决方案

我实际上使用DotNet.Highcharts来创建一个图表,未定义数量的系列。为此,我使用linq查询需要添加到图表的数据。我使用对象[]的列表来创建单个点,然后我将该列表添加到系列列表中。我遍历循环的次数达到了我需要的所有系列。然后为SetSeries分配系列列表中包含的内容。代码是用C#编写的,但我相信你可以将它改为VB.NET。这是我用来创建图表的整个ActionResult:

  public ActionResult CombinerBarToday(DateTime?utcStartingDate = null,
DateTime?utcEndingDate = null)
{
//获取指定日期时间的生成读数
var firstQ = from db.PowerCombinerHistorys
在db.PowerCombiners中加入u s.combiner_id等于u.id
其中s.recordTime> = utcStartingDate
其中s.recordTime< = utcEndingDate
选择新的
{
CombinerID = u。名称,
Current = s.current,
RecordTime = s.recordTime,
电压= s.voltage,
Watts =(s.current * s.voltage)
};

//获取包含在QUERY中的组合列表
var secondQ =(从firstQ
中选择新的
{
Combiner = s .CombinerID
})。Distinct();

/ *此系列清单将用于动态地添加许多系列
*至所需的高级版本,而无需创建每个系列的个人资料* /
列出<系列> allSeries =新列表< Series>();

TimeZoneInfo easternZone = TimeZoneInfo.FindSystemTimeZoneById(东部标准时间);

//通过每个组合器创建系列并创建系列
foreach(secondQ中的var distinctCombiner)
{
var combinerDetail = from db2.PowerCombinerHistorys
加入你在db2.PowerCombiners上的s.combiner_id等于u.id
其中u.name == distinctCombiner.Combiner
其中s.recordTime> = utcStartingDate
其中s.recordTime< = utcEndingDate
选择新的
{
CombinerID = u.name,
Current = s.current,
RecordTime = s.recordTime,
电压= s。电压,
Watts =(sCurrent * s.voltage)/ 1000d
};


var results = new List< object []>();

foreach(combinerCombiner in combinerDetail)
{
results.Add(new object [] {
TimeZoneInfo.ConvertTimeFromUtc(detailCombiner.RecordTime,easternZone),
detailCombiner.Watts});


allSeries.Add(新系列
{
名称= distinctCombiner.Combiner,
// Data = new Data(myData)
Data = new Data(results.ToArray())

});
}

Highcharts chart = new Highcharts(chart)
.InitChart(新图表{DefaultSeriesType = ChartTypes.Spline,ZoomType = ZoomTypes.X})
.SetTitle(新标题{Text =组合历史})
.SetSubtitle(新Subtitle {文本=单击并拖动绘图区以放大})
.SetOptions(new GlobalOptions { Global = new Global {UseUTC = false}})
.SetPlotOptions(new PlotOptions
{
Spline = new PlotOptionsSpline
{
LineWidth = 2,
States = new PlotOptionsSplineStates {Hover = new PlotOptionsSplineStatesHover {LineWidth = 3}},
Marker = new PlotOptionsSplineMarker
{
Enabled = false,
States = new PlotOptionsSplineMarkerStates
{
Hover = new PlotOptionsSplineMarkerStatesHover
{
Enabled = tru e,
Radius = 5,
LineWidth = 1
}
}
}
}
})
.SetXAxis新的XAxis
{
Type = AxisTypes.Datetime,
Labels = new XAxisLabels
{
Rotation = -45,
Align = Horizo​​ntalAligns.Right,
Style =font:'normal 10px Verdana,sans-serif'
},
Title = new XAxisTitle {Text =Time(Hour)},
})
。SetYAxis(new YAxis
{
Title = new YAxisTitle {Text =Kilowatt}
})

.SetSeries(allSeries.Select(s => new Series {Name = s.Name,Data = s.Data})。ToArray());

返回PartialView(图表);
}


I have a set of series that I have created using VB.NET and DotNet.HighCharts:

Dim SeriesList4As New List(Of Series)(stfipsList4.Count)

What I want to have happen is something similar to http://jsfiddle.net/8M2fF/ except I want to be able to pass in multiple series without knowing before hand how many I have.

The VB code that created that example above is this:

        Dim stfipsList4 = (From r In dt4.AsEnumerable() Select r("areaname")).Distinct().ToList()
        Dim SeriesList4 As New List(Of Series)(stfipsList4.Count)
        Dim seriesItem4(stfipsList4.Count) As Series
        Dim xDate4 As DateTime
        Dim fakeDate4 As String
        Dim sX4 As Integer

        sX4 = 1
        For Each state In stfipsList4
            Dim data As New Dictionary(Of DateTime, Decimal)
            Dim stateVal As String = state.ToString
            Dim recCount As Integer = dt4.Rows.Count - 1
            Dim seriesPointCount As Integer = dt4.Compute("Count(population)", "areaname = '" + stateVal + "'")
            Dim chartData As Object(,) = New Object(seriesPointCount - 1, 1) {}
            Dim x As Integer = 0
            For i As Integer = 0 To recCount
                If dt4.Rows(i)("areaname").ToString = stateVal Then
                    fakeDate4 = "1/1/" + dt4.Rows(i)("periodyear").ToString
                    xDate4 = DateTime.Parse(fakeDate4)
                    chartData.SetValue(xDate4.Date, x, 0)
                    chartData.SetValue(dt4.Rows(i)("population"), x, 1)
                    x += 1
                End If

            Next

            seriesItem4(sX4) = New Series With {
                        .Name = state.ToString, _
                        .Data = New Helpers.Data(chartData)
            }

            SeriesList4.Add(seriesItem4(sX4))

            sX4 = sX4 + 1
        Next

        Dim iterateData As String = JsonSerializer.Serialize(seriesItem4(1))

            Dim chart4 As Highcharts = New Highcharts("chart4").SetOptions(New Helpers.GlobalOptions() With { _
                .[Global] = New [Global]() With { _
                        .UseUTC = False _
                    } _
                }).InitChart(New Chart() With { _
                 .DefaultSeriesType = ChartTypes.Column, _
                 .MarginRight = 10, _
                 .Events = New ChartEvents() With { _
                  .Load = "ChartEventsLoad" _
                 } _
                }).SetTitle(New Title() With { _
                 .Text = "Population" _
                }).SetTooltip(New Tooltip() With { _
                    .Formatter = "function() { return '<b>' + this.series.name + '<br/>' + Highcharts.dateFormat('%Y', this.x) +'</b>: '+ Highcharts.numberFormat(this.y, 0, ','); }" _
                }).SetXAxis(New XAxis() With { _
                 .Type = AxisTypes.Datetime, _
                 .TickPixelInterval = 150 _
                }).SetYAxis(New YAxis() With { _
                       .Min = 0, _
                       .Title = New YAxisTitle() With { _
                        .Text = "Population", _
                        .Align = AxisTitleAligns.High _
                        } _
                }).SetSeries(New Series() With { _
                     .Data = New Helpers.Data(New Object() {}) _
                }) _
                .SetOptions(New Helpers.GlobalOptions() With { _
                .Colors = palette_colors _
                }) _
                .AddJavascripVariable("iterated", iterateData.ToString) _
                .AddJavascripFunction("ChartEventsLoad", "// set up the updating of the chart each second" & vbCr & vbLf & _
                                  " var result = iterated.data;" & vbCr & vbLf & _
                                  " var counter = 0;" & vbCr & vbLf & _
                                  " var series = this.series[0];" & vbCr & vbLf & _
                                  " var loopseries = function() {" & vbCr & vbLf & _
                                  " if (counter <= result.length) {" & vbCr & vbLf & _
                                  " var p = String(result[counter]);" & vbCr & vbLf & _
                                  " var splitp = p.split("","");" & vbCr & vbLf & _
                                  " var x = Number(splitp[0]);" & vbCr & vbLf & _
                                  " var y = Number(splitp[1]);" & vbCr & vbLf & _
                                  " series.addPoint([x, y], true, series.points.length > 10, true);" & vbCr & vbLf & _
                                  " counter++;" & vbCr & vbLf & _
                                  " } else {" & vbCr & vbLf & _
                                  " clearInterval(loopseries);" & vbCr & vbLf & _
                                  " }};" & vbCr & vbLf & _
                                  " setInterval(loopseries, 300);")

        ltrChart4.Text = chart4.ToHtmlString()

This is just for a single series. I would like to pass in a List(Of Series). Things that need to be involved: Creating n number of series Adding points to each series Naming each series

I can handle those items it is just passing in the master series "list" that I cannot accomplish.

EDIT: There seems to be some confusion on what I am asking. I am able to pass N number of series to HighCharts via the DotNet.HighCharts API. What I am not currently able to do is pass this same set of series to the javascript function to loop through and "play" the series. Please see:

            .AddJavascripVariable("iterated", iterateData.ToString) _
            .AddJavascripFunction("ChartEventsLoad", "// set up the updating of the chart each second" & vbCr & vbLf & _
                              " var result = iterated.data;" & vbCr & vbLf & _
                              " var counter = 0;" & vbCr & vbLf & _
                              " var series = this.series[0];" & vbCr & vbLf & _
                              " var loopseries = function() {" & vbCr & vbLf & _
                              " if (counter <= result.length) {" & vbCr & vbLf & _
                              " var p = String(result[counter]);" & vbCr & vbLf & _
                              " var splitp = p.split("","");" & vbCr & vbLf & _
                              " var x = Number(splitp[0]);" & vbCr & vbLf & _
                              " var y = Number(splitp[1]);" & vbCr & vbLf & _
                              " series.addPoint([x, y], true, series.points.length > 10, true);" & vbCr & vbLf & _
                              " counter++;" & vbCr & vbLf & _
                              " } else {" & vbCr & vbLf & _
                              " clearInterval(loopseries);" & vbCr & vbLf & _
                              " }};" & vbCr & vbLf & _
                              " setInterval(loopseries, 300);")

The .AddJavaScriptVariable expects a string and in-lining the code is giving me invalid object references.

解决方案

I actually use DotNet.Highcharts to create a chart that has an undefined number of series. To do this I query for the data I need to add to the chart using linq. I use a list of object[] to create the individual points then I take that list and add it to a list of Series. I iterate through the loop as many times as I need to get all of the Series. Then for SetSeries I assign what was contained in the Series list. The code is written in C# but I am sure you can change it to VB.NET. Here is the entire ActionResult I use for creating the chart:

public ActionResult CombinerBarToday(DateTime? utcStartingDate = null,
                                     DateTime? utcEndingDate = null)
{
    //GET THE GENERATED POWER READINGS FOR THE SPECIFIED DATETIME
    var firstQ = from s in db.PowerCombinerHistorys
                 join u in db.PowerCombiners on s.combiner_id equals u.id
                 where s.recordTime >= utcStartingDate
                 where s.recordTime <= utcEndingDate
                 select new
                 {
                     CombinerID = u.name,
                     Current = s.current,
                     RecordTime = s.recordTime,
                     Voltage = s.voltage,
                     Watts = (s.current * s.voltage)
                 };

    //GET A LIST OF THE COMBINERS CONTAINED IN THE QUERY
    var secondQ = (from s in firstQ
                   select new
                   {
                        Combiner = s.CombinerID
                   }).Distinct();

    /* THIS LIST OF SERIES WILL BE USED TO DYNAMICALLY ADD AS MANY SERIES 
     * TO THE HIGHCHARTS AS NEEDED WITHOUT HAVING TO CREATE EACH SERIES INDIVIUALY */
    List<Series> allSeries = new List<Series>();

    TimeZoneInfo easternZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");

    //LOOP THROUGH EACH COMBINER AND CREATE SERIES
    foreach (var distinctCombiner in secondQ)
    {
        var combinerDetail = from s in db2.PowerCombinerHistorys
                 join u in db2.PowerCombiners on s.combiner_id equals u.id
                 where u.name == distinctCombiner.Combiner
                 where s.recordTime >= utcStartingDate
                 where s.recordTime <= utcEndingDate
                 select new
                 {
                     CombinerID = u.name,
                     Current = s.current,
                     RecordTime = s.recordTime,
                     Voltage = s.voltage,
                     Watts = (s.current * s.voltage) / 1000d
                 };


        var results = new List<object[]>();

        foreach (var detailCombiner in combinerDetail)
        {
            results.Add(new object[] { 
                            TimeZoneInfo.ConvertTimeFromUtc(detailCombiner.RecordTime, easternZone), 
                            detailCombiner.Watts });
        }

        allSeries.Add(new Series
        {
            Name = distinctCombiner.Combiner,
            //Data = new Data(myData)
            Data = new Data(results.ToArray())

        });
    }

    Highcharts chart = new Highcharts("chart")
    .InitChart(new Chart { DefaultSeriesType = ChartTypes.Spline, ZoomType = ZoomTypes.X})
    .SetTitle(new Title { Text = "Combiner History" })
    .SetSubtitle(new Subtitle { Text = "Click and drag in the plot area to zoom in" })
    .SetOptions(new GlobalOptions { Global = new Global { UseUTC = false } })
    .SetPlotOptions(new PlotOptions
    {
        Spline = new PlotOptionsSpline
        {
            LineWidth = 2,
            States = new PlotOptionsSplineStates { Hover = new PlotOptionsSplineStatesHover { LineWidth = 3 } },
            Marker = new PlotOptionsSplineMarker
            {
                Enabled = false,
                States = new PlotOptionsSplineMarkerStates
                {
                    Hover = new PlotOptionsSplineMarkerStatesHover
                    {
                        Enabled = true,
                        Radius = 5,
                        LineWidth = 1
                    }
                }
            }
        }
    })
    .SetXAxis(new XAxis
    {
        Type = AxisTypes.Datetime,
        Labels = new XAxisLabels
        {
            Rotation = -45,
            Align = HorizontalAligns.Right,
            Style = "font: 'normal 10px Verdana, sans-serif'"
        },
        Title = new XAxisTitle { Text = "Time(Hour)" },
    })
    .SetYAxis(new YAxis
    {
        Title = new YAxisTitle { Text = "Kilowatt" }
    })

    .SetSeries(allSeries.Select(s => new Series {Name = s.Name, Data = s.Data }).ToArray());

    return PartialView(chart);
}

这篇关于使用HighCharts和DotNet.HighCharts来“播放”多个系列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆