SVG无法正确呈现为骨干视图

rr.*_*rr. 21 javascript html5 svg backbone.js d3.js

我正在使用d3.js在svg中渲染世界地图(使用https://github.com/johan/world.geo.json/blob/master/countries.geo.json获取这些功能).我将渲染逻辑封装在Backbone View中.当我渲染视图并将其附加到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();
Run Code Online (Sandbox Code Playgroud)

这是有效的代码,不使用Backbone.View

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);
Run Code Online (Sandbox Code Playgroud)

我还附上了生成的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;
}
Run Code Online (Sandbox Code Playgroud)

mbo*_*ock 27

问题是"svg"元素需要命名空间.D3会自动执行此操作; 当你追加一个"svg"元素时,它使用命名空间" http://www.w3.org/2000/svg ".有关详细信息,请参阅SRC /核心/ ns.js.不幸的是,Backbone似乎不支持命名空间元素.您想要更改view.make方法.然后,您需要在视图上使用namespaceURI属性来设置适当的命名空间,或者只是为SVG元素自动执行此操作以与HTML5解析器保持一致.

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

  • @Milimetric Make已在Backbone 0.9.10中删除.见http://backbonejs.org/#changelog 0.9.10.更具体地说,参见https://github.com/documentcloud/backbone/pull/2041以及https://github.com/documentcloud/backbone/commit/c1e62cda999dd902060ea04a11b81376aba63a16和https://github.com/上的提交和提取documentcloud /骨干网/提交/ 8a42d536d8c862d259ca4d7909026798c046c3e9 (4认同)