したがって、ディレクティブをコンポーネントに変換しようとしています。ディレクティブは基本的に、入力データセットが与えられたときに伝説のあるドーナツチャートをレンダリングします。また、ドーナツ上の円弧上にマウスを置くと、ポップアップアニメーションが表示されます。この指令は絶対にうまく動作します。問題は、ディレクティブをコンポーネントに変換したときです。上記のテンプレートがangularJSはd3jsのカスタムドーナツディレクティブをコンポーネントに変換します
<div layout="row" id={{$ctrl.chartId}} layout-align="center center"></div>
上記のコンポーネントが正常に動作し、意図したとおりにドーナツグラフを描画する成分
(() => {
angular
.module('charts.donut-chart')
.component('donutChart', {
templateUrl: 'charts/donut-chart/donut-chart.html',
controller: DonutChartController,
bindings: {
chartData: '=',
chartColors: '=',
chartHeight: '=',
chartWidth: '=',
legendHeight: '=',
hover: '@',
tooltips: '=',
enableLegend: '=',
id: '=',
},
});
function DonutChartController ($document, donutOptionsFactory, $filter, $scope, $timeout, $window, $element, $attrs, $compile) {
// console.log($element, $attrs);
const d3 = $window.d3;
const vm = this;
const timestamp = new Date().getTime();
vm.chartId = `donut_chart_${timestamp}`;
const donutOptions = {
chartWidth: vm.chartWidth,
chartHeight: vm.chartHeight,
legendHeight: vm.legendHeight,
};
// chart options
let chartWidth;
let chartHeight;
let enableLegend;
let legendHeight;
let outerRadiusOfArc;
let innerRadiusOfArc;
let color;
let arcColors;
let pie;
let arc;
let svgContainer;
let formattedDonutChartOptions;
let svgElement;
const deregistrationFn = $scope.$watch(() => $document[0].querySelector(`#${this.chartId}`), (newValue) => {
if (newValue !== null) {
deregistrationFn();
svgContainer = d3.select(`#${vm.chartId}`);
vm.initChartOptions();
createChart();
// bindMouseEvents();
}
});
vm.initChartOptions =() => {
formattedDonutChartOptions = donutOptionsFactory.getOptionsForDonutChart(donutOptions, svgContainer);
chartWidth = formattedDonutChartOptions.chartWidth;
chartHeight = formattedDonutChartOptions.chartHeight;
enableLegend = formattedDonutChartOptions.enableLegend;
legendHeight = formattedDonutChartOptions.legendHeight;
outerRadiusOfArc = formattedDonutChartOptions.outerRadiusOfArc;
innerRadiusOfArc = formattedDonutChartOptions.innerRadiusOfArc;
color = formattedDonutChartOptions.chartColors;
};
function onArcMouseOver (d, path) {
console.log('mouseover', d, path);
d3.select(path).transition()
.attr('d', d3.svg.arc()
.innerRadius(outerRadiusOfArc * 1.5)
.outerRadius(outerRadiusOfArc));
}
function onArcMouseOut (d, path) {
console.log('mouseout', d, path);
d3.select(path).transition()
.duration(500)
.ease('bounce')
.attr('d', d3.svg.arc()
.innerRadius(innerRadiusOfArc)
.outerRadius(outerRadiusOfArc));
}
function createChart() {
arcColors = d3.scale.ordinal()
.range(color);
pie = d3.layout.pie()
.sort(null)
.value(d => d.value);
arc = d3.svg.arc()
.innerRadius(innerRadiusOfArc)
.outerRadius(outerRadiusOfArc);
svgElement = svgContainer.append('svg')
.attr('width', chartWidth)
.attr('height', chartHeight)
.append('g')
.attr('transform', `translate(${chartWidth/2}, ${chartHeight/2})`);
svgElement.selectAll('path')
.data(pie(vm.chartData))
.enter()
.append('path')
.attr('fill', (d, i) => arcColors(i))
.attr('d', arc)
.on('mouseover', (d, i, j) => {
console.log(d, i, j, this);
const ref = this;
const dObject = d;
// (() => {
// onArcMouseOver(dObject, d3.select(this));
// })(dObject, ref);
d3.select(this).transition()
.attr('d', d3.svg.arc()
.innerRadius(outerRadiusOfArc * 1.5)
.outerRadius(outerRadiusOfArc));
})
.on('mouseout', (d, i, j) => {
console.log(d, i, j, this);
// onArcMouseOut(d, d3.select(this));
const ref = this;
const dObject = d;
// (() => {
// onArcMouseOut(dObject, d3.select(this));
// })(dObject, ref);
d3.select(this).transition()
.duration(500)
.ease('bounce')
.attr('d', d3.svg.arc()
.innerRadius(innerRadiusOfArc)
.outerRadius(outerRadiusOfArc));
});
}
function bindMouseEvents() {
/* function pathAnim (path, dir) {
switch (dir) {
case 0: // mouseout
path.transition()
.duration(500)
.ease('bounce')
.attr('d', d3.svg.arc()
.innerRadius(innerRadiusOfArc)
.outerRadius(outerRadiusOfArc));
break;
case 1:// mouseover
path.transition()
.attr('d', d3.svg.arc()
.innerRadius(outerRadiusOfArc * 1.5)
.outerRadius(outerRadiusOfArc));
break;
default: break;
}
}*/
const eventObject = {
mouseover (d) {
console.log('mouseover', this, d);
// pathAnim(d3.select(this), 1);
},
mouseout (d) {
console.log('mouseout', this, d);
// pathAnim(d3.select(this), 0);
},
};
svgElement.on(eventObject);
}
}
})();
については、以下のコードを見つけてください。問題の領域は、私が指示のようなホバー効果を行うことができないということです。私はマウスイベントをバインドする2つの方法を試みました。最初の関数は関数bindMouseEvents()を使用して別々にあり、この関数は動作し、円弧のすべての始点と終点の値を持つ 'd'引数を返しますが、これらの関数のthis
は定義されていないか、DonutControllerを指しています。 this
は、ホバリングされていない要素を指す必要があります。
私は2番目のアプローチを試しました。私は、パスのセクション.on('mouseover', (d, i, j) => {
にデータを追加するイベントをバインドします。私は匿名のコールバックを割り当て、その中から私自身の関数を起動して、自分の関数に引数を渡します。ここで私はクロムのデバッガを使用してコードをデバッグしているときにthis
がホバリングされた要素を正しく指していることを示していますが、私自身の関数に渡すときにはthis
のオブジェクト値がすべて空または未定義として渡され、 。
だから最初のアプローチでは、私は必要に応じてd
オブジェクトを取得しますがthis
がめちゃくちゃされ、第二のアプローチでは、私は適切にthis
を取得するが、私は私の関数を呼び出すと、それにthis
を渡すとき、それは次のように渡されています空のオブジェクト(すべてのキーを持ち、それらのキーの値が空または未定義のオブジェクト)。
私は何かを指摘できますか?または、私のディレクティブをコンポーネントに変換するための良い方法はありますか?事前に
おかげで脂肪矢印表記のための主な理由の
:ここにあなたのコードを使用した作業のデモンストレーションだ
。私は、矢印の表記法を使用していることが「これ」を保存しないことを理解しました。 Mozillaのドキュメントが私を助けてくれました。 – digitalis