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

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

本文介绍了SVG无法正确呈现为骨干视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用d3.js在svg中呈现世界地图(使用。有关详细信息,请参见 。不幸的是,Backbone似乎不支持命名空间元素。您需要更改方法。然后,您需要在视图上使用一个namespaceURI属性来设置相应的命名空间,或者只为SVG元素自动执行以与HTML5解析器保持一致。



,一个简单的修复你的问题是将您的SVG包装在一个DIV元素,然后使用D3创建SVG元素。


I'm using d3.js to render a map of the world in svg (using https://github.com/johan/world.geo.json/blob/master/countries.geo.json for the features). I am encapsulating the rendering logic in a Backbone View. When I render the view and attach it to the DOM, nothing displays in my browser, though the SVG markup is correctly generated when looking at the generated HTML. This renders fine when not encapsulating within a Backbone.View. Here's my code using 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();

Here's the code that works, without using 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);

I've also attached a screenshot of the generated SVG markup. Any idea what could be going wrong here?

Edit - Here's the overridden make method that ended up solving this, per request:

/**
 * 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;
}
解决方案

The issue is that the "svg" element requires a namespace. D3 does this for your automatically; when you append an "svg" element, it uses the namespace "http://www.w3.org/2000/svg". For details, see src/core/ns.js. Backbone, unfortunately, does not appear to support namespaced elements. You'd want to change the view.make method. Then you'd need a namespaceURI property on your view to set the appropriate namespace, or just do it automatically for SVG elements for consistency with the HTML5 parser.

At any rate, a simple fix for your problem is to wrap your SVG in a DIV element, and then use D3 to create the SVG element.

这篇关于SVG无法正确呈现为骨干视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-13 13:45