How can I pass json data returned from a webservice into D3.json(…)?

安稳与你 提交于 2019-12-24 05:49:22

问题


Thank you for your help so far! I was able to successfully build my webservice and NVD3.js stacked area chart. However, I have been struggling without any success in passing json data from my webservice into my NVD3.js graph. On my webform, I select two dates for an interval and click a "go" button.

I feel that it is something obvious that I am missing. If not possible, is there a way of saving the json data returned from my webservice into a regular file (e.g. myFile.json), so that I can pass it in my graph? Thank you very much for your help! Here is my latest attempt:

<script type="text/javascript">
        $(document).ready(function(){
            $("#btGO").click(function(){
                var startDate = $("#startDate").val();
                var endDate = $("#endDate").val();

                $.ajax({
                    url: "dataWebService.asmx/getCasesForDateInterval",
                    method: "post",
                    data: {
                        startDate: startDate,
                        endDate: endDate
                    },
                    dataType: "json",
                    contentType: "application/json",
                    success: function (data) {
                        //This is where I attempt to pass my json data
                        d3.json(data, function (error, data) {
                            nv.addGraph(function () {
                                var chart = nv.models.stackedAreaChart()
                                              .x(function (d) { return d[0] })
                                              .y(function (d) { return d[1] })
                                              .clipEdge(true)
                                              .useInteractiveGuideline(true);

                                chart._options.controlOptions = ['Expanded', 'Stacked'];

                                chart.xAxis
                                    .showMaxMin(true)
                                    .tickFormat(function (d) { return d3.time.format('%x')(new Date(d)) });

                                chart.yAxis
                                    .tickFormat(d3.format(',.0f'));

                                d3.select('#chart svg')
                                  .datum(data)
                                    .transition().duration(500).call(chart);

                                nv.utils.windowResize(chart.update);

                                return chart;
                            });
                        });
                    }
                });

            });
        });
     </script>

Here is my webservice:

    [WebMethod]
     public string getTotalForDateInterval(string startDate, string endDate)
    {
    string cs = ConfigurationManager.ConnectionStrings["vetDatabase_Wizard"].ConnectionString;
    List<keyValues> master = new List<keyValues>();

    using (SqlConnection con = new SqlConnection(cs))
    {
        SqlCommand cmd = new SqlCommand("sp_CountAndGroupByDate", con);
        cmd.CommandType = CommandType.StoredProcedure;

        //Linking SQL parameters with webmethod parameters
        SqlParameter param1 = new SqlParameter()
        {
            ParameterName = "@startDate",
            Value = startDate
        };

        SqlParameter param2 = new SqlParameter()
        {
            ParameterName = "@endDate",
            Value = endDate
        };

        cmd.Parameters.Add(param1);
        cmd.Parameters.Add(param2);
        con.Open();

        //Get time in milliseconds
        DateTime start = DateTime.ParseExact(startDate, "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture);
        DateTime end = DateTime.ParseExact(endDate, "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture);
        DateTime utime = DateTime.ParseExact("1970-01-01", "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture);

        long startMilliseconds = (long)((start - utime).TotalMilliseconds);
        long endMilliseconds = (long)((end - utime).TotalMilliseconds);
        const long oneDayInMilliseconds = 86400000;

        //Declare temp dictionary to store the lists
        Dictionary<string, List<long[]>> temp = new Dictionary<string, List<long[]>>();
        string[] buildings = { "SSB", "GEN", "LYM", "LUD", "GCC", "MAC", "MMB" };

        //Create building lists and initialize them with individual days and the default value of 0 
        foreach (string building in buildings){
            temp.Add(building, new List<long[]>());
            for (long j = startMilliseconds; j <= endMilliseconds; j = j + oneDayInMilliseconds){
                long[] timeTotal = { j, 0 };
                temp[building].Add(timeTotal);
            }
        }

        SqlDataReader rdr = cmd.ExecuteReader();
        while (rdr.Read())
        {

            //Remove time from dateTime2 and assign totals for appropriate date
            string s = (rdr["dateOpened"].ToString()).Substring(0, 10);
            DateTime dateOpened = DateTime.ParseExact(s, "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture);
            long time = (long)((dateOpened - utime).TotalMilliseconds);
            long total = (long)Convert.ToInt32(rdr["total"]);

            string buildingName = rdr["building"].ToString();
            int index = temp[buildingName].FindIndex(r => r[0].Equals(time));
            temp[buildingName][index][1] = total;
        }
            //add all the keyValue objects to master list
            for (int i = 0; i < buildings.Length; i++)
            {
                keyValues kv = new keyValues();
                kv.key = buildings[i];
                kv.values = temp[kv.key];
                master.Add(kv);
            }

      }
    JavaScriptSerializer js = new JavaScriptSerializer();

    //Serialize list object into a JSON array and write in into the response stream
    string ss = js.Serialize(master);
    return ss;

}

Here is the structure of the json returned from my webservice. I get the file within script tags:


回答1:


You don't need to call both $.ajax and d3.json, these methods do the same thing and I would just use:

 d3.json("dataWebService.asmx/getCasesForDateInterval", function (error, data) {

Second, if you stick with the $.ajax call your method is actually a GET not a POST since you can navigate to it in a web-browser.

Third, and your biggest problem, your web service is not returning JSON. It's returning a JSON string wrapped in XML (this is the default for older Microsoft SOAP based web services). You should be able to force JSON by adding this attribute to top of your methods:

[ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
public string getTotalForDateInterval(string startDate, string endDate)


来源:https://stackoverflow.com/questions/38677142/how-can-i-pass-json-data-returned-from-a-webservice-into-d3-json

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!