2016-07-30 38 views
1

Vielen Dank für Ihre Hilfe bis jetzt! Ich konnte mein webservice und NVD3.js gestapeltes Bereichsdiagramm erfolgreich errichten. Ich habe jedoch ohne Erfolg versucht, JSON-Daten von meinem Webservice in mein NVD3.js-Diagramm zu übertragen. In meinem Webformular wähle ich zwei Daten für ein Intervall aus und klicke auf "Gehe".Wie kann ich von einem Webservice zurückgegebene JSON-Daten an D3.json (...) übergeben?

Ich fühle, dass es etwas offensichtlich ist, dass ich vermisse. Wenn es nicht möglich ist, gibt es eine Möglichkeit, die von meinem Webservice zurückgegebenen JSON-Daten in einer normalen Datei (z. B. myFile.json) zu speichern, damit ich sie in meinem Diagramm weitergeben kann? Vielen Dank für Ihre Hilfe! Hier ist mein letzter Versuch:

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

Hier ist meine 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; 

} 

Hier ist die Struktur der json von meinem Webservice zurückgegeben. Ich erhalte die Datei innerhalb von Script-Tags:

enter image description here

+0

Ein Wort des Rates: Sie öffnen eine Menge von doppelten Fragen zu diesem Thema. In einigen von ihnen haben die Leute Kommentare und Antworten geliefert, auf die Sie nicht geantwortet haben. Dies ist sehr gegen die Überlauf-Etikette und wird Benutzer dazu bringen, Ihnen nicht zu helfen. Zum Beispiel die Antwort, die ich unten gebe [dupliziert eine Antwort] (http://stackoverflow.com/a/37759986/16363) @cyril gab Ihnen vor über einem Monat. – Mark

+0

@Mark Hallo Markus! Vielen Dank für Ihre Antwort. Ich stimme dir zu: Ich habe sehr ähnliche/duplizierte Fragen gepostet, während ich nicht antwortete, und es sieht schlecht aus. Die Lösungen funktionierten nicht, da einige Fehler nicht mit dem Google-Inspektor in Verbindung gebracht wurden. Trotzdem hätte ich ihnen antworten sollen. Ich bin manchmal so konzentriert, dass es gegenüber anderen respektlos wird. Ich entschuldige mich dafür. – Johnathan

Antwort

1

Sie brauchen nicht beide $.ajax und d3.json zu nennen, haben diese Methoden die gleiche Sache und ich würde nur verwenden:

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

Zweitens, Wenn Sie mit dem $.ajax Anruf bleiben Ihre Methode ist eigentlich ein GET kein POST seit Sie in einem Web-Browser zu ihm navigieren können.

Drittens, und Ihr größtes Problem, Ihr Web-Service gibt JSON nicht zurück. Es gibt eine JSON-Zeichenfolge zurück, die in XML eingebettet ist (dies ist die Standardeinstellung für ältere Microsoft SOAP-basierte Webdienste). Sie sollten in der Lage sein, JSON zu erzwingen, indem Sie dieses Attribut an die Spitze Ihrer Methoden hinzufügen:

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