2012-04-20 21 views
5

Tengo un conjunto de series que he creado usando VB.NET y DotNet.HighCharts:Highcharts y DotNet.HighCharts en "PLAY" múltiple Serie

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

Lo que queremos que suceda es algo similar a http://jsfiddle.net/8M2fF/ excepto que quiero poder pasar varias series sin saber de antemano cuántas tengo.

El código VB que crea que el ejemplo anterior es la siguiente:

 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() 

esto es sólo para una sola serie. Me gustaría pasar una lista (de series). cosas que necesitan ser involucrados: Creación número n de serie puntos añadiendo a cada serie nombrando cada serie

puedo manejar esos artículos que sólo está pasando en la "lista" serie maestra que no puedo lograr.

EDITAR: Parece haber cierta confusión en lo que estoy preguntando. Puedo pasar N series a HighCharts a través de la API DotNet.HighCharts. Lo que actualmente no puedo hacer es pasar este mismo conjunto de series a la función javascript para recorrer y "reproducir" la serie. Por favor ver:

  .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);") 

El .AddJavaScriptVariable espera una cadena y en el revestimiento del código me está dando referencias a objetos no válidos.

Respuesta

5

De hecho, uso DotNet.Highcharts para crear un gráfico que tiene un número indefinido de series. Para hacer esto, consulto los datos que necesito agregar al gráfico usando linq. Utilizo una lista de objetos [] para crear puntos individuales, luego tomo esa lista y la agrego a una lista de Series. Repito el ciclo tantas veces como necesito para obtener todas las Series. Luego, para SetSeries, asigno lo que estaba contenido en la lista de Series. El código está escrito en C#, pero estoy seguro de que puedes cambiarlo a VB.NET. Aquí está todo el ActionResult que uso para crear el gráfico:

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); 
} 
+0

No tengo ningún problema para obtener una lista de series. Eso es lo que está haciendo mi For 'Each state In stfipsList4'. Y puedo iterar a través de esa lista para agregar la serie al gráfico sin problemas utilizando el método predeterminado. Para qué sirve esta pregunta es para animar/reproducir la serie a través del tiempo (no confundirla con la animación de carga por defecto de HighCharts). Vea mi jsFiddle por lo que estaba tratando de lograr, pero con solo 1 serie. Mi problema es que no estoy seguro de cómo pasar la lista de series a la función javascript que itera y hace series.addpoint. – wergeld

+0

Entiendo que esta respuesta es una gran solución general para agregar series múltiples a HighCharts utilizando la API DotNet.HighCharts, pero no atiende la pregunta planteada. Lo que hace es simplemente agregar todas las series de la lista de series a la vez al gráfico. No reproduce los puntos de serie como se describe en el ejemplo jsFiddle. – wergeld

+0

Originalmente leí mal su pregunta. Lo siento. No sé por qué la gente lo está votando. Es una buena forma de usar DotNet.Highcharts. Pero como lo mencionaste, no responde tu pregunta. – Linger

Cuestiones relacionadas