forsakenedsj
forsakenedsj

Reputation: 61

New to d3, unable to show graph with json

I'm very very very new to d3, and I have a problem getting a line graph with json.

In my ReportBucketDAO.java, I generate out json with my database data.

while (rs.next()) 
{
     String currency = rs.getString("currency");

     Timestamp pointDateTimeTs = rs.getTimestamp("point_datetime");
     String pointDateTime = pointDateTimeTs.toString();
     pointDateTime = pointDateTime.substring(0, pointDateTime.indexOf('.'));
     double pointValue = rs.getDouble("sum(`point_value`)");
     org.json.JSONObject jobj = new org.json.JSONObject();
     jobj.put("currency", currency);
     jobj.put("pointDateTime", pointDateTime);
     jobj.put("pointValue", pointValue);
     jArray.add(jobj);
}

The json string is:

[{"pointValue":274,"pointDateTime":"2015-01-20 00:00:00","currency":"GBP"}, {"pointValue":571,"pointDateTime":"2015-01-20 00:00:00","currency":"SGD"}, {"pointValue":561,"pointDateTime":"2015-01-20 00:00:00","currency":"USD"}]

I also had a jsp called getVolumeData.jsp which allow me to save the above json to "data.json"

<%@page import="java.util.ArrayList"%>
<%@page import="com.ach.model.ReportBucket"%>
<%@page import="com.ach.model.ReportBucketDAO"%>
<%@page import="java.io.*"%>
<%@page import="org.json.simple.*"%>
<%
    ReportBucketDAO rbDAO = new ReportBucketDAO();

    JSONArray rbjson = rbDAO.retrieveByReportTypeJson();
    System.out.println(rbjson);
    request.setAttribute("rbJsonString", rbjson);

    try {
        FileWriter jsonFileWriter = new FileWriter("data.json");
        jsonFileWriter.write(rbjson.toJSONString());
        jsonFileWriter.flush();
        jsonFileWriter.close();
        System.out.println("Done");
    } catch (IOException e) {
        e.printStackTrace();
    }
%>

I call the d3 content within home.jsp content

<!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="utf-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <meta name="description" content="">
            <meta name="author" content="">
            <link rel="icon" href="../../favicon.ico">

            <title>Project</title>

            <link rel="shortcut icon" href="assets/img/tBank.ico">

            <!-- Bootstrap core CSS -->
            <link href="assets/css/bootstrap.min.css" rel="stylesheet">
            <script data-require="[email protected]" data-semver="3.5.3" src="assets/js/d3.js"></script>

            <!-- Custom styles for this template -->
            <link href="assets/css/dashboard.css" rel="stylesheet">

            <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
            <script type="text/javascript" src="assets/js/script.js"></script>
            <script>
                $(function() {
                    $("#header").load("header.jsp");
                    $("#sidebar").load("sidebar.html");
                    //$("#d3content").load("getVolumeData.jsp");
                });
            </script> 
        </head>

    <body>
    <div id="header"></div>
    <div class="container-fluid">
      <div class="row">
        <div class="col-sm-3 col-md-2 sidebar" id="sidebar">
          <!--Sidebar here-->
        </div>
        <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
          <!--                    <img id="loading" src="assets/img/ajax_load.gif" alt="loading" />-->
          <div id="pageContent">
            <!-- this is where our AJAX-ed content goes -->
            <h1 class="page-header">My Dashboard</h1>
          </div>
          <div id="d3content">
            <script type="text/javascript">
                $("#d3content").load(function(event){
                    // Set the dimensions of the canvas / graph
            var margin = {
              top: 30,
              right: 20,
              bottom: 70,
              left: 50
            },
              width = 600 - margin.left - margin.right,
              height = 300 - margin.top - margin.bottom;

             // Parse the date / time
            var parseDate = d3.time.format("%Y-%m-%d %X").parse;

             // Set the ranges
            var x = d3.time.scale().range([0, width]);
            var y = d3.scale.linear().range([height, 0]);

             // Define the axes
            var xAxis = d3.svg.axis().scale(x)
              .orient("bottom").ticks(5);

            var yAxis = d3.svg.axis().scale(y)
              .orient("left").ticks(5);

             // Define the line
            var priceline = d3.svg.line()
              .x(function(d) {
                return x(d.pointDateTime);
              })
              .y(function(d) {
                return y(d.pointTime);
              });

             // Adds the svg canvas
            var svg = d3.select("#d3content")
              .append("svg")
              .attr("width", width + margin.left + margin.right)
              .attr("height", height + margin.top + margin.bottom)
              .append("g")
              .attr("transform",
                "translate(" + margin.left + "," + margin.top + ")");

             // Get the data
            d3.json("data.json", function(error, data) {
              data.forEach(function(d) {
                d.symbol = d.currency;
                d.pointDateTime = parseDate(d.pointDateTime);
                d.pointTime = +d.pointValue;
              });
              console.log(data);
              // Scale the range of the data
              x.domain(d3.extent(data, function(d) {
                return d.pointDateTime;
              }));
              y.domain([0, d3.max(data, function(d) {
                return d.pointTime;
              })]);

              // Nest the entries by symbol
              var dataNest = d3.nest()
                .key(function(d) {
                  return d.symbol;
                })
                .entries(data);

              console.log(dataNest);

              var color = d3.scale.category10(); // set the colour scale

              legendSpace = width / dataNest.length; // spacing for the legend

              // Loop through each symbol / key
              dataNest.forEach(function(d, i) {
                console.log(d);
                svg.append("path")
                  .attr("class", "line")
                  .style("stroke", function() { // Add the colours dynamically
                    return d.color = color(d.key);
                  })
                  .attr("id", 'tag' + d.key.replace(/\s+/g, '')) // assign ID
                .attr("d", priceline(d.values));

                // Add the Legend
                svg.append("text")
                  .attr("x", (legendSpace / 2) + i * legendSpace) // space legend
                .attr("y", height + (margin.bottom / 2) + 5)
                  .attr("class", "legend") // style the legend
                .style("fill", function() { // Add the colours dynamically
                  return d.color = color(d.key);
                })
                  .on("click", function() {
                    // Determine if current line is visible 
                    var active = d.active ? false : true,
                      newOpacity = active ? 0 : 1;
                    // Hide or show the elements based on the ID
                    d3.select("#tag" + d.key.replace(/\s+/g, ''))
                      .transition().duration(100)
                      .style("opacity", newOpacity);
                    // Update whether or not the elements are active
                    d.active = active;
                  })
                  .text(d.key);

              });

              // Add the X Axis
              svg.append("g")
                .attr("class", "x axis")
                .attr("transform", "translate(0," + height + ")")
                .call(xAxis);

              // Add the Y Axis
              svg.append("g")
                .attr("class", "y axis")
                .call(yAxis);

            });
                });
          </script>
          </div>
        </div>
      </div>
    </div>
    <!-- Bootstrap core JavaScript
        ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script data-require="[email protected]" data-semver="3.3.1" src="assets/js/bootstrap.min.js"></script>
    <!--<script src="assets/js/docs.min.js"></script>-->

  </body>
</html>

I wish the d3 to be loaded inside d3content, but it doesnt show/display anything, any help?

Upvotes: 0

Views: 426

Answers (1)

Mark
Mark

Reputation: 108537

Here's the problems:

1.) You don't load d3.js

2.) Your variables aren't mapped correctly. In this block:

data.forEach(function(d) {
    d.currency = +d.currency; // this is a string do not use +
    d.pointDateTime = parseDate(d.pointDateTime);
    d.pointTime = +d.pointTime; // your json is pointValue, not pointTime
});

3.) Your date parse function is wrong. Should be:

var parseDate = d3.time.format("%Y-%m-%d %X").parse;

Cleaning this up, produces this example.

Upvotes: 1

Related Questions