2013-06-26 3 views
3

Я хочу обновить Treemap динамически с новыми данными. Я прочитал это article, но я не запускаю его. Так что это мой код:D3.js обновить Treemap динамически

function buildTreemap(jVals){ 
    //$("#treemap").empty(); 

    var data = jQuery.parseJSON(jVals); 

    var margin = {top: 40, right: 10, bottom: 10, left: 10}, 
     width = 760 - margin.left - margin.right, 
     height = 500 - margin.top - margin.bottom; 

    var treemap = d3.layout.treemap() 
     .size([width, height]) 
     .sticky(true) 
     .sort(function(a,b) { return a.anzahl - b.anzahl; }) 
     .round(true) 
     .value(function(d) { return Math.log(d.anzahl); }); 

    var div = d3.select("#treemap").append("div") 
     .style("position", "relative") 
     .style("width", (width + margin.left + margin.right) + "px") 
     .style("height", (height + margin.top + margin.bottom) + "px") 
     .style("left", margin.left + "px") 
     .style("top", margin.top + "px") 
     .attr("id", "first"); 

    var node = div.datum(data).selectAll(".node") 
     .data(treemap.nodes) 
     .enter().append("div") 
     .attr("class", "node") 
     .style("left", function(d) { return d.x + "px"; }) 
     .style("top", function(d) { return d.y + "px"; }) 
     .style("width", function(d) { return Math.max(0, d.dx - 1) + "px"; }) 
     .style("height", function(d) { return Math.max(0, d.dy - 1) + "px"; }) 
     .style("background", function(d) { return d.color ? d.color : "#ffffff";}) 
     .text(function(d) { return d.children ? "blue" : d.keytable + "(" + d.anzahl + "-" + Math.max(0, d.dx) + "-" + Math.max(0, d.dy) + ")"; }) 
     ; 

}; 

С другой Js-функции я вызываю buildTreemap() с новыми данными. Теперь я хочу, чтобы treemap перерисовывался с помощью Transition/Duration.

Может ли кто-нибудь помочь мне, пожалуйста. Большого спасибо ...

Update: Я добавил это:

d3.selectAll("input").on("change", function change() { 
     var value = this.value === "count" 
      ? function() { return 1; } 
      : function(d) { return Math.log(d.anzahl); }; 

     node 
      .data(treemap.value(value).nodes) 
      .transition() 
      .duration(1500) 
      .call(position); 
    }); 

и с этим кодом TreeMap перестраивает, если я нажимаю "изменить" -input. Но если я возьму этот код:

d3.selectAll("#search").on("keyup", function change() { 
     var value = function(d) { return Math.log(d.anzahl); }; 

     node 
      .data(treemap.value(value).nodes) 
      .transition() 
      .duration(1500) 
      .call(position); 
    }); 

treemap остается и еще один treemap с новыми значениями данных открывается ниже моего первого. На клавиатуре запускается другая js-функция и отправляются новые данные в buildTreemap().

+0

Вы видели [это] (http://bl.ocks.org/mbostock/4063582)? –

+0

Да, но это только масштабирует размер div с теми же данными. Мне нужно перемасштабировать новые данные. – maker23

+0

Принцип тот же. Он по-прежнему передает новые данные в макет treemap при изменении. –

ответ

3

Я упростил и немного изменил ваш jsfiddle here, чтобы отобразить второй набор данных при нажатии кнопки. Ключ в том, что внутри функции, которую вы называете, когда кнопка нажата, вы передаете в новых данных, как вы делали, когда вы инициализирован в TreeMap, а затем обрабатывать ввод и обновление выбора соответственно, например, так:

var node = div.datum(data2).selectAll(".node") 
      .data(treemap.nodes); 
node.enter().append("div") 
    .attr("class", "node"); 

node.transition().duration(1500).call(position) 
    .style("background", function(d) { return d.color ? d.color : "#ffffff"; }) 
    .text(function(d) { return d.children ? "blue" : d.keytable + "(" + d.anzahl + "-" + Math.max(0, d.dx) + "-" + Math.max(0, d.dy) + ")"; }); 

Обратите внимание, что выбор ввода сливается с выбором обновления, поэтому достаточно просто добавить узлы и установить атрибуты в выборе обновления.

+0

Хорошо, очень хорошо! Но если я беру более сложные данные, поведение очень странно. Посмотрите на это: http://jsfiddle.net/maker23/WB5jh/4/ – maker23

+0

Я думаю, что старые узлы остались в treemap, а новые вытолкнули ... что-то вроде этого !! !!?! – maker23

+0

Просто добавьте 'node.exit(). Remove()' в конце функции изменения. –

0

Я не вижу неправильного форматирования.

Мои первые данные:

{ 
    "name": "items", 
    "children": [ 
     { 
      "id": "33447", 
      "anzahl": "13", 
      "color": "#ff8080", 
      "keytable": "CCR", 
      "bordercolor": "#B25959" 
     }, 
     { 
      "id": "33455", 
      "anzahl": "4", 
      "color": "#80ff80", 
      "keytable": "COMMODITY", 
      "bordercolor": "#59B259" 
     }, 
     { 
      "id": "2", 
      "anzahl": "37", 
      "color": "#80ffff", 
      "keytable": "COUNTRY", 
      "bordercolor": "#59B2B2" 
     }, 
     { 
      "id": "33465", 
      "anzahl": "3", 
      "color": "#ff0000", 
      "keytable": "FUNDS", 
      "bordercolor": "#B20000" 
     }, 
     { 
      "id": "67400", 
      "anzahl": "22", 
      "color": "#ffff00", 
      "keytable": "GOVERNMENT", 
      "bordercolor": "#B2B200" 
     }, 
     { 
      "id": "29", 
      "anzahl": "183", 
      "color": "#008080", 
      "keytable": "INDEX", 
      "bordercolor": "#005959" 
     }, 
     { 
      "id": "33449", 
      "anzahl": "1", 
      "color": "#8080ff", 
      "keytable": "INTER", 
      "bordercolor": "#5959B2" 
     }, 
     { 
      "id": "67422", 
      "anzahl": "8", 
      "color": "#800000", 
      "keytable": "PARTY", 
      "bordercolor": "#590000" 
     }, 
     { 
      "id": "33358", 
      "anzahl": "4", 
      "color": "#8000ff", 
      "keytable": "PM", 
      "bordercolor": "#5900B2" 
     }, 
     { 
      "id": "30", 
      "anzahl": "1920", 
      "color": "#f90631", 
      "keytable": "SHARE", 
      "bordercolor": "#AE0422" 
     }, 
     { 
      "id": "81", 
      "anzahl": "70960", 
      "color": "#11b1ee", 
      "keytable": "WARRANT", 
      "bordercolor": "#0B7BA6" 
     }, 
     { 
      "id": "1", 
      "anzahl": "1", 
      "color": "#004000", 
      "keytable": "WORLD", 
      "bordercolor": "#002C00" 
     } 
    ] 
} 

и второй данные:

{ 
    "name": "items", 
    "children": [ 
     { 
      "id": "29", 
      "anzahl": "12", 
      "color": "#008080", 
      "keytable": "INDEX", 
      "bordercolor": "#005959" 
     }, 
     { 
      "id": "55645", 
      "anzahl": "165", 
      "color": "#11b1ee", 
      "keytable": "WARRANT", 
      "bordercolor": "#0B7BA6" 
     } 
    ] 
} 

Ok в консоли это выглядит иначе ... но почему:

data1:

Object {name: "items", children: Array[12]} 
area: 333000 
children: Array[12] 
depth: 0 
dx: 740 
dy: 450 
name: "items" 
value: 39.15699051089851 
x: 0 
y: 0 
__proto__: Object 

данные2:

Object {name: "items", children: Array[2]} 
children: Array[2] 
name: "items" 
__proto__: Object 

Но дети тоже там ...

UPDATE:

Я думаю, что на data2 ошибку "Uncaught TypeError: Не удается прочитать свойство 'детей' неопределенных" означает, что один из наборов данных отсутствует.

В скрипке оба набора данных, в которых функция прерывается. Но в моем живом примере представлены наборы данных, которые передаются функции.Likie это:

function buildTreemap(jVals_all, jVals_filtered, doRebuild){ 

if(doRebuild === false){ 
    var data1 = jQuery.parseJSON(jVals_all); 
} 
if(doRebuild === true){ 
    var data2 = jQuery.parseJSON(jVals_filtered); 
} 
.... 
} 

Итак, возможно, что, если я отправить data2 функция отсутствует детей data1, потому что data1 пуст ??

В конце я хочу передать только один объект функции ...

function buildTreemap(data){} 

Если это легче решить, тогда я предпочитаю этот путь.