首页 文章

如何将d3.js v5模块导入聚合物3元素?

提问于
浏览
1

我之前使用d3 v3创建了聚合物1.x自定义元素 . 我想将它们更新为聚合物3和d3 v5 .

这是一个基础聚合物3元素,我想包括d3 v5到:

import {html, PolymerElement} from '@polymer/polymer/polymer-element.js';

/**
 * `foo-bar`
 * 
 *
 * @customElement
 * @polymer
 * @demo demo/index.html
 */
class FooBar extends PolymerElement {
  static get template() {
    return html`
      <style>
        :host {
          display: block;
        }
      </style>
      <h2>Hello [[prop1]]!</h2>
    `;
  }
  static get properties() {
    return {
      prop1: {
        type: String,
        value: 'foo-bar',
      },
    };
  }
  constructor() {
    super();
  }

  ready() {
    super.ready();
    console.log('foo-bar is ready!');
  }

}

window.customElements.define('foo-bar', FooBar);

我叫 npm install d3

如何将d3导入此PolymerElement?我使用d3有两种不同类型的聚合物元素 . 我已经完成了力和层次聚合物元素 .

我想我需要在聚合物元素中的 constructor()ready() 函数中做一些事情以利用d3库 .

我正在尝试以下导入:

import 'd3/dist/d3.js';

1 回答

  • 2

    由于 d3 已附带ES模块 . 所以你可以根据需要import .

    import { select, scaleOrdinal } from 'd3'
    // or
    import * as d3 from 'd3'
    

    然后你可以像往常一样使用 d3 .

    例:

    的index.html

    <foo-bar></foo-bar>
    <script type='module' src='app.js'></script>
    

    app.js

    import { PolymerElement, html } from '@polymer/polymer/polymer-element.js'
    import * as d3 from 'd3'
    
    class FooBar extends PolymerElement {
      static get template () {
        return html`
          <style>
            .links line {
              stroke: #999;
              stroke-opacity: 0.6;
            }
    
            .nodes circle {
              stroke: #fff;
              stroke-width: 1.5px;
            }
          </style>
    
          <svg width='960' height='600'></svg>
        `
      }
    
      ready () {
        super.ready()
        this.initGraph()
      }
    
      initGraph () {
        let svg = d3.select(this.shadowRoot.querySelector('svg'))
        let width = +svg.attr('width')
        let height = +svg.attr('height')
    
        let color = d3.scaleOrdinal(d3.schemeCategory10)
    
        let simulation = d3.forceSimulation()
          .force('link', d3.forceLink().id(d => d.id))
          .force('charge', d3.forceManyBody())
          .force('center', d3.forceCenter(width / 2, height / 2))
    
        d3.json('miserables.json').then(graph => {
          let link = svg.append('g')
            .attr('class', 'links')
            .selectAll('line')
            .data(graph.links)
            .enter().append('line')
            .attr('stroke-width', d => Math.sqrt(d.value))
    
          let node = svg.append('g')
            .attr('class', 'nodes')
            .selectAll('circle')
            .data(graph.nodes)
            .enter().append('circle')
            .attr('r', 5)
            .attr('fill', d => color(d.group))
            .call(d3.drag()
              .on('start', dragstarted)
              .on('drag', dragged)
              .on('end', dragended))
    
          node.append('title').text(d => d.id)
    
          simulation.nodes(graph.nodes)
            .on('tick', () => {
              link
                .attr('x1', d => d.source.x)
                .attr('y1', d => d.source.y)
                .attr('x2', d => d.target.x)
                .attr('y2', d => d.target.y)
              node
                .attr('cx', d => d.x)
                .attr('cy', d => d.y)
            })
    
          simulation.force('link').links(graph.links)
        })
    
        function dragstarted (d) {
          if (!d3.event.active) simulation.alphaTarget(0.3).restart()
          d.fx = d.x
          d.fy = d.y
        }
    
        function dragged (d) {
          d.fx = d3.event.x
          d.fy = d3.event.y
        }
    
        function dragended (d) {
          if (!d3.event.active) simulation.alphaTarget(0)
          d.fx = null
          d.fy = null
        }
      }
    }
    
    customElements.define('foo-bar', FooBar)
    

    注意:Polymer使用Shadow DOM,普通选择器(例如 d3.select )无法通过 .

    在这个例子中,我从Force-Directed Graph修改 .

相关问题