Я работаю над проектом Polymer (v1), и один из моих пользовательских полимерных элементов должен содержать диаграмму D3 (v4). D3, похоже, довольно сильно работает с добавлением в DOM. К сожалению, Polymer кажется довольно строгим в отношении того, как выполняются манипуляции с DOM.
Я создал очень простую версию диаграммы D3, которую хочу реализовать:
index.html
<!DOCTYPE html>
<html>
<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
.bar {
fill: #0198E1;
}
</style>
</head>
<body>
<svg></svg>
<script>
var data = [100, 120, 130, 110, 150, 90];
const CHART_WIDTH = 126;
const CHART_HEIGHT = 160;
svg = d3.select('svg')
.attr("width", CHART_WIDTH)
.attr("height", CHART_HEIGHT);
svg.selectAll('rect')
.data(data).enter().append('rect')
.attr("x", function(d, i) {return i * 21})
.attr("y", function(d) {return CHART_HEIGHT - d})
.attr("height", function(d) {return d})
.attr("width", 20)
.attr("class", "bar");
</script>
</body>
</html>
Я пробовал два решения со следующими файлами.
index.html
<!DOCTYPE html>
<html>
<head>
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="./d3-chart.html">
</head>
<body>
<d3-chart></d3-chart>
</body>
</html>
d3-lib.html
<script src="https://d3js.org/d3.v4.min.js"></script>
Попытка решения 1
Используйте комбинацию D3 и Polymer, чтобы выбрать целевой элемент svg, а затем выполните добавление d3.
d3-chart.html
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="./d3-lib.html">
<dom-module id="d3-chart">
<template>
<style>
.bar {
fill: #0198E1;
}
</style>
<svg id="svg"></svg>
</template>
<script>
Polymer({
is: 'd3-chart',
properties: {
data: {
Type: Array,
value: [100, 120, 130, 110, 150, 90]
}
},
ready: function() {
const CHART_WIDTH = 126;
const CHART_HEIGHT = 160;
var svg = d3.select(this.$.svg)
.attr("width", CHART_WIDTH)
.attr("height", CHART_HEIGHT);
svg.selectAll('rect')
.data(this.data).enter().append('rect')
.attr("x", function(d, i) {return i * 21})
.attr("y", function(d) {return CHART_HEIGHT - d})
.attr("height", function(d) {return d})
.attr("width", 20)
.attr("class", "bar");
}
});
</script>
</dom-module>
Это успешно отображает диаграмму, но стиль css не применяется. Я предполагаю, что это связано с тем, что Polymer не «знает» о добавленных новых элементах.
Попытка решения 2
Используйте D3, чтобы выбрать новый элемент svg (не в DOM), выполните добавление D3 к элементу и используйте Polymer, чтобы добавить его в DOM.
d3-chart.html
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="./d3-lib.html">
<dom-module id="d3-chart">
<template>
<style>
.bar {
fill: #0198E1;
}
</style>
</template>
<script>
Polymer({
is: 'd3-chart',
properties: {
data: {
Type: Array,
value: [100, 120, 130, 110, 150, 90]
}
},
ready: function() {
const CHART_WIDTH = 126;
const CHART_HEIGHT = 160;
var newSvgElement = document.createElement("svg");
var svg = d3.select(newSvgElement)
.attr("width", CHART_WIDTH)
.attr("height", CHART_HEIGHT);
svg.selectAll('rect')
.data(this.data).enter().append('rect')
.attr("x", function(d, i) {return i * 21})
.attr("y", function(d) {return CHART_HEIGHT - d})
.attr("height", function(d) {return d})
.attr("width", 20)
.attr("class", "bar");
Polymer.dom(this.root).appendChild(newSvgElement);
}
});
</script>
</dom-module>
Этот код успешно добавляет все элементы в DOM, но ничего не отображается.
Как правильно интегрировать Polymer с D3?