如何将 d3.js v5 模块导入到聚合物 3 元素中?
How to import the d3.js v5 module into a polymer 3 element?
我之前使用 d3 v3 创建了聚合物 1.x 自定义元素。我想将它们更新为 polymer 3 和 d3 v5。
这是我想将 d3 v5 包含在其中的基础聚合物 3 元素:
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';
因为 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 使用普通选择器(例如 d3.select
)无法通过的阴影 DOM。
在这个例子中,我修改自 Force-Directed Graph。
我之前使用 d3 v3 创建了聚合物 1.x 自定义元素。我想将它们更新为 polymer 3 和 d3 v5。
这是我想将 d3 v5 包含在其中的基础聚合物 3 元素:
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';
因为 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 使用普通选择器(例如 d3.select
)无法通过的阴影 DOM。
在这个例子中,我修改自 Force-Directed Graph。