MVC5 Live刷新Chart.js

时间:2015-03-06 21:09:47

标签: javascript c# asp.net-mvc asp.net-mvc-4 asp.net-mvc-5

我目前正在创建一个信息中心,以显示通过Chart.js从Google Analytics获取的信息。目标是允许用户选择指标,日期和图表间隔,仪表板将调用Google并在单击按钮时更新图表。仪表板是在MVC应用程序中的Visual Studio 2013中创建的。信息中心目前看起来像这样:Dashboard Sample 右边那个画得不好的盒子是我打算按下按钮的地方。我遇到的问题是为按钮创建功能。我对MVC非常陌生,而且我相对肯定我已经打破了逻辑,因为我没有观点。这个应用程序基本上成为控制器查看。 (这是在几十个MVC教程之后发生的事情。

Controller目前看起来像这样:

public enum Metrics{users, newUsers, percentNewSessions,  sessionsPerUser, sessions, bounces, bounceRate, sessionDuration, hits}

public enum Interval{Today, Yesterday, LastWeek, LastTwoWeeks, Daily, Weekly, Monthly, Yearly}

public class HomeController : Controller
{
    public ActionResult Index()
    {
        string accountEmailAddress = "email@thing.com";
        string keyPath = Server.MapPath("path");
        var certificate = new X509Certificate2(keyPath, "blah", X509KeyStorageFlags.Exportable);//Creates certificate

        var credentials = new ServiceAccountCredential(
           new ServiceAccountCredential.Initializer(accountEmailAddress)
           {
               Scopes = new[] { AnalyticsService.Scope.AnalyticsReadonly }
           }.FromCertificate(certificate));//Creates credentials ot GA server

        AnalyticsService service = new AnalyticsService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = credentials,
            ApplicationName = "Dash"
        });//Starts the service up.

        string profileId = "ga:59346790";
        string startDate = "2012-06-07";
        string endDate = "2015-02-17";
        string timing = "Yearly";
        string metrics = "ga:users";
        string[] dates = DateList(startDate, endDate, timing);
        List<string> ColumnName = new List<string>();
        List<double> values = new List<double>();
        if (timing.Equals("Daily"))
        {
            for (int i = 0; i < dates.Length - 1; i++)
            {
                DataResource.GaResource.GetRequest request = service.Data.Ga.Get(profileId, dates[i], dates[i], metrics);
                GaData data = request.Execute();
                ColumnName.Add(DateLabel(dates[i]));
                if (data.Rows == null)
                {
                    values.Add(0);
                }
                else
                {
                    foreach (var row in data.Rows)
                    {
                        foreach (var item in row)
                        {
                            values.Add(Convert.ToDouble(item));
                        }
                    }
                }
            }
        }
        else
        {
            for (int i = 0; i < dates.Length - 2; i+=2)
            {
                DataResource.GaResource.GetRequest request = service.Data.Ga.Get(profileId, dates[i], dates[i + 1], metrics);
                GaData data = request.Execute();
                ColumnName.Add(DateLabel(dates[i]));
                if (data.Rows == null)
                {
                    values.Add(0);
                }
                else
                {
                    foreach (var row in data.Rows)
                    {
                        foreach (var item in row)
                        {
                            values.Add(Convert.ToDouble(item));
                        }
                    }
                }
            }
        }
        List<Metrics> metricList = Enum.GetValues(typeof(Metrics)).Cast<Metrics>().ToList();
        List<Interval> intervalList = Enum.GetValues(typeof(Interval)).Cast<Interval>().ToList();
        ViewBag.Metrics = new SelectList(metricList);            
        ViewBag.Intervals = new SelectList(intervalList);
        values.OrderByDescending(m => values.Min());
        ViewBag.ColumnName = ColumnName.ToArray();
        ViewBag.Values = values.ToArray();
        int[] test = { 3, 5, 6, 7, 3, 8, 9 };
        ViewBag.intArray = test;
        string[] testLabel = { "This", "Is", "A", "Test", "You", "Got", "It?" };
        ViewBag.strArray = testLabel;
        return View();
    }

    private static string DateLabel(string date){ ....code}
    private static string[] DateList(string startDate, string endDate, string timing){...code}
}

这是我的看法:     @ {     ViewBag.Title =&#34;主页&#34 ;;

double[] result = ViewBag.Values;
string[] labels = ViewBag.ColumnName;
string test = "";
string label = "";

for(int i =0; i<= result.Length - 1; ++i)
{
    if(i==0)
    {
        test = test + result[i].ToString();
    }
    else
    {
        test = test + "," + result[i].ToString();
    }
}

for (int i = 0; i <= labels.Length - 1; ++i)
{
    if (i == 0)
    {
        label = label + labels[i].ToString();
    }
    else
    {
        label = label + "," + labels[i].ToString();
    }
}
}
<label for="myChart">
    Google Analytics<br />
     <canvas id="myChart" width="800" height="400"></canvas>
 </label>
<div>
    <label for="Metrics">
        Metrics <br />
        @Html.DropDownList("Metrics", (SelectList)ViewBag.Metrics, new { @class = "form-control" })
    </label>
    <label for="Intervals">
        Interval<br />
        @Html.DropDownList("Intervals", (SelectList)ViewBag.Intervals, new { @class = "form-control" })
    </label>
    <label for="StartDate">
         Start Date<br />
        @Html.TextBox("StartDate")
    </label>
     <label for="EndDate">
        End Date<br />
        @Html.TextBox("EndDate")
    </label>
 </div>

<script>
var result = "@test";
var resultsArray = result.split(',');
var newLabels = "@label";
var labelsArray = newLabels.split(',');
var context = $("#myChart").get(0).getContext("2d");
var data = {
    labels: labelsArray,

    datasets: [{

        label: "My First dataset",
        fillColor: "rgba(220,220,220,0,2)",
        strokeColor: "rgba(220,220,220,1)",
        pointColor: "rgba(220,220,220,1)",
        pointStrokeColor: "#fff",
        pointHighlightFill: "#fff",
        pointHighlightStroke: "rgba(220,220,220,1)",
        data: resultsArray

    }]
}
var options = {
    ///Boolean - Whether grid lines are shown across the chart
    scaleShowGridLines: true,
    //String - Colour of the grid lines
    scaleGridLineColor: "rgba(0,0,0,.05)",
    //Number - Width of the grid lines
    scaleGridLineWidth: 1,
    //Boolean - Whether the line is curved between points
    bezierCurve: true,
    //Number - Tension of the bezier curve between points
    bezierCurveTension: 0.4,
    //Boolean - Whether to show a dot for each point
    pointDot: true,
    //Number - Radius of each point dot in pixels
    pointDotRadius: 4,
    //Number - Pixel width of point dot stroke
    pointDotStrokeWidth: 1,
    //Number - amount extra to add to the radius to cater for hit detection outside the drawn point
    pointHitDetectionRadius: 20,
    //Boolean - Whether to show a stroke for datasets
    datasetStroke: true,
    //Number - Pixel width of dataset stroke
    datasetStrokeWidth: 2,
    //Boolean - Whether to fill the dataset with a colour
    datasetFill: true,

}
var myLineChart = new Chart(context).Line(data, options)

$(document).ready(function () {
    $('#StartDate').datepicker();
    $('#EndDate').datepicker();
});
</script>

如果有人能够通过我当前的代码向我展示如何创建一个按钮来实时刷新仪表板,那将是很棒的,尽管就MVC标准而言,代码有点像FUBAR。我愿意在正确的方向上接受温和(或不那么)的推动。

1 个答案:

答案 0 :(得分:1)

不要在Controller的Index方法中填充图表数据,也不要在加载视图时绘制它。创建一个单独的方法(甚至可以查看WebAPI),它只返回您用来填充图表的JSON数据。调用该方法并在按钮单击中刷新图表。用于填充图表的JavaScript也应位于单独的文件中,不包含在View的文本中。无需重新加载整个页面即可刷新图表。

Google AJAX,如果您想了解更多信息,请点击此处。

我还会考虑使用SignalR,这样您就不需要按钮了,服务器可以在图表可用时将新数据发送到图表,但这可能是一种先进的技术。