dongtun2572 2015-10-06 07:13
浏览 77
已采纳

将D3.js与symfony2一起使用

I just started learning php for a few weeks and now I'm using Symfony2 as a framework. So, I have very few knowledges using Symfony.

What I'm trying to do now is, I want to implement this D3 tutorial but rather than use plain php, I want to use Symfony.

So, what I did until now :

  1. Created a database called 'homedb' and I fill it exactly as the tutorial did.
  2. Managed to connect symfony with the database (modified in parameters.yml)
  3. Created a new bundle call TreeBundle.
  4. Created a controller called DataController to fetch data from the database.
  5. Created a html.twig file to display the data.

I converted this file : data.php

<?php
    $username = "homedbuser"; 
        $password = "homedbuser";   
        $host = "localhost";
    $database="homedb";

    $server = mysql_connect($host, $username, $password);
    $connection = mysql_select_db($database, $server);

    $myquery = "SELECT  `date`, `close` FROM  `data2`";

    $query = mysql_query($myquery);   
    if ( ! $query ) {
        echo mysql_error();
        die;
    }

    $data = array();

    for ($x = 0; $x < mysql_num_rows($query); $x++) {
        $data[] = mysql_fetch_assoc($query);
    }

    echo json_encode($data);     

    mysql_close($server);

into this file : DataController.php

<?php
// src/Dependency/TreeBundle/Controller/DataController.php
namespace TreeBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;

class DataController extends Controller
{
     /**
     * @Route("/tree")
     */

    public function queryAction()
    {
        $em = $this->getDoctrine()->getEntityManager();

        $query=$em->createQuery(
            'SELECT date AND close
            FROM data2'
            );

        $list = $query->getResult();
        return new JsonResponse($list);

    }
    return $list->render('DependencyTreeBundle:Data:simple-graph.html.twig'); 
}

but, I got this error :

Parse Error: syntax error, unexpected 'return' (T_RETURN), expecting function (T_FUNCTION)

I know this is just a tiny error from my erroneous code. Anyone could help me to correctly converted this script?

P/S : For my simple-graph.html.twig, I just use {{source(simple-graph.html)}} to just return the content without rendering it.

UPDATE 1

I just edited my code as follow to fetch the data from database and convert it to json.

public function queryAction()
{
    $em = $this->getDoctrine()->getManager();

    $sql = " 
    SELECT date,
           close
      FROM data2
    ";

    $stmt = $this->getDoctrine()->getManager()->getConnection()->prepare($sql);
    $stmt->execute();
    return $stmt->fetchAll();
    $json = json_encode($stmt);
    return $json-->render('DependencyTreeBundle:query:simple-graph.html.twig');
}

But, I got this error this time : The controller must return a response (Array(0 => Array(date => 1-May-12, close => 58.13), 1 => Array(date => 30-Apr-12, close => 53.98), ,....

Seems like the data is fetched but failed to convert it as json..

UPDATE 2

Here is my new code thanks to @adiii4 for the suggestion. But this code has error : Attempted to load class "TreeBundle" from namespace "Dependency\TreeBundle". Did you forget a "use" statement for another namespace?

<?php
// src/Dependency/TreeBundle/Controller/DataController.php
namespace Dependency\TreeBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;

class DataController extends Controller
{
     /**
     * @Route("/tree")
     */

    public function queryAction()
    {
        $em = $this->getDoctrine()->getManager();

        $sql = " 
                SELECT date,
                close
                FROM data2
                ";

        $stmt = $this->getDoctrine()->getManager()->getConnection()- >prepare($sql);

        $stmt->execute();

        $stmt->fetchAll();

        $list = json_encode($stmt);

        return $this->render('DependencyTreeBundle:Data:simple-graph.html.twig', array('data' => $list));
    }

}

UPDATE 3

I think I managed to fetch the data and convert to json correctly. Now, I need to visualized the data by calling D3 in the html file. Is it possible just to embed the html file in Twig and let Twig alone do the rest? Or do I need to convert all of it to Twig syntaxes?

Here is the source code of the simple-graph.html :

        <!DOCTYPE html>
        <meta charset="utf-8">
        <style> /* set the CSS */

        body { font: 12px Arial;}

        path { 
            stroke: steelblue;
            stroke-width: 2;
            fill: none;
        }

        .axis path,
        .axis line {
            fill: none;
            stroke: grey;
            stroke-width: 1;
            shape-rendering: crispEdges;
        }

        </style>
        <body>

        <!-- load the d3.js library -->    
        <script src="http://d3js.org/d3.v3.min.js"></script>

        <script>

        // Set the dimensions of the canvas / graph
        var margin = {top: 30, right: 20, bottom: 30, left: 50},
            width = 600 - margin.left - margin.right,
            height = 270 - margin.top - margin.bottom;

        // Parse the date / time
        var parseDate = d3.time.format("%d-%b-%y").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 valueline = d3.svg.line()
            .x(function(d) { return x(d.date); })
            .y(function(d) { return y(d.close); });

        // Adds the svg canvas
        var svg = d3.select("body")
            .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.php", function(error, data) {
            data.forEach(function(d) {
                d.date = parseDate(d.date);
                d.close = +d.close;
            });

            // Scale the range of the data
            x.domain(d3.extent(data, function(d) { return d.date; }));
            y.domain([0, d3.max(data, function(d) { return d.close; })]);

            // Add the valueline path.
            svg.append("path")
                .attr("class", "line")
                .attr("d", valueline(data));

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

What I did just now, in my simple-graph.html.twig is, I just outsource the json data, and call the html file to do the rest. Obviously, I was thrown with this error : Unable to find template "{}" in DependencyTreeBundle:Data:simple-graph.html.twig at line 2

Here is my code in my simple-graph.html.twig :

{# src/Dependency/TreeBundle/Resources/views/simple-graph.html.twig #}
{{ source(data) }}
{{ source('public/html/simple-graph.html') }}

Does anyone have idea? I appreciate it a lot.

  • 写回答

1条回答 默认 最新

  • dounaoji2054 2015-10-06 12:10
    关注

    You get your second error because you can't call two return statements in a function! And since a controller function in symfony expects always a Response Object you get this error because this first return statement returns NOT a response object:

    return $stmt->fetchAll();
    

    Your controller function needs to look like this:

    public function queryAction()
    {
        $em = $this->getDoctrine()->getManager();
        $query=$em->createQuery(
            'SELECT date AND close
            FROM data2'
            );
    
        $list = json_encode($query->getResult());
    
        return $this->render('DependencyTreeBundle:query:simple-graph.html.twig', array('data' => $list));
    }
    

    Then you can output your json in your template like this

    {{ source(data) }}
    

    Also did you create an entity class for you database table?

    Update

    Just a little enhancement:

    When you're using raw sql queries without entities fetch your data like this:

        $conn = $this->get('database_connection');
        $list = $conn->fetchAll('SELECT date,close FROM data2');
    

    Reference: http://symfony.com/doc/current/cookbook/doctrine/dbal.html

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 单片机学习顺序问题!!
  • ¥15 ikuai客户端多拨vpn,重启总是有个别重拨不上
  • ¥20 关于#anlogic#sdram#的问题,如何解决?(关键词-performance)
  • ¥15 相敏解调 matlab
  • ¥15 求lingo代码和思路
  • ¥15 公交车和无人机协同运输
  • ¥15 stm32代码移植没反应
  • ¥15 matlab基于pde算法图像修复,为什么只能对示例图像有效
  • ¥100 连续两帧图像高速减法
  • ¥15 如何绘制动力学系统的相图