admin管理员组文章数量:1312795
is it possible to append another svg to a preexisting svg parent using d3.js?
I know that its possible by using an 'svg:image'-attribute. But unfortunately then i am loosing full control about the inner svg-child.
The regarding dom node gets created by d3 but is not rendered and as a result the page stays blank.
Hope somebody can help, thx in advance :)
Here's what I got:
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>
is it possible to append another svg to a preexisting svg parent using d3.js?
I know that its possible by using an 'svg:image'-attribute. But unfortunately then i am loosing full control about the inner svg-child.
The regarding dom node gets created by d3 but is not rendered and as a result the page stays blank.
Hope somebody can help, thx in advance :)
Here's what I got:
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/plete.svg',
position: 'none'
}
];
}]);
Share
Improve this question
edited Jul 13, 2017 at 15:56
luQ
asked Jul 13, 2017 at 15:19
luQluQ
5291 gold badge13 silver badges26 bronze badges
2
-
When you refer to the "svg:image" attribute, did you try using an
image
element --g.append('image')
? What was wrong with that approach? – anbnyc Commented Jul 13, 2017 at 15:33 - The inner SVG element will be another plex SVG graphic. If it's just an image tag, iam not able to further manipulate it's child nodes – luQ Commented Jul 13, 2017 at 15:37
2 Answers
Reset to default 6Your question is: "is it possible to append an SVG to an SVG using D3?" That object in the title is a bit misleading (However, if you're really talking about an <object>
or even loading an external SVG, you're doing it wrong, and the following explanation would be useless. In that case, answers like this one will be more useful).
The answer is yes. For whatever reason you want to nest those SVGs (you probably don't need it), just use the append
method as you would with any other element.
Here is a demo, have a look at the console: there is an SVG inside an 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)
<script src="https://d3js/d3.v4.min.js"></script>
As you can see, our ponent will be code-driven, with nothing in the template except a div, which will serve as our container. The chart size will be inferred from the size of this element, which will be helpful in making the SVG react like a normal html node. Here is the main part of the code, the ‘src/app/bar-chart/bar-chart.ponent.ts’ file:
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));
}
}
Link webs: https://tienanhvn.blogspot./2019/06/create-responsive-angular-d3-charts.html
本文标签: javascriptHow to append an svg to an prexisting svg using d3jsStack Overflow
版权声明:本文标题:javascript - How to append an svg to an prexisting svg using d3.js? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741836295a2400234.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论