javascript - 从Android平板电脑图像路径在d3.js中显示图像

标签 javascript android json image d3.js

我正在使用 Android 以 JSON 格式将数据发送到 d3.js webview。 我遇到了一个问题。这里我有一个像这样的 d3.js 代码。 我已附上此代码的示例,以便可以运行它。 https://drive.google.com/file/d/0B7Ztdu46v0uOZjhvTG5HRlVRRG8/edit?usp=sharing

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,但我不知道如何提取元素,select(“g”),selectAll , 等等。我也不知道如何将该路径引入 xlink:href 中。我只是将图像放入 Android asset/中,这根本不通用。我想使用任何路径插入图片作为屏幕背景。

此外,我想使用在graph1.json.php中获得的宽度和高度在update-anim.html中设置。我想知道这是否可行,或者我是否必须仅通过 JavaScript 进行设置。

有人可以帮我解决这个问题吗?

最佳答案

您的示例数据格式是

{
  "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"}
}

因此,当您读入数据时,数据对象中就有路径。您只需设置 xlink:href您的<image>数据处理函数中的元素 ( joinGraph() )。您仍然可以在初始化中创建图像元素,而不需要源路径,然后将其保存在变量中或稍后重新选择它。

/* 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 上使用,则必须设置 CSS display:block;display:inline-block;在 SVG 上——存在一个 Firefox 错误,该错误会在内联 SVG 上提供未处理的宽度和高度值。

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

关于javascript - 从Android平板电脑图像路径在d3.js中显示图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21464444/

相关文章:

java - 获取 { 和 } 之间的所有文本(源文本包含\n)

android向布局添加点线

javascript - 错误: "JSON.parse: unexpected character at line 1 column 1 of the JSON data" when include additional php file

c# - 反序列化呈现为不同类型的节点

javascript - 在 Greasemonkey 中自动登录?

javascript - 移动输入无法以编程方式更新

android - 如何加载谷歌驱动器上的文件

python - 将简单的数字列表转换为 JSON 数组

javascript - 选项卡焦点未正确显示

javascript - xmldoc.selectNodes() 无法正常工作