Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/466.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript SVG未正确呈现为主干视图_Javascript_Html_Svg_Backbone.js_D3.js - Fatal编程技术网

Javascript SVG未正确呈现为主干视图

Javascript SVG未正确呈现为主干视图,javascript,html,svg,backbone.js,d3.js,Javascript,Html,Svg,Backbone.js,D3.js,我使用d3.js在svg中渲染世界地图(用于特性)。我将渲染逻辑封装在主干视图中。当我呈现视图并将其附加到DOM时,浏览器中不会显示任何内容,尽管在查看生成的HTML时SVG标记是正确生成的。当不封装在Backbone.View中时,这会呈现良好效果。以下是我使用Backbone.view的代码: /** * SVG Map view */ var MapView = Backbone.View.extend({ tagName: 'svg', translationOffs

我使用d3.js在svg中渲染世界地图(用于特性)。我将渲染逻辑封装在主干视图中。当我呈现视图并将其附加到DOM时,浏览器中不会显示任何内容,尽管在查看生成的HTML时SVG标记是正确生成的。当不封装在Backbone.View中时,这会呈现良好效果。以下是我使用Backbone.view的代码:

/**
 * SVG Map view
 */
var MapView = Backbone.View.extend({
    tagName: 'svg',
    translationOffset: [480, 500],
    zoomLevel: 1000,

    /**
     * Sets up the map projector and svg path generator
     */
    initialize: function() {
        this.projector = d3.geo.mercator();
        this.path = d3.geo.path().projection(this.projector);
        this.projector.translate(this.translationOffset);
        this.projector.scale(this.zoomLevel);
    },

    /**
     * Renders the map using the supplied features collection
     */
    render: function() {
        d3.select(this.el)
          .selectAll('path')
          .data(this.options.featureCollection.features)
          .enter().append('path')
          .attr('d', this.path);
    },

    /**
     * Updates the zoom level
     */
    zoom: function(level) {
        this.projector.scale(this.zoomLevel = level);
    },

    /**
     * Updates the translation offset
     */
    pan: function(x, y) {
        this.projector.translate([
            this.translationOffset[0] += x,
            this.translationOffset[1] += y
        ]);
    },

    /**
     * Refreshes the map
     */
    refresh: function() {
        d3.select(this.el)
          .selectAll('path')
          .attr('d', this.path);
    }
});

var map = new MapView({featureCollection: countryFeatureCollection});
map.$el.appendTo('body');
map.render();
下面是不使用主干的代码

var projector = d3.geo.mercator(),
    path = d3.geo.path().projection(projector),
    countries = d3.select('body').append('svg'),
    zoomLevel = 1000;

coords = [480, 500];
projector.translate(coords);
projector.scale(zoomLevel);

countries.selectAll('path')
         .data(countryFeatureCollection.features)
         .enter().append('path')
         .attr('d', path);
我还附上了生成的SVG标记的屏幕截图。知道这里出了什么问题吗

编辑-根据请求,以下是最终解决此问题的重写make方法:

/**
 * Custom make method needed as backbone does not support creation of
 * namespaced HTML elements.
 */
make: function(tagName, attributes, content) {
    var el = document.createElementNS('http://www.w3.org/2000/svg', tagName);
    if (attributes) $(el).attr(attributes);
    if (content) $(el).html(content);
    return el;
}
问题是“svg”元素需要一个名称空间。D3会自动为您的客户执行此操作;附加“svg”元素时,它使用名称空间“”。有关详细信息,请参阅。不幸的是,主干网似乎不支持名称空间元素。您可能想更改方法。然后,您需要在视图上使用namespaceURI属性来设置适当的名称空间,或者只是为SVG元素自动设置名称空间,以与HTML5解析器保持一致


无论如何,解决问题的一个简单方法是将SVG包装在一个DIV元素中,然后使用D3创建SVG元素。

您只需在initialize函数中设置视图的元素,如下所示:

Backbone.View.extend({
    // This is only for informaiton. The node will
    // be raplaced in the initialize function.
    tagName: 'svg',

    initialize: function () {
        this.setElement(
            d3.select($('<div/>')[0]).append('svg')[0]
        );
    }
);
Backbone.View.extend({
//这仅用于提供信息。节点将
//放在初始化函数中。
标记名:“svg”,
初始化:函数(){
这个.setElement(
d3.选择($('')[0])。追加('svg')[0]
);
}
);
这有明确的优点。

看看这个 从


谢谢!我在视图中改写了“make”,并将CreateElements与“”一起使用,而不是使用createElement,这似乎起到了作用。感谢您的指导。@rr:您能将make方法发布到某个地方吗?@PierreSpring:完成,不确定这与较新版本的主干有多大关系,我一直没有跟上。仍然相关,只是遇到了它。谢谢@mbostock,让我的脸从一种非常困惑的表情中免于冻结:)@Milimetric Make已在主干网0.9.10中删除。请参见0.9.10。更具体地说,在和提交和拉取的讨论中,这是主干网作者在这里提到的:您不需要创建div,
setElement(document.createElements('http://www.w3.org/2000/svg“,'svg'))
很好。考虑到make方法已被删除,现在正确的方法是什么?
Backbone.View.extend({
  nameSpace: "http://www.w3.org/2000/svg",
  _ensureElement: function() {
     if (!this.el) {
        var attrs = _.extend({}, _.result(this, 'attributes'));
        if (this.id) attrs.id = _.result(this, 'id');
        if (this.className) attrs['class'] = _.result(this, 'className');
        var $el = $(window.document.createElementNS(_.result(this, 'nameSpace'), _.result(this, 'tagName'))).attr(attrs);
        this.setElement($el, false);
     } else {
        this.setElement(_.result(this, 'el'), false);
     }
 }
});