2014-01-30 67 views
1

我正在使用Android以JSON格式將數據發送到d3.js webview。 我遇到了問題。在這裏,我有一個這樣的d3.js代碼。 我附上了這段代碼的例子,以便它可以運行。 https://drive.google.com/file/d/0B7Ztdu46v0uOZjhvTG5HRlVRRG8/edit?usp=sharing從Android平板電腦圖像路徑d3.js中顯示圖像

var RADIUS = 5; 
var moved = false; 
var graph = {}; 
var nodes, links; 

var svg = d3.select("svg"); 

// Retreive SVG element's width and height 
// TODO: This needs to be fixed. This code terribly fails when width and 
// height attributes are not specified in pixels. 
var SVG_WIDTH = svg.attr('width'); 
var SVG_HEIGHT = svg.attr('height'); 
svg.append("image") 
    .attr("x", 0) 
     .attr("y", 0) 
     .attr("xlink:href", "Map.jpg") 
     .attr("width", SVG_WIDTH) 
     .attr("height", SVG_HEIGHT); 


svg.append("defs") 
    .append("marker") 
    .attr("id", "head") 
    .attr("viewBox", "0 -5 10 10") 
    .attr("refX", 15) 
    .attr("refY", 0) 
    .attr("markerWidth", 2) 
    .attr("markerHeight", 2) 
    .attr("orient", "auto") 
    .attr("class", "link") 
    .append("path") 
    .attr("d", "M0,-5L10,0L0,5"); 

var drag = d3.behavior.drag() 
    .origin(Object) 
    .on("drag", dragMove) 
    .on("dragend", dragEnd) 
    ; 

// Prepare a group to draw links 
svg.append("g").attr("class", "links"); 

// Prepare a group to draw nodes 
svg.append("g").attr("class", "nodes"); 

/////////////////////////////////////////////////////////////////// 
// Function to update SVG contents with current nodes and links 
// info attached to each SVG element (including the newly added 
// ones). Animation effects are performed if anim is true. 
/////////////////////////////////////////////////////////////////// 
function update(anim) { 
    nodes.select(".node") 
     .classed("gw", function(d) 
     { 
     return graph.nodes[d].type == 'gw'; 
     }); 

    if (anim) 
    { 
    updatedNodes = nodes.transition().duration(300).ease("linear"); 
    updatedLinks = links.transition().duration(300).ease("linear") 
         .attr("opacity", "1"); 
    } 
    else 
    { 
    updatedNodes = nodes; 
    updatedLinks = links; 
    } 
    updatedLinkShadow = linkShadow; 

    updatedNodes.attr("transform", function(d) { 
     return "translate(" + graph.nodes[d].pos + ")"; 
     }); 
    updatedLinks.attr("d", drawLink); 
    updatedLinkShadow.attr("d", drawLink); 
} 

function drawLink(pair) { 
    console.log(pair); 
    var dx = graph.nodes[pair[0]].pos[0] - graph.nodes[pair[1]].pos[0]; 
    var dy = graph.nodes[pair[0]].pos[1] - graph.nodes[pair[1]].pos[1]; 
    var dist = Math.sqrt(dx*dx+dy*dy); 
    return "M" + graph.nodes[pair[0]].pos 
     + "A" + dist + "," + dist + " 0 0,0 " + 
     graph.nodes[pair[1]].pos; 
} 

/////////////////////////////////////////////////////////////////// 
// Function to perform data join between the graph model ('graph') 
// and SVG elements 
/////////////////////////////////////////////////////////////////// 
function joinGraph() { 
    ////////////////////// 
    // Link data join 
    ////////////////////// 
    links = svg.select("g.links").selectAll("path.link") 
    .data(graph.links, function(d) { return d;}); 
    linkShadow = svg.select("g.links").selectAll("path.linkshadow") 
    .data(graph.links, function(d) { return d;}); 

    linkShadow.enter() 
    .append("path") 
    .classed("linkshadow", true) 
    .attr("marker-end", "url(#head)") 
    .attr("d", drawLink) 
    .attr("opacity","1") 

    links.enter() 
    .append("path") 
    .classed("link", true) 
    //.attr("marker-end", "url(#head)") 
    .attr("d", drawLink) 
    .attr("opacity","0") 

    var goneLinks = links.exit(); 
    linkShadow.exit().remove(); 

    // Node data join 
    // *Notes* Set key to be value rather than index 
    nodes = svg.select("g.nodes").selectAll("g") 
     .data(d3.keys(graph.nodes), Number); 

    // Nodes just appearing 
    var newNodes = nodes.enter().append("g").call(drag); 

    // Nodes no longer exist 
    var goneNodes = nodes.exit(); 

    newNodes 
    .append("circle") 
    .attr("r", RADIUS) 
    .classed("node", true) 
    ; 

    newNodes 
    .append("text") 
    .attr("x", RADIUS+2) 
    .attr("y", RADIUS+2) 
    .attr("class", "shadow") 
    .text(String) 
    ; 

    newNodes 
    .append("text") 
    .attr("x", RADIUS+2) 
    .attr("y", RADIUS+2) 
    .attr("fill", "blue") 
    .text(String) 
    ; 

    // Update SVG elements with animation 
    update(true); 

    // Remove nodes and links that no longer exist 
    goneNodes 
    .transition().duration(300).ease("linear") 
     .attr("transform", "translate(0,0)") 
    .remove(); 
    goneLinks 
    .attr("opacity", "1") 
    .transition().duration(300).ease("linear") 
     .attr("opacity", "0") 
    .remove(); 

} 

/////////////////////////////////////////////////////////////////// 
// Function to be called by D3 when a node SVG element is dragged. 
// The new position is updated to the 'graph' variable and then the 
// corresponding SVG elements. 
/////////////////////////////////////////////////////////////////// 
function dragMove(d) { 
    // Update position of the dragged node in the graph model 
    var newpos = graph.nodes[d].pos; 
    newpos[0] += d3.event.dx; 
    newpos[1] += d3.event.dy; 
    newpos[0] = Math.max(0, Math.min(newpos[0], SVG_WIDTH)); 
    newpos[1] = Math.max(0, Math.min(newpos[1], SVG_HEIGHT)); 

    // Update SVG elements without animation 
    update(false); 

    moved = true; 
} 

/////////////////////////////////////////////////////////////////// 
// Function to be called by D3 when a node SVG element is dropped. 
/////////////////////////////////////////////////////////////////// 
function dragEnd(d) { 
    if (moved) 
    { 
    d3.select("#msg").text("Updating node " + d + " to database"); 
    moved = false; 
    } 
    else 
    d3.select("#msg").text("Showing " + d + " details"); 
} 

/////////////////////////////////////////////////////////////////// 
// *FOR TESTING* Function to be called when test buttons are clicked. 
// It reloads a graph from the given name in form of JSON 
/////////////////////////////////////////////////////////////////// 
function reload(g) { 
    d3.json("./" + g + ".json.php", function(json) 
    { 
    graph = json; 
    joinGraph(); 
    }); 
} 

我的JSON數據在文件graph1.json.php。 我想從Android平板電腦中的路徑添加圖片,例如/mnt/sdcard/DCIM/Camera/Map.jpg,但我不知道如何提取元素,請選擇(「g」), selectAll等等。我也不知道如何將這個路徑引入xlink:href。我只是把圖片放入Android資產/這根本不是多功能的。我想使用任何路徑將圖片插入爲屏幕背景。

此外,我想使用graph1.json.php中獲得的寬度和高度在update-anim.html中設置。我想知道這是可能的,還是隻能通過JavaScript來設置。

有人能幫助我嗎?

回答

1

你的樣本數據格式是

{ 
    "nodes": { 
    "1": {"pos":[100,200], "type":"gw" }, 
    "2": {"pos":[330,150], "type":"node" }, 
    "3": {"pos":[130,150], "type":"node" }, 
    "5": {"pos":[230,100], "type":"gw" }, 
    "10": {"pos":[430,200], "type":"node" } 
    }, 
    "links": [[3,5],[1,2],[10,1],[1,3],[3,1]] 
    "mapimage": {"path":"/mnt/sdcard/DCIM/Camera/Map.jpg", 
       "width":"1280", "height"":"720"} 
} 

所以,當你在數據讀取方面,你有你的數據對象的路徑。您只需在數據處理函數(joinGraph())中設置<image>元素的xlink:href即可。您仍然可以在初始化中創建圖像元素,而不使用源路徑,然後將其保存在變量中或稍後重新選擇它。

/* Initialization */ 
var background = svg.append("image") 
    .attr("x", 0) 
    .attr("y", 0) 
    .attr("preserveAspectRatio", "xMidYMid slice") 
     // This prevents the aspect ratio from being distorted; 
     // skip if the image can be stretched to fit. 
     // xMidYMid will center the image in the SVG; 
     // slice means that it will be sized big enough to cover 
     // the background, even if some of the image is cut off. 
     // Use "xMidYMid meet" if you want the whole image shown 
     // even if that leaves empty space on the sides 
    .attr("width", SVG_WIDTH) 
    .attr("height", SVG_HEIGHT); 

/* Link to data */ 
function joinGraph() { 

    background.attr("xlink:href", graph.mapImage.path); 

    /* The rest of the joinGraph method is the same */ 
} 

至於如何找出通過CSS大小一個SVG的寬度和高度,你用window.getComputedStyle()吃出了所使用的實際像素長度。不過請注意,如果您的代碼還有可能在Firefox上使用,則必須在SVG上設置CSS display:block;display:inline-block;--這是一個Firefox內聯的SVG中未處理的寬度和高度值的bug。

var svg = d3.select("svg") 

var SVG_WIDTH = parseFloat(getComputedStyle(svg.node())['width']); 
var SVG_HEIGHT = parseFloat(getComputedStyle(svg.node())['height']); 
    //selection.node() extracts the first (and only) svg DOM element 
    //from the selection, so it can be used by Javascript functions 
    //getComputedStyle returns height and width as pixel lengths 
    //parseFloat strips off the "px" to return a number 
+0

background.attr(「xlink:href」,graph.mapImage.path);在joinGraph()中並不顯示任何圖片,即使我使用靜態路徑。 – user3170377

+1

你確定你有一個有效的圖像文件路徑?檢查您的DOM檢查器,以驗證圖像是否正在創建並正確設置其屬性。然後檢查你的控制檯是否有錯誤信息以上代碼作爲一個簡單的小提琴:http://fiddle.jshell.net/Sqt3F/ – AmeliaBR

+0

我現在就知道了。非常感謝! – user3170377

相關問題