如何将动态对象附加到HTML元素?

时间:2018-07-30 14:04:10

标签: javascript d3.js dom

我正在使用D3.js创建此简化示例中所述的图表

class MyClass {
   // logic goes here
   // constructor() and other functions defined here.
   doSomething() {
       console.log('something.');
   }
}

function createChart(chartID, data) {
    // creating the SVG and appending it to the body
    var svg = d3.select('body').append('svg')
                     .attr('width',400)
                     .attr('height',400)
                     .attr('id',chartID);

   // instantiating an instance of MyClass to be attached to the SVG
   var anObject = new MyClass();
   svg.myObject = anObject;   // this has no effect


   // code to actually build the chart + math to be done on passed data

   // finally, attach a click event to the svg so that data can be manipulated later on
   svg.on('click',function(){
        var object = d3.select(this).myObject;   //this does not work
        object.doSomething();                   // so this also doesn't work
   });
}

createChart('test1',[1,2,3,4]);   // triggering the createChart() function

我假设变量svg像任何JSON对象一样被对待,因此,我认为我可以将任何对象附加到该对象上。

显然,事实并非如此。如何将对象附加到HTML DOM元素,以便以后可以访问该对象?

2 个答案:

答案 0 :(得分:3)

svg变量是包含DOM元素的d3选择对象。

您可以设置svg的datum(),以后再获取它

function createChart(chartID, data) {
    // creating the SVG and appending it to the body
    var svg = d3.select('body').append('svg')
                     .attr('width',400)
                     .attr('height',400)
                     .attr('id',chartID);

   // instantiating an instance of MyClass to be attached to the SVG
   var anObject = new MyClass();
   svg.datum(anObject);


   // code to actually build the chart + math to be done on passed data

   // finally, attach a click event to the svg so that data can be manipulated later on
   svg.on('click',function(){
        var object = d3.select(this).datum();
        object.doSomething();
   });
}

或者使用this处理程序中的click是DOM元素的事实

function createChart(chartID, data) {
    // creating the SVG and appending it to the body
    var svg = d3.select('body').append('svg')
                     .attr('width',400)
                     .attr('height',400)
                     .attr('id',chartID);

   // instantiating an instance of MyClass to be attached to the SVG
   var anObject = new MyClass();
   svg.node().myObject = anObject;


   // code to actually build the chart + math to be done on passed data

   // finally, attach a click event to the svg so that data can be manipulated later on
   svg.on('click',function(){
        var object = this.myObject;
        object.doSomething();
   });
}

答案 1 :(得分:3)

只需添加到已经accepted answer,这对于 D3局部变量是一个很好的用途。

根据API

  

D3 Locals允许您定义独立于数据的本地状态。

因此,您可以设置本地...

var local = d3.local();

local.set(svg.node(), myObject)

...并轻松获得它:

local.get(svg.node())

这样,您无需将不必要的数据(即与可视化无关的数据)绑定到DOM元素。

这是一个演示:

var local = d3.local();

class MyClass {
  doSomething() {
    console.log('something.');
  }
}

function createChart(chartID, data) {
  var svg = d3.select('body')
    .append('svg')
    .attr('width', 200)
    .attr('height', 200)
    .attr('id', chartID);

  var anObject = new MyClass();
  local.set(svg.node(), anObject)

  svg.on('click', function() {
    local.get(this).doSomething()
  });
}

createChart('test1', [1, 2, 3, 4]);
svg {
  background-color: wheat;
}
<script src="https://d3js.org/d3.v5.min.js"></script>