Angular-ui + D3:如何实现上下文菜单(popover vs modal)? [英] Angular-ui + D3: how to implement contextual menu (popover vs modal)?
问题描述
鉴于以下用例:
我使用 D3js 来渲染由 AngularJS 管理的对象.我想为 D3 图表添加交互性.单击 svg 元素时,我想要一种允许修改对象属性的弹出菜单.AngularJS 需要这些属性,但 D3 不呈现这些属性.
I use D3js to render objects which are managed by AngularJS. I would like to add interactivity to the D3 chart. When clicking on a svg element I would like to have a kind of popup menu allowing to modify the object properties. These properties are required by AngularJS but are not rendered by D3.
D3-Angular 集成源自 http://bl.ocks.org/biovisualize/5372077 使用闭包.
The D3-Angular integration is derived from http://bl.ocks.org/biovisualize/5372077 which uses a closure.
当前实施:
截至今天,我正在使用 angular-ui bootstrap 中的 $modal 服务来创建弹出菜单.从功能的角度来看,它工作得很好:单击 svg 元素时,D3 会调度一个事件该事件由调用 $modal 服务的 Angular 捕获在模态窗口中,我修改了对象属性
As of today I am using the $modal service from angular-ui bootstrap to create the popup menu. From a functionnality point of view it works pretty well: When clicking on a svg element, D3 dispatches an event That event is catched by Angular which calls the $modal service Within the modal window I modify the object properties
但是我对渲染不满意.我希望弹出菜单看起来像一个弹出框.它应该靠近被点击的 svg 元素.
However I am not satisfied with the rendering. I would like the popup menu to look like a popover. It should be placed close to the svg element which was clicked.
据我所知,我有两种选择:
- 继续使用 $modal 服务并修改其外观.应该采取什么方法?使用 windowClass 选项?
- 停止使用 $modal 服务并开始攻击 popover 指令.问题是我不认为这是可能的将这样的指令添加到 svg 元素.解决办法是在 $modal 服务附近创建一个 popover 服务.
应该选择哪个选项?以及如何实施?
Which option should be chosen? and how to implement it?
使用自定义 my-popover 指令的工作 plunker:http://plnkr.co/edit/5KYvxi?p=preview
Working plunker using a custom my-popover directive: http://plnkr.co/edit/5KYvxi?p=preview
推荐答案
可以向 d3
生成的代码添加指令,唯一需要确保的是调用 $compile
内容呈现后的服务.
It is possible to add a directives to code generated by d3
, only thing you need to ensure is that you call the $compile
service on the content after it has been rendered.
对于给定的示例,它看起来像这样:
For the given example, it would look something like this:
.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);
这篇关于Angular-ui + D3:如何实现上下文菜单(popover vs modal)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!