Javascript 在d3.js图表中回显JSON
我用Javascript 在d3.js图表中回显JSON,javascript,php,sql-server,json,d3.js,Javascript,Php,Sql Server,Json,D3.js,我用d3.js创建了一个图表,如果将鼠标悬停在月份上,就会找到每周的分数 我在这里谈论的图表的小提琴链接: 我的数据库中也有一个表格,用于保存员工每周的分数记录。您在这里看到的仅为四周-(第一周到第四周),但在我的数据库中,我有每月所有周的记录。这仅供参考 表点存储: 用户登录后,我只想显示该用户的相关分数。假设Rob登录,他第一周的分数是47,第二周是44,第三周是44,第四周是43 问题:我正在使用php从SQL服务器提取json。下面的PHP文件就是这样做的 问题是如何将JSON放入d3.
d3.js
创建了一个图表,如果将鼠标悬停在月份上,就会找到每周的分数
我在这里谈论的图表的小提琴链接:
我的数据库中也有一个表格,用于保存员工每周的分数记录。您在这里看到的仅为四周-(第一周到第四周),但在我的数据库中,我有每月所有周的记录。这仅供参考
表点存储:
用户登录后,我只想显示该用户的相关分数。假设Rob登录,他第一周的分数是47,第二周是44,第三周是44,第四周是43
问题:我正在使用php从SQL
服务器提取json。下面的PHP
文件就是这样做的
问题是如何将JSON
放入d3.js
文件,即上面的小提琴。
请帮忙
json
文件(让我们把它命名为data.php
):我知道我需要在上面的d3.js
文件中包含这个data.php
。但不确定如何
<?php
session_start();
$servername = "xxxxxxx";
$connectioninfo = array(
'Database' => 'xxxxxx'
);
$conn = sqlsrv_connect($servername, $connectioninfo);
if ($conn) {
echo 'connection established';
}
else {
echo 'connection failure';
die(print_r(sqlsrv_errors() , TRUE));
}
$q1 = "SELECT WeekNumber,pointsRewarded,EmployeeID FROM pointsBadgeTable WHERE EmployeeID = '" . $_SESSION['id'] . "' ";
$stmt = sqlsrv_query($conn, $q1);
if ($stmt == false) {
echo 'error to retrieve info !! <br/>';
die(print_r(sqlsrv_errors() , TRUE));
}
do {
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$result[] = $row;
}
}
while (sqlsrv_next_result($stmt));
sqlsrv_free_stmt($stmt);
sqlsrv_close($conn); //Close the connnectiokn first
echo json_encode($result); //You will get the encoded array variable
?>
1:返回JSON
由于您希望以json
格式返回数据,因此请记住在响应头中设置内容类型,并删除成功的连接echo
,因为它会弄乱结果:
<?php
session_start();
$servername = "xxxxxxx";
$connectioninfo = array(
'Database' => 'xxxxxx'
);
$conn = sqlsrv_connect($servername, $connectioninfo);
if (!$conn) {
echo 'connection failure';
die(print_r(sqlsrv_errors() , TRUE));
}
$q1 = "SELECT WeekNumber,pointsRewarded,EmployeeID FROM pointsBadgeTable WHERE EmployeeID = '" . $_SESSION['id'] . "' ";
$stmt = sqlsrv_query($conn, $q1);
if ($stmt == false) {
echo 'error to retrieve info !! <br/>';
die(print_r(sqlsrv_errors() , TRUE));
}
do {
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$result[] = $row;
}
}
while (sqlsrv_next_result($stmt));
sqlsrv_free_stmt($stmt);
sqlsrv_close($conn); //Close the connnectiokn first
//Set content type to json
header('Content-Type: application/json');
//Echo a json object to the browser
echo json_encode($result);
?>
或者,在香草JS中:
httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = function() {
if (httpRequest.readyState === XMLHttpRequest.DONE) {
if (httpRequest.status === 200) {
var data = httpRequest.responseText;
//Do stuff with data here
}
}
};
httpRequest.open('GET', "path/to/data.php");
httpRequest.send();
3:使用数据
现在我们有了来自服务器的数据,但它的格式不适合图形,我们该怎么办
根据您的评论,Ajax请求以如下格式返回数据:
[{
"WeekNumber": "week49",
"pointsRewarded": 50,
"EmployeeID": 100739
}, {
"WeekNumber": "week51",
"pointsRewarded": 50,
"EmployeeID": 100739
}, {
"WeekNumber": "week50",
"pointsRewarded": 50,
"EmployeeID": 100739
}]
但是,查看您的JSFIDLE,它需要一种完全不同的格式,因此很明显我们需要更改格式
首先,我们需要解析对象,以便获得所有正确的数据:
function ParseData(data) {
var parsed = {};
var months = ['January - 2016', 'February - 2016', 'March - 2016', 'April - 2016', 'May - 2016', 'June - 2016', 'July - 2016', 'August - 2016', 'September - 2016', 'October - 2016', 'November - 2016', 'December - 2016'];
data.forEach(function(item) {
var week = parseInt(item.WeekNumber.slice(4)),
month = Math.floor((week - 1) / 4);
if (!parsed[month]) parsed[month] = {
weeks: [],
points: 0,
month: months[month - 1]
}
var weekLabel = "Week " + week + ": " + item.pointsRewarded;
parsed[month].weeks.push(weekLabel);
parsed[month].points += item.pointsRewarded;
});
return FormatData(parsed);
}
我们在那里所做的就是循环结果,并用相关信息构建一个对象。接下来,我们需要格式化数据,使其与图表一起工作。因为我们已经有了解析的数据,这很简单:
function FormatData(data) {
var formatted = {
points: [],
weeks: [],
months: []
};
for (var month in data) {
var now = data[month];
formatted.points.push(now.points);
formatted.months.push(now.month);
formatted.weeks.push(now.weeks.join("<br>"));
}
return formatted;
}
现在,只需将所有数据放在一起,并用数据呈现图表:
$.get("path/to/data.php", function(data){
//Get data
var parsedData = ParseData(data);
//Render chart
InitChart(parsedData);
});
不要忘记设置正确的ajax URL。运行第一个代码段会给出
“未捕获引用错误:$未定义”
如果要在javascript中包含PHP,请确保脚本位于PHP文件中。如果您的javascript位于不同的文件中,您可能希望使用http请求,使用$.ajax()从PHP文件中请求数据。@Kingsthor看起来不错。但它在这里不起作用。总之,谢谢。有帮助吗?@MaximilianPetters不幸没有。我在发布问题之前检查了它,因为它是stackoverflow中唯一的问题,与我的问题有关。无论如何,谢谢。谢谢你的输入。我会尝试你所说的。我会回复你的。但是我如何将数据拉到上面的javascript中呢fiddle@janeajax
请求返回数据。谢谢。我会回复你的。Jacob,我想没有PDO也可以。
function FormatData(data) {
var formatted = {
points: [],
weeks: [],
months: []
};
for (var month in data) {
var now = data[month];
formatted.points.push(now.points);
formatted.months.push(now.month);
formatted.weeks.push(now.weeks.join("<br>"));
}
return formatted;
}
function InitChart(formattedData) {
let colors = ['#67001f', '#b2182b', '#d6604d', '#f4a582', '#fddbc7', '#e0e0e0', '#bababa', '#878787', '#4d4d4d', '#1a1a1a', 'white', 'white'];
var width = document.querySelector('.chart-wrapper').offsetWidth,
height = document.querySelector('.chart-wrapper').offsetHeight,
minOfWH = Math.min(width, height) / 2,
initialAnimDelay = 300,
arcAnimDelay = 150,
arcAnimDur = 3000,
secDur = 1000,
secIndividualdelay = 150;
var radius = undefined;
// calculate minimum of width and height to set chart radius
if (minOfWH > 200) {
radius = 200;
} else {
radius = minOfWH;
}
// append svg
var svg = d3.select('.chart-wrapper').append('svg').attr({
'width': width,
'height': height,
'class': 'pieChart'
}).append('g');
svg.attr({
'transform': 'translate(' + width / 2 + ', ' + height / 2 + ')'
});
// for drawing slices
var arc = d3.svg.arc().outerRadius(radius * 0.6).innerRadius(radius * 0.45);
// for labels and polylines
var outerArc = d3.svg.arc().innerRadius(radius * 0.85).outerRadius(radius * 0.85);
// d3 color generator
// let c10 = d3.scale.category10();
var tooltip = d3.select("body").append("div").attr("class", "tooltip").style("opacity", 0);
var pie = d3.layout.pie().value(function(d) {
return d;
}).sort(null);
var draw = function draw() {
svg.append("g").attr("class", "lines");
svg.append("g").attr("class", "slices");
svg.append("g").attr("class", "labels");
// define slice
var slice = svg.select('.slices').datum(formattedData.points).selectAll('path').data(pie);
slice.enter().append('path').attr({
'fill': function fill(d, i) {
return colors[i];
},
'd': arc,
'stroke-width': '25px'
}).attr('transform', function(d, i) {
return 'rotate(-180, 0, 0)';
}).style('opacity', 0).transition().delay(function(d, i) {
return i * arcAnimDelay + initialAnimDelay;
}).duration(arcAnimDur).ease('elastic').style('opacity', 1).attr('transform', 'rotate(0,0,0)');
slice.transition().delay(function(d, i) {
return arcAnimDur + i * secIndividualdelay;
}).duration(secDur).attr('stroke-width', '5px');
var midAngle = function midAngle(d) {
return d.startAngle + (d.endAngle - d.startAngle) / 2;
};
var text = svg.select(".labels").selectAll("text").data(pie(formattedData.points));
text.enter().append('text').attr('dy', '0.35em').style("opacity", 0).attr("cursor", "default").style('fill', function(d, i) {
return colors[i];
}).text(function(d, i) {
return formattedData.months[i];
}).attr('transform', function(d) {
// calculate outerArc centroid for 'this' slice
var pos = outerArc.centroid(d);
// define left and right alignment of text labels
pos[0] = radius * (midAngle(d) < Math.PI ? 1 : -1);
return 'translate(' + pos + ')';
}).style('text-anchor', function(d) {
return midAngle(d) < Math.PI ? "start" : "end";
}).transition().delay(function(d, i) {
return arcAnimDur + i * secIndividualdelay;
}).duration(secDur).style('opacity', 1);
text.on("mousemove", function(d, i) {
tooltip.html(formattedData.weeks[i])
.style('top', d3.event.pageY - 6 + 'px')
.style('left', d3.event.pageX + 14 + 'px')
.style("opacity", 1);
}).on("mouseout", function(d) {
tooltip.style("opacity", 0);
});
var polyline = svg.select(".lines").selectAll("polyline").data(pie(formattedData.points));
polyline.enter().append("polyline").style("opacity", 0.5).attr('points', function(d) {
var pos = outerArc.centroid(d);
pos[0] = radius * 0.95 * (midAngle(d) < Math.PI ? 1 : -1);
return [arc.centroid(d), arc.centroid(d), arc.centroid(d)];
}).transition().duration(secDur).delay(function(d, i) {
return arcAnimDur + i * secIndividualdelay;
}).attr('points', function(d) {
var pos = outerArc.centroid(d);
pos[0] = radius * 0.95 * (midAngle(d) < Math.PI ? 1 : -1);
return [arc.centroid(d), outerArc.centroid(d), pos];
});
};
draw();
var button = document.querySelector('button');
var replay = function replay() {
d3.selectAll('.slices').transition().ease('back').duration(500).delay(0).style('opacity', 0).attr('transform', 'translate(0, 250)').remove();
d3.selectAll('.lines').transition().ease('back').duration(500).delay(100).style('opacity', 0).attr('transform', 'translate(0, 250)').remove();
d3.selectAll('.labels').transition().ease('back').duration(500).delay(200).style('opacity', 0).attr('transform', 'translate(0, 250)').remove();
setTimeout(draw, 800);
};
}
$.get("path/to/data.php", function(data){
//Get data
var parsedData = ParseData(data);
//Render chart
InitChart(parsedData);
});