用D3js将JSON转换为SVG平面图
JSON to SVG plan drawing with D3js
所以这将是我第一次仅仅通过搜索就找不到问题的答案。。
我是D3和Javascript的新手,我试图在浏览器中实现从CAD工具(Autodesk Revit)导出的一些曲线的可视化。我已经将几何体导出到json,数据结构可以在这里查看:http://codepen.io/MadsHolten/pen/RaJGOp.js
正如你所看到的,我有直线和弧线。现在我只是想让线路正常工作,但我还没有成功。
我的方法是循环遍历数据,并以以下格式生成一个新的Javascript对象:
[ [{x: startX, y: startY},{x: endX, y: endY}],[{...},{...}] ]
我以为我已经成功了,但我收到了以下错误:"错误:属性d="MNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN
坐标的数据类型可能有问题(但我不明白为什么)。
var w = 1000,
h = 600;
var svg = d3.select("#d3").append("svg")
.attr("width", w)
.attr("height", h);
//accessor function used by the path generator to produce path data (this works for lines - find another one for archs later)
var lineFunction = d3.svg.line()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; })
.interpolate("linear");
d3.json("http://codepen.io/MadsHolten/pen/RaJGOp.js",function(error, plan) { if (error) return console.error(error);
//Loop through lines of room 0 (for test purpose)
var lineArray = [];
for(i=0;i<plan[0][0].length;i++){
var pointArray = [];
//Start point
var x = (plan[0][0][i].start[0]).toFixed(0);
var y = (plan[0][0][i].start[1]).toFixed(0);
var startPoint = {x: x, y: y};
pointArray.push(startPoint);
//End point
var x = (plan[0][0][i].end[0]).toFixed(0);
var y = (plan[0][0][i].end[1]).toFixed(0);
var endPoint = {x: x, y: y};
pointArray.push(endPoint);
//Push line start and end point to lineArray
lineArray.push(pointArray);
}
var testdata = JSON.stringify(lineArray);
d3.select("#console").html('testdata = '+testdata+';');
svg.append("path")
.attr("d", lineFunction(lineArray))
.attr("stroke", "blue")
.attr("stroke-width", 2)
.attr("fill", "none");
});
请在此处查看我的完整代码笔:http://codepen.io/MadsHolten/pen/mPLzOx?editors=1010
问题是lineFunction
需要形式为[{x: #, y: #}, {x: #, y: #}]
的数据。您的代码为它提供了一个数组。
为了将阵列拆分为"可用"部分,您必须使用d3 enter
功能。
svg.selectAll("path").data(lineArray)
.enter().append("path")
.attr("d", linefunction)
.attr("stroke", "blue")
.attr("stroke-width", 2)
.attr("fill", "none");
此代码将:
- 获取所有路径
- 将数据与所有选定的路径匹配
- Enter操作缺失的元素,即存在数据但未选择任何内容的元素
- 为进入的对象创建路径并设置属性
- 当您使用
.attr("d", linefunction)
时,它会自动调用带有绑定到对象的数据的lineFunction
如果用这个代码替换附加块,它就会工作。也就是说,不会显示任何内容,因为您的坐标在SVG之外。
首先,由于@JSBob声明您的数据结构不正确。你想要一个点的数组,而你有一个点数组的数组。与其按照他的建议去做,我只想建立一个更平坦的阵列。
其次,应该将字符串x和y的值强制转换为数字。
第三,您需要解决坐标映射问题(从用户空间单元移动到像素空间单元);这就是d3.scales的用途。
把所有这些想法放在一起:
var w = 1000,
h = 600;
var svg = d3.select("#d3").append("svg")
.attr("width", w)
.attr("height", h);
//accessor function used by the path generator to produce path data (this works for lines - find another one for archs later)
var xS = d3.scale.linear().range([0,w]),
yS = d3.scale.linear().range([0,h]);
var lineFunction = d3.svg.line()
.x(function(d) { return xS(d.x); })
.y(function(d) { return yS(d.y); })
.interpolate("linear");
var lineArray = [];
var plan = [[[{"end":[-8486.116239411676,12835.110726856616,3199.999999999939],"primitive":"line","start":[-2239.281919861382,12835.110726856616,3199.999999999939]},{"end":[-9261.116239411669,12060.110726856617,3199.999999999939],"middle":[-9034.123994831243,12608.118482276192,3199.999999999939],"primitive":"arc","start":[-8486.116239411669,12835.110726856617,3199.999999999939]},{"end":[-9261.116239411669,11198.225231380193,3199.999999999939],"primitive":"line","start":[-9261.116239411669,12060.11072685661,3199.999999999939]},{"end":[-5826.691683009594,9948.196921016917,3199.999999999939],"primitive":"line","start":[-9261.116239411669,11198.225231380193,3199.999999999939]},{"end":[-5826.691683009596,9508.020490004836,3199.999999999939],"primitive":"line","start":[-5826.691683009595,9948.196921016919,3199.999999999939]},{"end":[-5826.6916830096,7618.520490004801,3199.999999999939],"primitive":"line","start":[-5826.691683009596,9508.020490004836,3199.999999999939]},{"end":[-2239.2819198613906,7618.520490004789,3199.999999999939],"primitive":"line","start":[-5826.691683009599,7618.520490004801,3199.999999999939]},{"end":[-2239.2819198613815,12835.110726856616,3199.999999999939],"primitive":"line","start":[-2239.2819198613906,7618.520490004789,3199.999999999939]}]],[[{"end":[-2103.7819198613815,12835.110726856616,3199.999999999939],"primitive":"line","start":[-486.11623941167545,12835.110726856616,3199.999999999939]},{"end":[-2103.781919861391,7618.520490004788,3199.999999999939],"primitive":"line","start":[-2103.781919861382,12835.110726856616,3199.999999999939]},{"end":[288.88376058833137,7618.520490004782,3199.999999999939],"primitive":"line","start":[-2103.7819198613906,7618.520490004789,3199.999999999939]},{"end":[288.8837605883311,12060.110726856623,3199.999999999939],"primitive":"line","start":[288.8837605883311,7618.520490004781,3199.999999999939]},{"end":[-486.11623941166886,12835.110726856616,3199.999999999939],"middle":[61.89151600790524,12608.118482276192,3199.999999999939],"primitive":"arc","start":[288.88376058833103,12060.110726856617,3199.999999999939]}]],[[{"end":[5705.558316990388,7483.020490004815,3199.999999999939],"primitive":"line","start":[5705.558316990388,3985.110726856617,3199.999999999939]},{"end":[513.8837605883309,7483.020490004815,3199.999999999939],"primitive":"line","start":[5705.558316990388,7483.020490004815,3199.999999999939]},{"end":[-2171.531919861391,7483.02049000479,3199.999999999939],"primitive":"line","start":[513.8837605883309,7483.020490004781,3199.999999999939]},{"end":[-5826.691683009598,7483.020490004801,3199.999999999939],"primitive":"line","start":[-2171.531919861391,7483.020490004789,3199.999999999939]},{"end":[-5826.691683009604,3985.110726856616,3199.999999999939],"primitive":"line","start":[-5826.691683009598,7483.020490004801,3199.999999999939]},{"end":[-3369.4416830096116,3985.110726856616,3199.999999999939],"primitive":"line","start":[-5826.691683009604,3985.110726856616,3199.999999999939]},{"end":[-3144.441683009611,3985.110726856645,3199.999999999939],"primitive":"line","start":[-3369.441683009612,3985.110726856616,3199.999999999939]},{"end":[513.8837605883314,3985.110726856634,3199.999999999939],"primitive":"line","start":[-3144.441683009611,3985.1107268566457,3199.999999999939]},{"end":[1938.883760588331,3985.1107268566293,3199.999999999939],"primitive":"line","start":[513.8837605883311,3985.110726856634,3199.999999999939]},{"end":[5705.558316990389,3985.110726856617,3199.999999999939],"primitive":"line","start":[1938.883760588331,3985.1107268566293,3199.999999999939]}]],[[{"end":[5705.558316990388,3849.610726856618,3199.999999999939],"primitive":"line","start":[5705.558316990388,1514.3156084306947,3199.999999999939]},{"end":[2006.6337605883305,3849.6107268566298,3199.999999999939],"primitive":"line","start":[5705.558316990388,3849.6107268566175,3199.999999999939]},{"end":[2006.6337605883266,1514.3156084307066,3199.999999999939],"primitive":"line","start":[2006.6337605883307,3849.6107268566298,3199.999999999939]},{"end":[5705.558316990389,1514.3156084306947,3199.999999999939],"primitive":"line","start":[2006.6337605883266,1514.3156084307066,3199.999999999939]}]],[[{"end":[5705.558316990388,-866.9795099951864,3199.999999999939],"primitive":"line","start":[2006.633760588323,-866.9795099951864,3199.999999999939]},{"end":[5705.558316990388,1378.815608430694,3199.999999999939],"primitive":"line","start":[5705.558316990388,-866.9795099951864,3199.999999999939]},{"end":[2006.633760588326,1378.8156084307066,3199.999999999939],"primitive":"line","start":[5705.558316990388,1378.8156084306947,3199.999999999939]},{"end":[2006.6337605883227,-866.9795099951862,3199.999999999939],"primitive":"line","start":[2006.6337605883266,1378.8156084307066,3199.999999999939]}]],[[{"end":[1871.1337605883227,-866.9795099951864,3199.999999999939],"primitive":"line","start":[581.6337605883233,-866.9795099951864,3199.999999999939]},{"end":[1871.1337605883266,1446.5656084307068,3199.999999999939],"primitive":"line","start":[1871.1337605883227,-866.9795099951864,3199.999999999939]},{"end":[1871.1337605883307,3849.6107268566293,3199.999999999939],"primitive":"line","start":[1871.1337605883266,1446.5656084307068,3199.999999999939]},{"end":[581.6337605883309,3849.6107268566343,3199.999999999939],"primitive":"line","start":[1871.1337605883307,3849.6107268566298,3199.999999999939]},{"end":[581.6337605883233,-866.9795099951866,3199.999999999939],"primitive":"line","start":[581.6337605883309,3849.6107268566343,3199.999999999939]}]],[[{"end":[-3144.4416830096125,-866.9795099951866,3199.999999999939],"primitive":"line","start":[-3144.4416830096125,3849.610726856646,3199.999999999939]},{"end":[446.1337605883232,-866.9795099951864,3199.999999999939],"primitive":"line","start":[-3144.4416830096125,-866.9795099951864,3199.999999999939]},{"end":[446.1337605883308,3849.610726856634,3199.999999999939],"primitive":"line","start":[446.13376058832324,-866.9795099951864,3199.999999999939]},{"end":[-3144.4416830096125,3849.610726856646,3199.999999999939],"primitive":"line","start":[446.1337605883308,3849.6107268566343,3199.999999999939]}]],[[{"end":[-9261.116239411669,4760.11072685661,3199.999999999939],"primitive":"line","start":[-9261.116239411669,7483.020490004812,3199.999999999939]},{"end":[-8486.116239411673,3985.110726856615,3199.999999999939],"middle":[-9034.123994831245,4212.1029714370425,3199.999999999939],"primitive":"arc","start":[-9261.116239411669,4760.110726856617,3199.999999999939]},{"end":[-5962.191683009603,3985.110726856616,3199.999999999939],"primitive":"line","start":[-8486.116239411669,3985.110726856616,3199.999999999939]},{"end":[-5962.191683009598,7483.020490004801,3199.999999999939],"primitive":"line","start":[-5962.191683009604,3985.110726856616,3199.999999999939]},{"end":[-9261.116239411669,7483.020490004812,3199.999999999939],"primitive":"line","start":[-5962.191683009598,7483.020490004801,3199.999999999939]}]],[[{"end":[-9261.116239411669,7618.520490004812,3199.999999999939],"primitive":"line","start":[-9261.116239411669,9440.270490004847,3199.999999999939]},{"end":[-5962.191683009598,7618.520490004801,3199.999999999939],"primitive":"line","start":[-9261.116239411669,7618.520490004812,3199.999999999939]},{"end":[-5962.191683009595,9440.270490004836,3199.999999999939],"primitive":"line","start":[-5962.191683009599,7618.520490004801,3199.999999999939]},{"end":[-9261.116239411669,9440.270490004845,3199.999999999939],"primitive":"line","start":[-5962.191683009595,9440.270490004836,3199.999999999939]}]],[[{"end":[-9261.116239411669,9575.770490004845,3199.999999999939],"primitive":"line","start":[-9261.116239411669,11054.029143209707,3199.999999999939]},{"end":[-5962.191683009594,9575.770490004836,3199.999999999939],"primitive":"line","start":[-9261.116239411669,9575.770490004845,3199.999999999939]},{"end":[-5962.191683009594,9853.318799589504,3199.999999999939],"primitive":"line","start":[-5962.191683009595,9575.770490004836,3199.999999999939]},{"end":[-9261.11623941167,11054.029143209707,3199.999999999939],"primitive":"line","start":[-5962.191683009594,9853.318799589504,3199.999999999939]}]]];
//Loop through lines of room 0 (for test purpose)
for(i=0;i<plan[0][0].length;i++){
var pointArray = [];
//Start point
var x = (plan[0][0][i].start[0]).toFixed(0);
var y = (plan[0][0][i].start[1]).toFixed(0);
var startPoint = {x: +x, y: +y};
lineArray.push(startPoint);
//End point
var x = (plan[0][0][i].end[0]).toFixed(0);
var y = (plan[0][0][i].end[1]).toFixed(0);
var endPoint = {x: +x, y: +y};
lineArray.push(endPoint);
}
xS.domain(d3.extent(lineArray, function(d){
return d.x;
}));
yS.domain(d3.extent(lineArray, function(d){
return d.y;
}));
var testdata = JSON.stringify(lineArray);
d3.select("#console").html('testdata = '+testdata+';');
svg.append("path")
.attr("d", lineFunction(lineArray))
.attr("stroke", "blue")
.attr("stroke-width", 2)
.attr("fill", "none");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div class="container-fluid">
<h2 class="text-center">D3 plan from Flux.io</h2>
<div id="d3">
</div>
<div id="console">
</div>
</div>
评论编辑
现在您想要使用嵌套选择:
svg.selectAll(".room").data(roomArray)
.enter()
.append("g") //<-- each g is a collection of paths that make up the room
.attr("class", "room")
.selectAll("path")
.data(function(d){
return d; //<-- return the array of data for the room
})
.enter()
.append("path")
.attr("d", lineFunction)
.attr("stroke", "blue")
.attr("stroke-width", 2)
.attr("fill", "none");
已更新代码笔。
- D3在一个调用中绘制不同的SVG形状,没有可见性
- 如何使用javascript从主svg对象动态创建svg视图框
- 如何更改<svg>标记为<img>用js标记
- 锚点元素不't使用svg时,请打开EDGE上的href
- 带有填充属性的SVG矩形显示在包含元素的上方插入框阴影
- 使用onclick绘制SVG路径
- SVG/JavaScript:尝试选择和更改多边形点
- 顺时针旋转Svg元件
- 禁用SVG拖动
- 在select元素中显示highchart dashstyle(svg)
- 在D3.js中,有没有任何方法可以将x和y方向上的滚动事件绑定到平移svg
- 缩放Raphael/SVG容器以适应所有内容
- JavaScript-动态SVG-onload属性-未触发事件
- 设置动画时,SVG/Raphael大圆圈会变形
- 使用SVG和JavaScript创建波浪动画
- Canvas+svg路径动画,在路径中的特定点暂停一段时间,然后继续
- D3.js生成有效的SVG,但不显示任何内容
- SVG xml to image
- 用D3js将JSON转换为SVG平面图
- 将Autocad .dwg转换为SVG,再转换为PolyMap的tile,从而生成活动平面图