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",
    "pointsR‌​ewarded": 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@jane
ajax
请求返回数据。谢谢。我会回复你的。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);
});