2016-04-19 7 views
1

Так что это будет первый раз, когда я не мог найти ответ на мою проблему, просто поиск ..JSON плану SVG рисования D3js

Я совершенно новой для D3 и Javascript в целом, и то, что я пытаюсь достичь, - это визуализация некоторых кривых, экспортированных из инструмента САПР (Autodesk Revit) в моем браузере. Я экспортировал геометрию в json, и структуру данных можно пересмотреть здесь: http://codepen.io/MadsHolten/pen/RaJGOp.js

Как видите, у меня есть линии и дуги. На данный момент я просто пытаюсь заставить строки работать, но я еще не успел.

Мой подход к проходным данных и создать новый объект Javascript в следующем формате:

[ [{x: startX, y: startY},{x: endX, y: endY}],[{...},{...}] ]

я думал, что это удалось, но я получаю следующее сообщение об ошибке: «Error: Invalid значение атрибута D = "MNaN, NaNLNaN, NaNLNaN, NaNLNaN, NaNLNaN, NaNLNaN, NaNLNaN, NaNLNaN, NaN"»

Там может быть проблема с типом данных координат (но не могу понять, почему) ,

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"); 
}); 

Смотрите мой полный codepen здесь: http://codepen.io/MadsHolten/pen/mPLzOx?editors=1010

ответ

1

Вопрос заключается в том, что 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"); 

будет этот код:

  • получить все пути к
  • MATCH данные для всех выбранных путей
  • Enter работает на недостающих элементов, т.е. там, где существуют данные, но ничего не было выбрано
  • Для входящих объектов создайте путь и установите атрибуты
  • Когда вы используете .attr("d", linefunction), это utomatically называет lineFunction с данными, связанными с объектом

Если вы замените блок добавления этим кодом, он будет работать. При этом ничего не отображается, потому что ваши координаты находятся вне SVG.

0

Во-первых, поскольку @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>

редактирует ДЛЯ КОММЕНТАРИЕВ

Теперь вы хотите использовать nested selection:

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"); 

Обновлено codepen.

+0

Благодарим вас за предоставление таких подробных ответов! Я закончил тем, что сделал часть обоих. Я добавил массив точек со всеми точками, чтобы получить расширения: http://codepen.io/MadsHolten/pen/mPLzOx – MadsHolten

+0

Моя следующая проблема заключается в том, что когда я добавляю остальные комнаты в массив, я получаю еще один уровень, и я немного потерял то, как я настроил это наилучшим образом. Идея заключается в том, что позже будут добавлены свойства комнат, которые, например, должны отображаться при наведении курсора мыши. Думаю, мне нужно будет сохранить влияние иерархии? См. Этот код для моей попытки: http://codepen.io/MadsHolten/pen/oxyWeW?editors=1010 – MadsHolten

+0

@MadsHolten, см. Обновления выше. Это идеальное время для использования * вложенного выбора *. – Mark

Смежные вопросы