【问题标题】:Angular-ui + D3: how to implement contextual menu (popover vs modal)?Angular-ui + D3:如何实现上下文菜单(popover vs modal)?
【发布时间】:2013-11-08 11:57:49
【问题描述】:

给定以下用例:

我使用 D3js 来渲染由 AngularJS 管理的对象。我想为 D3 图表添加交互性。单击 svg 元素时,我希望有一种允许修改对象属性的弹出菜单。 AngularJS 需要这些属性,但 D3 不呈现这些属性。

D3-Angular 集成源自使用闭包的http://bl.ocks.org/biovisualize/5372077

当前实施:

截至今天,我正在使用 angular-ui bootstrap 中的 $modal 服务来创建弹出菜单。从功能的角度来看,它工作得很好: 当点击一个 svg 元素时,D3 调度一个事件 该事件被调用 $modal 服务的 Angular 捕获 在模态窗口中,我修改对象属性

但是我对渲染不满意。我希望弹出菜单看起来像一个弹出框。它应该靠近被点击的 svg 元素。

据我了解,我有两种选择

  1. 继续使用 $modal 服务并修改其外观。应该采取什么方法?使用 windowClass 选项?
  2. 停止使用 $modal 服务并开始破解 popover 指令。问题是我认为不可能 将这样的指令添加到 svg 元素。解决方案是 在 $modal 服务附近创建一个弹出服务。

应该选择哪个选项?以及如何实现?

编辑:

使用自定义 my-popover 指令的工作 plunker: http://plnkr.co/edit/5KYvxi?p=preview

【问题讨论】:

    标签: angularjs d3.js modal-dialog popover angular-ui


    【解决方案1】:

    可以在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

    【讨论】:

    • 谢谢。我使用 angular-ui bootstrap 中的 popover 指令尝试了您的解决方案,并注意到它可以工作。这是一个plunker:plnkr.co/edit/ZjNZChVPlBUDWPxGhuEL?p=preview点击一个栏时应该打开一个弹出框,但它不是。
    • 我对 plunker 进行了许多更改:将content 的拼写固定为contents,添加了bootstrap.{js,css},编写了指令myPopover,它在内部使用了tooltip。当compared to the actual implementation 时,position calculation in ui.angular 已损坏。因此,ui.bootstrap 将起作用,但为 svg 元素计算的位置不正确。我稍后会提交一份错误报告/修复它。答案中添加了演示。
    • 为修复创建了一个拉取请求:github.com/angular-ui/bootstrap/pull/1225
    • 拉取请求已被合并,现在使用 popover 和最新版本的 ui.bootstrap 应该也可以工作。
    猜你喜欢
    • 1970-01-01
    • 2016-04-24
    • 1970-01-01
    • 2014-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-12
    • 2010-09-30
    相关资源
    最近更新 更多