2013-10-29 12 views
5

次のユースケースを考える:私はAngularJSで管理されているオブジェクトをレンダリングするためにD3jsを使用Angular-ui + D3:コンテキストメニューの実装方法(popover vs modal)

を。私はD3チャートに対話性を追加したいと思います。 svg要素をクリックすると、オブジェクトのプロパティを変更できるポップアップメニューが表示されます。これらのプロパティはAngularJSでは必須ですが、D3ではレンダリングされません。

D3角度統合は、クロージャを使用するhttp://bl.ocks.org/biovisualize/5372077に由来します。

現在の実装:

今日の時点で、私は、ポップアップメニューを作成するには、角-UIブートストラップから$モーダルサービスを使用しています。ビューのfunctionnalityポイントから、それはかなりうまく機能: SVG要素をクリックすると、D3は、イベントを送出 このイベントは、私は、オブジェクトのプロパティに

を変更するモーダルウィンドウ内で$モーダルサービス を呼び出す角度によってcatchedされますしかし、私はレンダリングに満足していません。ポップアップメニューがポップオーバーのように見えます。クリックされたsvg要素の近くに配置する必要があります。

私の知る限り理解し、私は二つのオプションあります

  1. は$モーダルサービスを使用し、その外観を変更するために続けます。どんなアプローチをとるべきですか? windowClassオプションを使用しますか?
  2. $モーダルサービスの使用を中止し、popoverディレクティブでハッキングを開始します。問題は、このようなディレクティブをsvg要素に追加することは可能ではないと私は考えているということです。解決策は、 に$モーダルサービスの近くでpopoverサービスを作成することです。

どのオプションを選択する必要がありますか?どのように実装するのですか?

EDIT:カスタム私の-ポップオーバーディレクティブを使用してplunker作業

http://plnkr.co/edit/5KYvxi?p=preview

答えて

9

d3によって生成されたコードにするディレクティブを追加することが可能である、あなたは確認する必要が唯一のものは、そのあなたですレンダリングされたコンテンツの$compileサービスに電話してください。

.directive('barChart', function($compile){ // inject $compile 
     var chart = d3.custom.barChart(); 
     return { 
      restrict: 'E', 
      replace: true, 
      template: '<div class="chart"></div>', 
      scope:{ 
       height: '=height', 
       data: '=data', 
       hovered: '&hovered' 
      }, 
      link: function(scope, element, attrs) { 
       var chartEl = d3.select(element[0]); 
       chart.on('customHover', function(d, i){ 
        scope.hovered({args:d}); 
       }); 

       scope.$watch('data', function (newVal, oldVal) { 
        chartEl.datum(newVal).call(chart); 
        $compile(element.contents())(scope); // <-- call to $compile 
       }); 

       scope.$watch('height', function(d, i){ 
        chartEl.call(chart.height(scope.height)); 
        $compile(element.contents())(scope); // <-- call to $compile 
       }) 
      } 
     } 

そしてd3の描画機能で:

 bars.enter().append('rect') 
      .classed('bar', true) 
      .attr('myPopover', 'Text to show') // <-- Adding an attribute here. 
      .attr({x: chartW, 
       width: barW, 
       y: function(d, i) { return y1(d); }, 
       height: function(d, i) { return chartH - y1(d); } 
      }) 
      .on('mouseover', dispatch.customHover); 

Demo

+0

感謝与え例えば

が、それは次のようになります。私はあなたの解決策をangular-uiブートストラップからのpopoverディレクティブで試してみました。ここにはプランカがあります:http://plnkr.co/edit/ZjNZChVPlBUDWPxGhuEL?p=previewバーをクリックするとポップオーバーが開くはずですが、そうではありません。 – apairet

+0

私はplunkerに多くの変更を加えました。内容に 'content'を固定し、' bootstrap。{js、css} 'を追加し、 'tooltip'を内部的に使う' myPopover'指示文を書きました。実際の実装と比較すると、[ui.angular'の位置計算](https://github.com/angular-ui/bootstrap/blob/master/src/position/position.js#L69)は壊れています](https://github.com/twbs/bootstrap/blob/master/js/tooltip.js#L295)。したがって、 'ui.bootstrap'は動作しますが、' svg'要素の位置は正しくありません。私はバグレポートを提出し、後でそれを修正します。デモが答えに追加されました。 –

+1

修正プログラムのプルリクエストが作成されました:https://github.com/angular-ui/bootstrap/pull/1225 –

関連する問題