2016-05-07 3 views
2

Я создаю несколько таблиц, используя d3.js, где таблицы заполняются на основе выбранной вами выпадающей опции, которая фильтрует данные. Это прекрасно работает. Я добавляю сноски к столам. Проблема, с которой я сталкиваюсь, заключается в том, что сноски div не очищаются при изменении раскрывающегося списка. Поэтому, когда вы выбираете «Раздел A», вы видите сноски a, b, c. Затем, когда вы выбираете «Раздел B», к ним добавляется сноска d. Я хочу видеть только сноску d в этом сценарии.не могу очистить d3.js div при изменении выпадающего меню

Я добавил d3.select ("# footnotes"). Remove(); выше, где создаются сноски, но это не работает. Как я могу очистить сноски div до того, как он будет создан в раскрывающемся меню?

Вот Plunker: https://plnkr.co/edit/SnuLaLcNGgOh15Vn0456?p=preview

Кодекс также ниже:

<!DOCTYPE html> 
    <html> 
    <head> 
     <style> 
      body{ 
       font-family:Arial, sans-serif; 
       font-size:14px; 
      } 
      table{ 
       border-spacing:0; 
       padding:0; 
      } 
      th{ 
       text-align:left; 
       font-weight:normal !important; 
       border-top:1px solid #ddd; 
       border-left:1px solid #ddd; 
       border-bottom:1px solid #ddd; 
       height:25px; 
       padding-left:5px; 
       width: 50px; 
      } 
      td{ 
       border:1px solid #ddd; 
       width:30px !important; 
       height:25px; 
       padding-left:5px; 
      } 
      tr.row-odd, 
      .row-odd{ 
       background: #eee; 
      } 
     </style> 
     <script src="http://d3js.org/d3.v3.min.js"></script> 
     <script src="//code.jquery.com/jquery-1.10.2.js"></script> 

    </head> 
    <body> 
     <select size="1" id="sections" type="select" name="style"> 
     <option>SELECT</option> 
     <option value="a">Section A</option> 
     <option value="b">Section B</option> 
     </select> 

     <div id="content"> 
     </div> 

    <script> 

    function filterJSON(json, key, value) { 
     var result = []; 
     for (var foo in json) { 
     if (json[foo][key] === value) { 
      result.push(json[foo]); 
     } 
     } 

     return result; 
    } 

    definitions = { 
     "a" : "a: footnote 1", 
     "b" : "b: footnote 2", 
     "c" : "c: footnote 3", 
     "d" : "d: footnote 4" 
    }; 

    var notes=""; 
    var added=[]; 

    d3.json("data3.json", function(json) { 
    d3.json("footnotes.json", function(foot){ 
       json.forEach(function(d) { 
        d.year = +d.year; 
       }); 

       $('#sections') 

        .on("change", function() { 
         var section = $(this).val(); 

         data1 = filterJSON(json, 'set', section); 
         filterFootnotes = filterJSON(foot, 'set', section); 

         //make an object with footnotes 
          function merge(data1, filterFootnotes) { 

           function makeObj(a) { 
            obj[a.state] = obj[a.state] || {}; 
            obj[a.state][a.year] = obj[a.state][a.year] || {}; 
            Object.keys(a).forEach(function (k) { 
             obj[a.state][a.year][k] = a[k]; 
            }); 
           } 
           var array = [], 
            obj = {}; 

           data1.forEach(makeObj); 
           filterFootnotes.forEach(makeObj); 
           Object.keys(obj).forEach(function (k) { 
            Object.keys(obj[k]).forEach(function (kk) { 
             array.push(obj[k][kk]); 
            }); 
           }); 
           return array; 
          } 
          var fullData = merge(data1, filterFootnotes); 

         // add years for select indicator 
         var nestyr = d3.nest() 
          .key(function(d) { return d.year; }) 
          .sortKeys(d3.ascending) 
          .map(data1); 

         var yearstring = Object.keys(nestyr); 

         var tableData = [], 
          states = {}; 
          fullData.forEach(function (d) { 
          var state = states[d.state]; 
          if (!state) { 
           tableData.push(state = states[d.state] = {}); 
           } 
            if (d.footnote_id){ 
             state[d.year] = d.value + " <sup class='footnote'>" + d.footnote_id + "</sup>"; 
             if(added.indexOf(d.footnote_id)==-1){ 
              states[d.state]['footnote'] = d.footnote_id; 
              if(undefined!=definitions[d.footnote_id]){ 
               notes+=definitions[d.footnote_id]+"<br />"; 
               added.push(d.footnote_id); 
              } 
              } 
             } else{ 
              state[d.year] = d.value; 
             } 
          states[d.state].State = d.state; 
         }); 

         yearstring.unshift("State"); 

         // render the table 
         tabulate(tableData, yearstring); 

         // add footnotes 
         d3.select("#footnotes").remove(); 
         var fnotes = d3.selectAll('#content').append('div').attr("id", "footnotes").html(notes); 

       }); 

       var width = 200, height = 25; 
       var minInd = d3.min(json, function(d) { return d.value;}) 
       var maxInd = d3.max(json, function(d) { return d.value;}) 

       xScale = d3.scale.linear().range([0, width - 10]).domain(d3.extent(json, function(d) { return d.year; })), 
       yScale = d3.scale.linear().range([height, 0]).domain([minInd,maxInd]), 

       xAxis = d3.svg.axis().scale(xScale).tickFormat(d3.format('0f')), 
       yAxis = d3.svg.axis().scale(yScale).orient("left"); 

     }); // close footnotes json 
    }); // close json 


    function tabulate(newData, columns) { 

       d3.select("#table").remove(); 

       var table = d3.select('#content').append('table').attr("id", "table") 
       var thead = table.append('thead') 
       var tbody = table.append('tbody'); 

       thead.append('tr') 
        .selectAll('th') 
        .data(columns).enter() 
        .append('th') 
        .text(function (column) { return column; }); 

       var rows = tbody.selectAll('tr') 
        .data(newData) 
        .enter() 
        .append('tr'); 

       rows.attr("class", function(d, i){ if (i++ % 2 === 0){return 'row-even'}else {return 'row-odd'}}); 

       var cells = rows.selectAll('td') 
        .data(function (row) { 
        return columns.map(function (column) { 
         return {column: column, value: row[column]}; 
        }); 
        }) 
        .enter() 
        .append('td') 
         .attr("class", function (d,i) { return columns[i]; }) 
        .html(function (d) { return d.value; }); 

       return table; 
    }; 
    </script> 
    </body> 
    </html> 

Файлы JSON находятся в Plunker.

ответ

3

Ваш d3.select("#footnotes").remove(); работает, это не проблема. Проблема в том, что ваши var notes и var added следует очистить после каждого change. То, что я сделал, просто помещало их в вашу функцию «изменения».

Вот plunker: https://plnkr.co/edit/Co61GlCydJAzxiV24Adt?p=preview

PS: Я не большой поклонник использования remove() в D3. Вы можете легко получить те же результаты без его использования (например, это то же самое, но без части remove(): https://plnkr.co/edit/5OS2BTwSWl1om4IPqcEV?p=preview).

+0

Большое спасибо за решение. Я очень ценю это. Спасибо также за ваш отзыв о том, что вы не используете remove() - мне нравится этот подход. – sprucegoose

+1

Я имею в виду, вы можете использовать 'remove()', это не что-то «неправильно», но это не способ D3 для обновления вещей. Приветствия. –

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