2016-06-13 9 views
0

Я пытаюсь построить файл topoJson в нескольких диаграммах в DOM. Пример, который я предоставляю, включает только две диаграммы, но я хочу в конечном итоге увеличить масштаб. Моя проблема в том, что хотя код Javascript точно такой же в каждом из двух контейнеров, файл topoJSON отображается только во втором контейнере. Я считаю, что это имеет какое-то отношение к режиму рендеринга D3, но я не могу понять это. Вот код и результирующая страница.D3.js Rendering topoJSON в нескольких диаграммах

P.S. Извините за избыточность кода JS. Я сделал это только ради примера

<!doctype html> 
<meta charset="utf-8"> 

<script src="./js/d3.js"></script> 
<script src="./js/topojson.js"></script> 


<body> 
    First Map (Empty!!!) 
    <div id='container1'> 

    <script charset="utf-8"> 

    var width=2712/9; 
    var height=1955/9; 
    var rasterBounds=[[-1.3312652841195303 , 41.964452901889715] , [1.748235284119533 , 43.59348149262565]]; 

    var projection = d3.geo.mercator() 
     .scale(1) 
     .translate([0, 0]) 

    var b = [projection(rasterBounds[0]), projection(rasterBounds[1])], 
     s = 1/Math.max((b[1][0] - b[0][0])/width, (b[1][1] - b[0][1])/height), 
     t = [(width - s * (b[1][0] + b[0][0]))/2, (height - s * (b[1][1] + b[0][1]))/2] 
    //update projection 
    projection 
     .scale(s) 
     .translate(t) 

    // geo path generator 
    var path = d3.geo.path() 
     .projection(projection) 


    var map = d3.select('#container1').append('svg') 
     .attr('width', width) 
     .attr('height', height) 

    map.append("rect") 
     .attr("width", "100%") 
     .attr("height", "100%") 
     .attr("fill", "#E6E6E6"); 

    var color = d3.scale.ordinal() 
     .domain(["1", "2", "3"]) 
     .range(["#ffd633", "#aaff00" , "#267300"]); 


    d3.json('MapTopoFinal.json', function(error, topology) { 
      map.selectAll("path") 
       .data(topojson.feature(topology, topology.objects.Fin_Map).features) 
      .enter() 
       .append("path") 
      .attr("d", path) 
      .attr("fill", function(d) { 
       return color(d.properties.DN); 
       }) 
      .style("opacity", .6); 
    }) 


    </script> 
    </div> 


    Second Map (OK) 
    <div id='container2'> 
    <script charset="utf-8"> 

    var width=2712/9; 
    var height=1955/9; 
    var rasterBounds=[[-1.3312652841195303 , 41.964452901889715] , [1.748235284119533 , 43.59348149262565]]; 

    var projection = d3.geo.mercator() 
     .scale(1) 
     .translate([0, 0]) 

    var b = [projection(rasterBounds[0]), projection(rasterBounds[1])], 
     s = 1/Math.max((b[1][0] - b[0][0])/width, (b[1][1] - b[0][1])/height), 
     t = [(width - s * (b[1][0] + b[0][0]))/2, (height - s * (b[1][1] + b[0][1]))/2] 
    //update projection 
    projection 
     .scale(s) 
     .translate(t) 

    // geo path generator 
    var path = d3.geo.path() 
     .projection(projection) 


    var map = d3.select('#container2').append('svg') 
     .attr('width', width) 
     .attr('height', height) 

    map.append("rect") 
     .attr("width", "100%") 
     .attr("height", "100%") 
     .attr("fill", "#E6E6E6"); 

    var color = d3.scale.ordinal() 
     .domain(["1", "2", "3"]) 
     .range(["#ffd633", "#aaff00" , "#267300"]); 


    d3.json('MapTopoFinal1.json', function(error, topology) { 
      map.selectAll("path") 
       .data(topojson.feature(topology, topology.objects.Fin_Map).features) 
      .enter() 
       .append("path") 
      .attr("d", path) 
      .attr("fill", function(d) { 
       return color(d.properties.DN); 
       }) 
      .style("opacity", .6); 
    }) 

    </script> 
    </div> 

</body> 

The resulting page

ответ

0

Короче говоря: разделение кода в нескольких тегов сценария не создает различные области применения.

Прямо сейчас вы используете несколько переменных в два раза чаще, чем ваш скрипт. Наиболее важным является map. Измените вторую карту из этого:

var map = d3.select('#container2').append('svg') 
    .attr('width', width) 
    .attr('height', height) 

к этому:

var map2 = d3.select('#container2').append('svg') 
    .attr('width', width) 
    .attr('height', height) 

И изменить все последующие map к map2 или что-нибудь еще. Кроме того, измените все другие повторяющиеся переменные, например color, projection и т. Д.

Не отделяйте свои сценарии. То, как они сейчас, распространяются по HTML, не является лучшей практикой, потому что браузер должен анализировать каждый скрипт, прежде чем продолжить анализировать остальную часть HTML (и это также может вызвать дополнительные проблемы). Поместите весь свой сценарий вместе, внутри одного <script></script>, в конце body.

Имейте ввиду, что использование нескольких тегов <script> не определяет различные области применения JavaScript.

+0

Большое спасибо за полезные комментарии! Я придерживался немного другого подхода и завернул JS-код в функцию с одним аргументом, то есть с контейнером div. Затем я вызывал функцию построения графика для каждого div отдельно. – spyrostheodoridis

+0

Теперь, используя функции, у вас разные области применения! –