【问题标题】:How to append an svg to an prexisting svg using d3.js?如何使用 d3.js 将 svg 附加到预先存在的 svg?
【发布时间】:2017-12-18 11:46:06
【问题描述】:

是否可以使用 d3.js 将另一个 svg 附加到预先存在的 svg 父级?

我知道这可以通过使用“svg:image”属性来实现。 但不幸的是,我失去了对内在 svg-child 的完全控制。

相关的 dom 节点由 d3 创建但未渲染,因此页面保持空白。

希望有人可以提供帮助,谢谢 :)

这是我得到的:

HTML CSS

  #svg-main-wrapper {
    position: absolute;
    min-width: 100%;
    min-height: 100%;
    bottom: 0;
    padding: 0;
    margin: 0;
  }
  
  
  <div id="svg-main-wrapper">
    <div svg-container svg-src="svgContainer[0].url" position="svgContainer[0].position">
    </div>    
  </div>

Javascript

angular.module('app', ['ui.bootstrap'])
  .directive('svgContainer', function() {
    return {
      restrict: 'A',
      template: function() {
        var parent = angular.element('body');
        return '<svg class="svg-container" width="' + parent.width() + '" height="' + parent.height() + '" viewBox=" 0 0 ' + parent.width() + ' ' + parent.height() + '"preserveAspectRatio ="xMinYMax meet"></svg>';
      },
      scope: {
        svgSrc: '=',
        position: '='
      },
      link: function(scope, element, attrs) {

        var parent = angular.element('#svg-main-wrapper');

        var x = 0;
        var y = parent.height() - 400;

        var svg = d3.select(element[0]);
        var g = svg.append('g');

        var innersvg = g.append('svg')
          .attr('xlink:href', scope.svgSrc)
          .attr('preserveAspectRatio', scope.position)
          .attr('width', parent.width())
          .attr('height', 400)
          .attr('transform', 'translate(' + x + ',' + y + ')');

      },
      replace: true
    };
  })

  .controller('ctrl', ['$scope', '$window', function($scope, $window) {

    $scope.svgContainer = [
      {
        id: 0,
        short_name: 'left',
        url: './images/complete.svg',
        position: 'none'
      }
      ];
  }]);

【问题讨论】:

  • 当您提到“svg:image”属性时,您是否尝试过使用image 元素——g.append('image')?这种方法有什么问题?
  • 内部 SVG 元素将是另一个复杂的 SVG 图形。如果它只是一个图像标签,我无法进一步操作它的子节点

标签: javascript html angularjs d3.js svg


【解决方案1】:

您的问题是:“是否可以使用 D3 将 SVG 附加到 SVG?” 标题中的 object 有点误导(但是,如果您'真的在谈论&lt;object&gt; 甚至加载外部SVG,你做错了,下面的解释是没有用的。在这种情况下,像this one 这样的答案会更有用)。

答案是肯定的。无论出于何种原因,您想要嵌套这些 SVG(您可能不需要它),只需像使用任何其他元素一样使用 append 方法即可。

这是一个演示,看看控制台:SVG 里面有一个 SVG。

var svg = d3.select("body").append("svg");
svg.append("text")
  .attr("y", 20)
  .text("this text is in the outer SVG");
var innerSVG = svg.append("svg");
innerSVG.append("text")
  .attr("y", 50)
  .text("this text is in the inner SVG");

var mySVG = (new XMLSerializer()).serializeToString(svg.node());
console.log(mySVG)
&lt;script src="https://d3js.org/d3.v4.min.js"&gt;&lt;/script&gt;

【讨论】:

  • 您是要绘制那个内部 SVG 还是要导入它已经制作好的?在最后一种情况下,请检查我的答案中的链接。
  • @GerardoFurtado 上面的代码有效。我想附加输入复选框。怎么做 ??提前致谢
  • @Arunjai 不清楚你想要什么。请将此作为一个新问题发布,并附上所有相关详细信息。
  • 嗨@GerardoFurtado,就像上面的代码一样,我想附加复选框。怎么做。如果不清楚,我会发布一个新问题。
  • @Arunjai 非常不同。除此之外,我无法回答 cmets 部分的问题,因此请将其作为新问题发布。
【解决方案2】:

如您所见,我们的组件将是代码驱动的,模板中除了作为容器的 div 之外没有任何内容。图表大小将从该元素的大小推断,这将有助于使 SVG 像普通 html 节点一样做出反应。这是代码的主要部分,即“src/app/bar-chart/bar-chart.component.ts”文件:

 private createChart(): void {
    d3.select('svg').remove();
    const element = this.chartContainer.nativeElement;
    const data = this.data;
    const svg = d3.select(element).append('svg')
        .attr('width', element.offsetWidth)
        .attr('height', element.offsetHeight);
    const contentWidth = element.offsetWidth - this.margin.left - this.margin.right;
    const contentHeight = element.offsetHeight - this.margin.top - this.margin.bottom;
    const x = d3
      .scaleBand()
      .rangeRound([0, contentWidth])
      .padding(0.1)
      .domain(data.map(d => d.letter));
    const y = d3
      .scaleLinear()
      .rangeRound([contentHeight, 0])
      .domain([0, d3.max(data, d => d.frequency)]);
    const g = svg.append('g')
      .attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')');
    g.append('g')
      .attr('class', 'axis axis--x')
      .attr('transform', 'translate(0,' + contentHeight + ')')
      .call(d3.axisBottom(x));
    g.append('g')
      .attr('class', 'axis axis--y')
      .call(d3.axisLeft(y).ticks(10, '%'))
      .append('text')
        .attr('transform', 'rotate(-90)')
        .attr('y', 6)
        .attr('dy', '0.71em')
        .attr('text-anchor', 'end')
        .text('Frequency');
    g.selectAll('.bar')
      .data(data)
      .enter().append('rect')
        .attr('class', 'bar')
        .attr('x', d => x(d.letter))
        .attr('y', d => y(d.frequency))
        .attr('width', x.bandwidth())
        .attr('height', d => contentHeight - y(d.frequency));
  }
}

链接网站:https://tienanhvn.blogspot.com/2019/06/create-responsive-angular-d3-charts.html

【讨论】:

    猜你喜欢
    • 2014-03-10
    • 1970-01-01
    • 2021-06-27
    • 2015-07-25
    • 1970-01-01
    • 1970-01-01
    • 2016-07-22
    • 1970-01-01
    • 2018-06-13
    相关资源
    最近更新 更多