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 bat批处理,关于数据复制问题
  • ¥50 同步两个不同结果的array中某些属性
  • ¥15 悬赏15远程操控解决问题
  • ¥15 CST复制的模型无法单独修改参数?
  • ¥15 前端页面想做个定时任务,但是使用requestAnimationFrame,setinterval和settimeout都不行
  • ¥15 根据以下文字信息,做EA模型图
  • ¥15 删除虚拟显示器驱动 删除所有 Xorg 配置文件 删除显示器缓存文件 重启系统 可是依旧无法退出虚拟显示器
  • ¥15 vscode程序一直报同样的错,如何解决?
  • ¥15 关于使用unity中遇到的问题
  • ¥15 开放世界如何写线性关卡的用例(类似原神)