我有粘贴here的d3.js代码。
我试图在同一页面中显示多个图表。虽然d3.js代码是相同的。从data1.json中说一个,从data2.json中说另一个。以下是困扰我的片段。
<svg width="960" height="960"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var svg2 = d3.select("svg"),
margin = 20,
diameter = +svg2.attr("width"),
g = svg2.append("g").attr("transform", "translate(" + diameter / 2 + "," + diameter / 2 + ")");
根据SO here,here,here,here或here中的不同答案,解决方案似乎是以下之一:< / p>
使用here所述的方法。
var chart1 = d3.select("#area1")
.append("svg")
方法二对我不起作用,因为它显示空白页。
如何解决这个问题。我确信我没有正确地获得语法。
答案 0 :(得分:5)
在同一页面上使用多个SVG完全没问题。这是一个例子:
var svg1 = d3.select("#svg1");
svg1.append("circle")
.attr("cx",100)
.attr("cy", 100)
.attr("r", 90)
.attr("fill", "red");
var svg2 = d3.select("#svg2");
svg2.append("circle")
.attr("cx",100)
.attr("cy", 100)
.attr("r", 90)
.attr("fill", "blue");
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg width="200" height="200" id="svg1"></svg>
<svg width="200" height="200" id="svg2"></svg>
&#13;
答案 1 :(得分:3)
您无需重复所有代码,就像您现在正在做的那样。 Don't repeat yourself
一个简单的替代方法是将所有D3代码包装在一个包含两个参数selector
和url
的函数中:
function draw(selector, url){
//code here
};
然后,在该函数draw
内,设置SVG的位置:
var svg = d3.select(selector).append("svg")...
您获取数据的URL:
d3.json(ulr, function(error, root) {...
之后,只需使用不同的参数调用draw
函数两次:
draw(selector1, url1);
draw(selector2, url2);
这是一个演示,仔细阅读以了解它是如何工作的:
draw("#svg1", "#data1");
draw("#svg2", "#data2");
function draw(selector, url){
var data = d3.csvParse(d3.select(url).text())
var width = 500,
height = 150;
var svg = d3.select(selector)
.append("svg")
.attr("width", width)
.attr("height", height);
var xScale = d3.scalePoint()
.domain(data.map(function(d) {
return d.name
}))
.range([50, width - 50])
.padding(0.5);
var yScale = d3.scaleLinear()
.domain([0, d3.max(data, function(d) {
return d.value
}) * 1.1])
.range([height - 20, 6]);
var line = d3.line()
.x(function(d){ return xScale(d.name)})
.y(function(d){ return yScale(d.value)});
svg.append("path")
.attr("d", line(data))
.attr("stroke", "teal")
.attr("stroke-width", "2")
.attr("fill", "none");
var xAxis = d3.axisBottom(xScale);
var yAxis = d3.axisLeft(yScale);
svg.append("g").attr("transform", "translate(0,130)")
.attr("class", "xAxis")
.call(xAxis);
svg.append("g")
.attr("transform", "translate(50,0)")
.attr("class", "yAxis")
.call(yAxis);
}
&#13;
pre {
display: none;
}
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
<div>First SVG</div>
<div id="svg1"></div>
<div>Second SVG</div>
<div id="svg2"></div>
<pre id="data1">name,value
foo,8
bar,1
baz,7
foobar,9
foobaz,4</pre>
<pre id="data2">name,value
foo,1
bar,2
baz,3
foobar,9
foobaz,8</pre>
&#13;
答案 2 :(得分:0)
如果这两个图表使用相同的代码,我认为最像d3的方式就是
var width = 960,
height = 960,
margin = 30;
var svgs = d3.select('#area1')
.selectAll('svg')
.data([json1, json2])
.enter()
.append('svg')
.attr('width', width)
.attr('height', height)
svgs.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
.each(function(d) {console.log(d)}) // will log json1, then json2
然后你将json1和json2绑定到每个新附加的svgs,后面的所有代码都将完成。
var width = 200,
height = 100,
margin = 30;
var svgs = d3.select('#area1')
.selectAll('svg')
.data([{text:'thing1'}, {text:'thing2'}])
.enter()
.append('svg')
.attr('width', width)
.attr('height', height);
svgs.append("text")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
.text(function(d) {return d.text});
<script src="https://d3js.org/d3.v4.js"></script>
<div id='area1'></div>