代码之家  ›  专栏  ›  技术社区  ›  Ahmad

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

  •  1
  • Ahmad  · 技术社区  · 6 年前

    我正在使用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 回复  |  直到 6 年前
        1
  •  3
  •   rioV8    6 年前

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

    你可以设置 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();
       });
    }
    
        2
  •  3
  •   Gerardo Furtado    6 年前

    只是为了增加 accepted answer ,这是一个很好的用途 D3局部变量 .

    根据 API :

    D3局部允许您定义独立于数据的局部状态。

    所以,你可以设置本地。。。

    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>