2013-07-12 48 views
10

我想從我的Rails應用中呈現以下樹狀圖渲染D3圖: http://bl.ocks.org/mbostock/4063570從JSON的字符串,而不是一個JSON文件

我有許多屬性的模型,但我想手動巢這些屬性並簡單地使用字符串插值來構建我自己的JSON字符串,然後直接將其傳遞給d3。

這裏是我的代碼:

<%= javascript_tag do %> 
     var width = 960, 
     height = 2200; 

     var cluster = d3.layout.cluster() 
     .size([height, width - 160]); 

     var diagonal = d3.svg.diagonal() 
     .projection(function(d) { return [d.y, d.x]; }); 

     var svg = d3.select("body").append("svg") 
     .attr("width", width) 
     .attr("height", height) 
     .append("g") 
     .attr("transform", "translate(40,0)"); 

     **d3.json("/assets/flare.json", function(root) {** 
     var nodes = cluster.nodes(root), 
     links = cluster.links(nodes); 

     var link = svg.selectAll(".link") 
     .data(links) 
     .enter().append("path") 
     .attr("class", "link") 
     .attr("d", diagonal); 

     var node = svg.selectAll(".node") 
     .data(nodes) 
     .enter().append("g") 
     .attr("class", "node") 
     .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; }) 

     node.append("circle") 
     .attr("r", 4.5); 

     node.append("text") 
     .attr("dx", function(d) { return d.children ? -8 : 8; }) 
     .attr("dy", 3) 
     .style("text-anchor", function(d) { return d.children ? "end" : "start"; }) 
     .text(function(d) { return d.name; }); 
     }); 

     d3.select(self.frameElement).style("height", height + "px"); 
    <% end %> 

這裏是我的(unminified)JSON字符串:

var mystring = '{ 
    "name": "Product", 
    "properties": { 
     "id": { 
      "type": "number", 
      "description": "Product identifier", 
      "required": true 
     }, 
     "name": { 
      "type": "string", 
      "description": "Name of the product", 
      "required": true 
     }, 
     "price": { 
      "type": "number", 
      "minimum": 0, 
      "required": true 
     }, 
     "tags": { 
      "type": "array", 
      "items": { 
       "type": "string" 
      } 
     }, 
     "stock": { 
      "type": "object", 
      "properties": { 
       "warehouse": { 
        "type": "number" 
       }, 
       "retail": { 
        "type": "number" 
       } 
      } 
     } 
    } 
}'; 

事情我已經嘗試:

1)涅槃的JSON所以它的輸入作爲只有一行(沒有效果)

2)在字符串上運行JSON.parse(mystring)

3)通過D3文檔查找和搜索以下方法來修改以下函數以接受字符串而不是文件路徑: d3.json(「/ assets/flare.json」,function(root) var nodes = cluster.nodes(root), links = cluster.links(nodes);

回答

23

首先,讓我們看看d3.json做什麼。

d3.json("/assets/flare.json", function(root) { 
    // code that uses the object 'root' 
}); 

這將加載來自服務器的文件/assets/flare.json,解釋內容作爲JSON並將得到的對象作爲root參數匿名函數。

如果您已經有JSON對象,則不需要使用d3.json函數 - 您可以直接使用該對象。

var root = { 
    "name": "flare", 
    "children": [ 
    ... 
    ] 
}; 
// code that uses the object 'root' 

如果該對象被表示爲一個字符串,那麼你可以使用JSON.parse來獲取對象:

var myString = '{"name": "flare","children": [ ... ] }'; 
var root = JSON.parse(mystring); 
// code that uses the object 'root' 

其次,讓我們來看看你的數據是什麼d3.layout.cluster期待。按照the docs

...默認孩子訪問假定每個輸入數據是一個帶兒童數組的對象...

換句話說,你的數據需要是這樣的形式:

var mystring = '{ 
    "name": "Product", 
    "children": [ 
     { 
      "name": "id", 
      "type": "number", 
      "description": "Product identifier", 
      "required": true 
     }, 
     ... 
     { 
      "name": "stock", 
      "type": "object", 
      "children": [ 
       { 
        "name: "warehouse", 
        "type": "number" 
       }, 
       { 
        "name": "retail", 
        "type": "number" 
       } 
      ] 
     } 
    ] 
} 
+0

knolleary,謝謝你爲解釋灰。這是有幫助的,但我特別要找的是:如何更改d3.json(「/ assets/flare.json」,函數(root){line允許本地字符串?d3.json的語法是: d3.json(url [,callback])。我想在我的字符串上運行匿名函數,而不是URL。 –

+4

Michael,您通過刪除它來更改d3.json(..)行... if你已經有了這個字符串,你不需要使用函數從url加載內容,這就是d3.json所做的一切。當前在d3.json(..)調用中指定的匿名函數可以被明確地調用這是我在前半部分的答案中描述的內容 – knolleary

+0

我怎樣才能加載一個json文件呢?它總是給我錯誤 –

3

d3。json實際上將URL作爲參數,所以我建議將數據管理委派給控制器(特別是如果將來需要從數據庫加載它),而不是將其作爲參數的路徑,那麼爲了簡化:

  1. 在控制器中創建一個方法,它實際上會打開該文件,並返回其內容:
class YourFlareController < ApplicationController 
    def load 
     @data = File.read("app/assets/json/flare.json") 
     render :json => @data 
    end 
end 
  1. 確保你在你的路由的路由.RB

GET 「yourflare /負荷」

  1. 現在在你的JavaScript,你可以簡單地調用

d3.json("http://host/yourflare/load", function(root) {

相關問題