如何将网络服务返回的 json 数据传递给 D3.json(...)?
How can I pass json data returned from a webservice into D3.json(...)?
感谢您到目前为止的帮助!我能够成功构建我的网络服务和 NVD3.js 堆积面积图。但是,我一直在努力将 json 数据从我的网络服务传递到我的 NVD3.js 图表中,但没有成功。在我的网络表单上,我 select 间隔两个日期,然后单击 "go" 按钮。
我觉得我缺少的东西很明显。如果不可能,是否有办法将从我的网络服务返回的 json 数据保存到常规文件中(例如 myFile.json),以便我可以将其传递到我的图表中?非常感谢您的帮助!这是我最近的尝试:
<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>
这是我的网络服务:
[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;
}
这是从我的网络服务返回的 json 的结构。我在脚本标签中获取文件:
您不需要同时调用 $.ajax
和 d3.json
,这些方法做同样的事情,我只需要使用:
d3.json("dataWebService.asmx/getCasesForDateInterval", function (error, data) {
其次,如果您坚持使用 $.ajax
调用,您的方法实际上是 GET
而不是 POST
,因为您可以在网络浏览器中导航到它。
第三,也是你最大的问题,你的网络服务没有返回 JSON。它返回一个包裹在 XML 中的 JSON 字符串(这是 older Microsoft 基于 SOAP 的 Web 服务的默认值)。您应该能够通过将此属性添加到您的方法顶部来强制 JSON:
[ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
public string getTotalForDateInterval(string startDate, string endDate)
感谢您到目前为止的帮助!我能够成功构建我的网络服务和 NVD3.js 堆积面积图。但是,我一直在努力将 json 数据从我的网络服务传递到我的 NVD3.js 图表中,但没有成功。在我的网络表单上,我 select 间隔两个日期,然后单击 "go" 按钮。
我觉得我缺少的东西很明显。如果不可能,是否有办法将从我的网络服务返回的 json 数据保存到常规文件中(例如 myFile.json),以便我可以将其传递到我的图表中?非常感谢您的帮助!这是我最近的尝试:
<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>
这是我的网络服务:
[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;
}
这是从我的网络服务返回的 json 的结构。我在脚本标签中获取文件:
您不需要同时调用 $.ajax
和 d3.json
,这些方法做同样的事情,我只需要使用:
d3.json("dataWebService.asmx/getCasesForDateInterval", function (error, data) {
其次,如果您坚持使用 $.ajax
调用,您的方法实际上是 GET
而不是 POST
,因为您可以在网络浏览器中导航到它。
第三,也是你最大的问题,你的网络服务没有返回 JSON。它返回一个包裹在 XML 中的 JSON 字符串(这是 older Microsoft 基于 SOAP 的 Web 服务的默认值)。您应该能够通过将此属性添加到您的方法顶部来强制 JSON:
[ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
public string getTotalForDateInterval(string startDate, string endDate)