2016-10-03 4 views
1

Я создаю приложение, в котором я могу динамически добавлять и удалять диаграммы. Все работает отлично, но удаляет диаграмму.dc.js: Проблемы с dispose() и deregisterChart()

Проблема, с которой я столкнулся, возникает, когда у меня есть линейная диаграмма и гистограмма, одна из которых является составной, и я удаляю один из них (удаляем измерение и де-регистровую диаграмму). На этом этапе диаграмма, которую я не выбрал, перестает реагировать на фильтры из других диаграмм и перестает реагировать на ее собственные события, даже подумал, что другие диаграммы фильтруются ими. Кроме того, как вы можете видеть на скрипке, линейная диаграмма, которую я удалял из постоянного тока, все еще реагирует на другие фильтры диаграммы.

Я выяснил, что проблема связана с вызовом deregisterChart dc, но поскольку мое приложение может создавать и удалять бесконечные диаграммы, мне нужен способ удаления из dc тех, которые мне больше не нужны, не нарушая оставшихся.

Это код:

resetFilter = function() { 
    lineData.dispose() 
    dc.deregisterChart(linechart); 
} 


for (var j = 0; j < axis.length; j++) { 

    var dimData = __cfArray[dataId].dimension(function(d) { 
     return d[axis[j].xaxis]; 
    }); 
    var barGroup = getGroup(dimData, axis[j].xaxis, axis[j].yaxis, operation, isDate); 

    barCharts.push(dc.barChart(composite) 
     .valueAccessor(accesor) 
     .dimension(dimData) 
     .group(barGroup, xAxisTitle[j]) 
     .transitionDuration(1000) 
     .gap(gap) 
     .colors(barColors[j]) 
     .centerBar(function() { 
     if (axis.length > 1) return false; 
     else return true; 
     }) 
     .title(function(d) { 
     if (operation === count) { 
      if (isDate) return format(d.key) + ": " + d.value.count; 
      else return d.key + ": " + d.value.count; 
     } else { 
      if (isDate) return format(d.key) + ": " + d.value.total; 
      else return d.key + ": " + d.value.total; 
     } 
     }) 
    ); 


    lineData = __cfArray[dataId].dimension(function(d) { 
     return d[axis[j].xaxis]; 
    }); 
    var lineGroup = getGroupLine(lineData, axis[j].xaxis, axis[j].yaxis, true, operation, isDate); 

    linechart = dc.lineChart(lineDom) 
     .dimension(lineData) 
     .group(lineGroup, xAxisTitle[j] + "/" + yAxisTitle) 
     .useRightYAxis(true) 
     .colors(lineColors[j]) 
     .title(function(d) { 
     if (operation === count) { 
      if (isDate) return format(d.key) + ": " + d.valueCount; 
      else return d.key + ": " + d.valueCount; 
     } else { 
      if (isDate) return format(d.key) + ": " + d.valueTotal; 
      else return d.key + ": " + d.valueTotal; 
     } 
     }) 
     .valueAccessor(function(p) { 
     if (operation === count) { 
      return p.valueCount; 
     } else { 
      return p.valueTotal; 
     } 
     }); 

    } 

    var xMine; 


    var dom = []; 
    for (var i = 0; i < axis.length; i++) { 
    if (dom.length === 0) { 
     dom = __dataArray[dataId].map(function(d) { 
     return d[axis[i].xaxis] 
     }); 
    } else { 
     dom = dom.concat(__dataArray[dataId].map(function(d) { 
     return d[axis[i].xaxis] 
     })); 
    } 
    } 
    if (isNaN(dom[0])) { 
    xMine = d3.scale.ordinal().domain(dom.sort()); 
    } else { 
    xMine = d3.scale.ordinal().domain(dom.sort(function(a, b) { 
     return a - b; 
    })); 
    } 
    composite.xUnits(dc.units.ordinal) 
    linechart.xUnits(dc.units.ordinal) 


    linechart.width(width) 
    .height(height) 
    .margins(margin) 
    .x(xMine) 
    .elasticY(true) 
    .legend(dc.legend().x(80).y(10).itemHeight(13).gap(5)) 
    ._rangeBandPadding(1) 
    .brushOn(false); 

    composite.width(width) 
    .height(height) 
    .margins(margin) 
    .x(xMine) 
    .rightYAxisLabel(yAxisRightTitle) 
    .elasticY(true) 
    .legend(dc.legend().x(80).y(10).itemHeight(13).gap(5)) 
    ._rangeBandPadding(1) 
    .brushOn(false) 
    .shareTitle(false) 
    .mouseZoomable(true) 
    .yAxisPadding('10%') 
    .compose(barCharts) 
    .renderHorizontalGridLines(true); 

    composite.yAxis().tickFormat(d3.format('s')); 
    composite.rightYAxis().tickFormat(d3.format('s')); 

    composite.render(); 

    linechart.render(); 

Это скрипка я создал с моей проблемой: https://jsfiddle.net/nofknndf/9/

Спасибо!

ответ

1

Это сложная и изощренная система, в которой вы собираетесь, поздравления.

Допустим, я не понял, почему вы видите текущее странное поведение, но я нашел проблему, и я думаю, что исправил ее.

В getGroupLine, вы на самом деле необходимо создать группу каждый раз, когда поддельный группа .all() метод называется:

function getGroupLine(dimension, xaxis, yaxis, isCum, operation, isDate){ 
     return { 
      all:function() { 
     // ... 
       var _group = dimension.group().reduce(reduceAdd, reduceRemove, reduceInitial).orderNatural(); 

То есть склонны запутаться очень быстро! Я обнаружил это, перейдя в dimension.dispose() в отладчик, чтобы посмотреть, работает ли он - и каждый раз, когда он работал, все больше групп.

Группы хранятся в измерении и могут быть расположены независимо друг от друга.

Вы хотите создать «базовую группу» _group, когда функция вызывается, и вернулись фальшивая группа просто принести _group.all():

function getGroupLine(dimension, xaxis, yaxis, isCum, operation, isDate){ 
     var reduceAdd = function(p, v) { 
      if (!(isDate && v[xaxis] === 0)) { 
       ++p.count; 
       p.total += v[yaxis]; 
      } 
      return p; 
     } 

     var reduceRemove = function(p, v) { 
      if (!(isDate && v[xaxis] === 0)) { 
       --p.count; 
       p.total -= v[yaxis]; 
      } 
      return p; 
     } 

     var reduceInitial = function() { 
      return { 
       count: 0, 
       total: 0, 
       elements: [] 
      }; 
     } 
     var _group = dimension.group().reduce(reduceAdd, reduceRemove, reduceInitial).orderNatural(); 
     return { 
      all:function() { 
       var totalCount = 0; 
       var total = 0; 
       var g = []; 


       _group.all().forEach(function(d,i) { 
        if(isCum){ 
         totalCount += d.value.count; 
         total += d.value.total; 
        } else { 
         totalCount = d.value.count; 
         total = d.value.total; 
        } 
        g.push({key:d.key,valueTotal:total,valueCount:totalCount}) 
       }); 
       return g; 
      } 
     }; 
    } 

Это, кажется, объясняет, почему линия графики продолжают быть отфильтрованы ,

Другая проблема заключается в том, что неправильная диаграмма получает регистрацию. Это связано с тем, что у каждого из ваших диаграмм должен быть свой собственный уникальный якорь (id) - в вашем примере оба они были названы «составными». dc.js полагается на сравнение имен привязок, когда он отменяет регистрацию, поэтому, если обе диаграммы имеют одинаковый id, неправильный будет удален. HTML требует, чтобы id s был уникальным, поэтому вы, вероятно, столкнетесь с другими проблемами.

Переименование id для линейной диаграммы на «строку» фиксирует дерегистрацию.

обновление развилка вашей скрипку здесь: https://jsfiddle.net/dnrxxjyo/4/

+0

Привет Гордон, спасибо за вашу помощь, но она по-прежнему не работает должным образом.Как вы можете видеть в своей скрипке, после нажатия кнопки «Расположить» гистограмма больше не реагирует на события щелчка для фильтрации. Во всяком случае, не создание дополнительных групп - хороший шаг вперед, так как я динамически создаю много диаграмм. Во всяком случае, моим обходным решением на данный момент является избавление от групп и размеров (но не от диаграмм), поэтому фильтрация с существующими диаграммами не очень дорогостоящая. – ruba

+0

Ой, извините, я пропустил эту часть. Отследил его, и теперь я обновляю свой ответ. – Gordon

+0

Привет, спасибо за обновление. Я понимаю уникальную проблему с идентификатором, и я думаю, что это может быть проблемой в коде, над которым я работаю, поскольку я вызываю эту функцию несколько раз. Но я не вижу этой проблемы в примере, если только создаю диаграммы один раз, потому что одна диаграмма называется составной, а другая называется линейной. – ruba

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

  • Нет связанных вопросов^_^