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

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

报告相同问题?

悬赏问题

  • ¥40 复杂的限制性的商函数处理
  • ¥15 程序不包含适用于入口点的静态Main方法
  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码