我正在使用 d3.js 以 svg 格式渲染世界地图(使用 https://github.com/johan/world.geo.json/blob/master/countries.geo.json 作为功能)。我将渲染逻辑封装在主干 View 中。当我呈现 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();
这是在不使用 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);
我还附上了生成的 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”元素时,它使用命名空间“http://www.w3.org/2000/svg”。有关详细信息,请参阅 src/core/ns.js .不幸的是,Backbone 似乎不支持命名空间元素。你想改变 view.make方法。然后,您需要 View 上的 namespaceURI 属性来设置适当的命名空间,或者只是自动为 SVG 元素执行此操作以与 HTML5 解析器保持一致。
无论如何,解决问题的一个简单方法是将 SVG 包装在 DIV 元素中,然后使用 D3 创建 SVG 元素。
关于javascript - SVG 无法正确呈现为主干 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9651167/