4

I am working with DotNet.Highcharts in Visual Studio 2010. I am creating a MVC 3 Web Application. I am able to get HighCharts working by statically assigning the data. I would like to be able to send the data from a database to HighCharts for displaying.

Can I create a class to control the data and then send the class to HighCharts? If so, can anyone tell me how to do this? Also, if someone has a working project that demonstrates this and is willing to share that would be awesome.

I saw someone posted the below class in another question. however, I don't know how to use it or send the class to the HighCharts script. Any help would be greatly appreciated.

class HighChartsPoint
{
    public double x {set; get;}
    public double y {set; get;}
    public string color {set; get;}
    public string id {set; get;}
    public string name {set; get;}
    public bool sliced {set; get;}
} 

EDIT

Well, I am building a web application to display the information from data collected from solar monitoring. So it would be power, voltage, current, and etc grouped by combiner, inverter, and etc. I believe that would be X and Y data. However, if it would be simpler to code via an array of object, then I am all for it. I hope that answered your question. Below are the model classes I have for the data. I am not fully done with them. I still need to add validation and change the fields that link to other tables. To link the combiner_id field in the power_string class to the id field in the power_combiner class would I use: public virtual power_combiner combiner_id { get; set; }

public class AESSmartEntities : DbContext
{
    public DbSet<power_combiner> PowerCombiners { get; set; }
    public DbSet<power_combinerhistory> PowerCombinerHistorys { get; set; }
    public DbSet<power_coordinator> PowerCoordinators { get; set; }
    public DbSet<power_installation> PowerInstallations { get; set; }
    public DbSet<power_inverter> PowerInverters { get; set; }
    public DbSet<power_string> PowerStrings { get; set; }
    public DbSet<power_stringhistory> PowerStringHistorys { get; set; }
}

public class power_combiner
{
    [ScaffoldColumn(false)]
    public int id { get; set; }

    [Required]
    [DisplayName("Name")]
    [StringLength(128, ErrorMessage = "The 'name' cannot be longer than 128 characters")]
    public string name { get; set; }

    [Required]
    [DisplayName("Mac Address")]
    [StringLength(24, ErrorMessage = "The 'mac' cannot be longer than 24 characters")]
    public string mac { get; set; }

    [DisplayName("Location")]
    [StringLength(512, ErrorMessage = "The 'name' cannot be longer than 512 characters")]
    public string location { get; set; }

    [DisplayName("power_installation")]
    public int? installation_id { get; set; }

    [DisplayName("power_inverter")]
    public int? inverter_id { get; set; }

    [DisplayName("power_coordinator")]
    public int coordinator_id { get; set; }

    [DisplayName("Installation ID")]
    public virtual power_installation installation_ { get; set; }

    [DisplayName("Inverter ID")]
    public virtual power_inverter inverter_ { get; set; }

    [DisplayName("Coordinator ID")]
    public virtual power_coordinator coordinator_ { get; set; }
}

public class power_combinerhistory
{
    [ScaffoldColumn(false)]
    public int id { get; set; }

    [Required]
    [DisplayName("Voltage")]
    public double voltage { get; set; }

    [Required]
    [DisplayName("Current")]
    public double current { get; set; }

    [Required]
    [DisplayName("Temperature")]
    public double temperature { get; set; }

    [Required]
    [DisplayName("DateTime")]
    public DateTime recordTime { get; set; }

    [Required]
    [DisplayName("power_combiner")]
    public int combiner_id { get; set; }

    [DisplayName("Combiner ID")]
    public virtual power_combiner combiner_ { get; set; }
}

public class power_coordinator
{
    [ScaffoldColumn(false)]
    public int id { get; set; }

    [Required]
    [DisplayName("Mac Address")]
    [StringLength(24, ErrorMessage = "The 'mac' cannot be longer than 24 characters")]
    public string mac { get; set; }

    [Required]
    [DisplayName("Report Time")]
    public DateTime reportTime { get; set; }

    [Required]
    [DisplayName("Command")]
    [StringLength(2, ErrorMessage = "The 'command' cannot be longer than 2 characters")]
    public string command { get; set; }

    [Required]
    [DisplayName("Collect Time")]
    public int collect_time { get; set; }

    [Required]
    [DisplayName("Interval Time")]
    public int interval_time { get; set; }

    [DisplayName("power_installation")]
    public int? installation_id { get; set; }

    [DisplayName("Installation ID")]
    public virtual power_installation installation_ { get; set; }
}

public class power_installation
{
    [ScaffoldColumn(false)]
    public int id { get; set; }

    [Required]
    [DisplayName("Name")]
    [StringLength(128, ErrorMessage = "The 'name' cannot be longer than 128 characters")]
    public string name { get; set; }

    [Required]
    [DisplayName("UUID")]
    [StringLength(36, ErrorMessage = "The 'uuid' cannot be longer than 36 characters")]
    public string uuid { get; set; }

    [DisplayName("Description")]
    [StringLength(512, ErrorMessage = "The 'description' cannot be longer than 512 characters")]
    public string description { get; set; }

    [DisplayName("History Time")]
    public int historytime { get; set; }
}

public class power_inverter
{
    [ScaffoldColumn(false)]
    public int id { get; set; }

    [Required]
    [DisplayName("Name")]
    [StringLength(128, ErrorMessage = "The 'name' cannot be longer than 128 characters")]
    public string name { get; set; }

    [Required]
    [DisplayName("UUID")]
    [StringLength(36, ErrorMessage = "The 'uuid' cannot be longer than 36 characters")]
    public string uuid { get; set; }

    [Required]
    [DisplayName("Location")]
    [StringLength(512, ErrorMessage = "The 'location' cannot be longer than 512 characters")]
    public string location { get; set; }

    [DisplayName("power_installation")]
    public int installation_id { get; set; }

    [DisplayName("power_coordinator")]
    public int coordinator_id { get; set; }

    [DisplayName("Installation ID")]
    public virtual power_installation installation_ { get; set; }

    [DisplayName("Coordinator ID")]
    public virtual power_coordinator coordinator_ { get; set; }
}

public class power_string
{
    [ScaffoldColumn(false)]
    public int id { get; set; }

    [Required]
    [DisplayName("UUID")]
    [StringLength(36, ErrorMessage = "The 'uuid' cannot be longer than 36 characters")]
    public string uuid { get; set; }

    [Required]
    [DisplayName("Position")]
    public int position { get; set; }

    [DisplayName("Name")]
    [StringLength(128, ErrorMessage = "The 'name' cannot be longer than 128 characters")]
    public string name { get; set; }

    [DisplayName("Location")]
    [StringLength(512, ErrorMessage = "The 'location' cannot be longer than 512 characters")]
    public string location { get; set; }

    [Required]
    [DisplayName("power_combiner")]
    public int combiner_id { get; set; }

    [DisplayName("Combiner ID")]
    public virtual power_combiner combiner_ { get; set; }
}

public class power_stringhistory
{
    [ScaffoldColumn(false)]
    public int id { get; set; }

    [Required]
    [DisplayName("Current")]
    public double current { get; set; }

    [Required]
    [DisplayName("Record Time")]
    public DateTime recordTime { get; set; }

    [Required]
    [DisplayName("power_string")]
    public int string_id { get; set; }

    [DisplayName("String ID")]
    public virtual power_string string_ { get; set; }
}

EDIT

The below code is what I have. I am having problems with the conversion of the date. The GetTotalMilliseconds does not exist in the current context. Is that coming from the HighCharts scripts or is that from some other namespace that I need to include? Also, does it look like I am using the data context correctly to assign the data to the chart? I changed the x value to the combiner id:

.SetSeries(new[]
{
    new Series
    {
        Name = "Combiner",
        YAxis = 0,
        Data = new Data(powercombinerhistorys.Select(mm => new Point { X = mm.combiner_id,  Y = mm.current}).ToArray())
    }
});

and I still get an error. The error is: Unable to cast the type 'System.Int32' to type 'DotNet.Highcharts.Helpers.Number'. LINQ to Entities only supports casting Entity Data Model primitive types.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Drawing;
using DotNet.Highcharts;
using DotNet.Highcharts.Enums;
using DotNet.Highcharts.Helpers;
using DotNet.Highcharts.Options;
using Point = DotNet.Highcharts.Options.Point;
using AESSmart.Models;
using System.Data;
using System.Data.Entity;

namespace AESSmart.Controllers
{
    public class HighChartsTestController : Controller
    {
        private AESSmartEntities db = new AESSmartEntities();

        public ActionResult CombinerHistoryData()
        {
            var powercombinerhistorys = db.PowerCombinerHistorys.Include(p => p.combiner_);

            Highcharts chart = new Highcharts("chart")
            .InitChart(new Chart { DefaultSeriesType = ChartTypes.Column })
            .SetTitle(new Title { Text = "Combiner History" })
            .SetXAxis(new XAxis { Type = AxisTypes.Datetime })
            .SetYAxis(new YAxis
            {
                Min = 0,
                Title = new YAxisTitle { Text = "Current" }
            })
            .SetSeries(new[]
                       {
                           new Series
                           {
                               Name = "Combiner",
                               YAxis = 0,
                               Data = new Data(powercombinerhistorys.Select(x => new Point { X = GetTotalMilliseconds(x.recordTime),  Y = x.current}).ToArray())
                           }
                       });

            return View(chart);
        }
    }
}
Linger
  • 14,942
  • 23
  • 52
  • 79
  • What kind of data you would like to display into the chats? With X and Y data or just array of objects? What is your domain model wich contains the data? – Vangi Mar 06 '12 at 23:15

1 Answers1

4

As I understand you need a chart to display all your values (temperature, voltage, current, etc.). Also I see in the model you have recordTime which can be your xAxis. Here is the example code:

Highcharts chart = new Highcharts("chart")
            .InitChart(new Chart { DefaultSeriesType = ChartTypes.Line })
            .SetTitle(new Title { Text = "Combiner History" })
            .SetXAxis(new XAxis { Type = AxisTypes.Datetime })
            .SetYAxis(new[]
                      {
                          new YAxis
                          {
                              Title = new YAxisTitle { Text = "Current" },
                              GridLineWidth = 1
                          },
                          new YAxis
                          {
                              Labels = new YAxisLabels { Formatter = "function() { return this.value +'°C'; }", },
                              Title = new YAxisTitle { Text = "Temperature" },
                              Opposite = true,
                              GridLineWidth = 0
                          },
                          new YAxis
                          {
                              Labels = new YAxisLabels { Formatter = "function() { return this.value +' V'; }" },
                              Title = new YAxisTitle { Text = "Voltage" },
                              Opposite = true,
                              GridLineWidth = 0
                          }
                      })
            .SetSeries(new[]
                       {
                           new Series
                           {
                               Name = "Current",
                               YAxis = 0,
                               Data = new Data(history.Select(x => new Point { X = GetTotalMilliseconds(x.recordTime), Y = x.current}).ToArray())
                           },
                           new Series
                           {
                               Name = "Temperature",
                               YAxis = 1,
                               Data = new Data(history.Select(x => new Point { X = GetTotalMilliseconds(x.recordTime), Y = x.temperature}).ToArray())
                           },
                           new Series
                           {
                               Name = "Voltage",
                               YAxis = 2,
                               Data = new Data(history.Select(x => new Point { X = GetTotalMilliseconds(x.recordTime), Y = x.voltage}).ToArray())
                           }
                       });

And the result is the following diagram: enter image description here

The second chart which can be interesting for you is the column diagram which compare current values from two measurements with the recorded time. Here is the example code:

Highcharts chart = new Highcharts("chart")
            .InitChart(new Chart { DefaultSeriesType = ChartTypes.Column })
            .SetTitle(new Title { Text = "Combiner History" })
            .SetXAxis(new XAxis { Type = AxisTypes.Datetime })
            .SetYAxis(new YAxis
            {
                Min = 0,
                Title = new YAxisTitle { Text = "Current" }
            })
            .SetSeries(new[]
                       {
                           new Series
                           {
                               Name = "Combiner",
                               YAxis = 0,
                               Data = new Data(combinerhistories.Select(x => new Point { X = GetTotalMilliseconds(x.recordTime), Y = x.current}).ToArray())
                           },
                           new Series
                           {
                               Name = "String",
                               YAxis = 0,
                               Data = new Data(stringhistories.Select(x => new Point { X = GetTotalMilliseconds(x.recordTime), Y = x.current}).ToArray())
                           }
                       });

And here is the chart on the page: enter image description here

I hope this is helpful for you.

Vangi
  • 586
  • 6
  • 20
  • First off, thanks for replying, I really appreciate it. It does look very close to what I am trying to achieve. I am fairly new at using Visual Studio and Highcharts. The way I was able to get highcharts working with static data is to create the chart in a Controller and pass the chart to the view. I would like to implement it that way. So, how do I go about gathering the data from the database and assigning it to history, combinerhistories, and stringhistories so the chart can use it? – Linger Mar 08 '12 at 14:04
  • In the previous examples combinerhistories is IEnumerable and stringhistories is IEnumerable. If you use for example EntityFramework to get the data from database, then you can get from the DataContext like:`using(PowerDatabaseContext context = new PowerDatabaseContext()) { IEnumerable combinerhistory = context.power_combinerhistory; }` – Vangi Mar 09 '12 at 13:27
  • Well I was able to get most of it working the way I want. Using what you have provided above I am 90% of where I need to be. What I am doing is querying the database for the data I need for the chart and then creating an array for each series. I then just pass the array to the chart. Works good. I found it easier to not even use a class to define the HighChartsPoint. I feel with the amount of time spent you deserve the accepted answer. Thanks for your help – Linger Mar 15 '12 at 15:50