我一直在关注一些关于如何在 Angular 应用程序中实现 d3 图表的演练。基本上,我试图实现以下 d3 chart进入我的自定义 Angular Directive(指令)('workHistory')。出于这个问题的目的,我正在关注一个简单的条形图 example我在哪里设置它:
index.html
<!doctype html>
<html lang="en" ng-app="webApp">
<head>
<meta charset="utf-8">
<title>My Portfolio</title>
<!--Stylesheets -->
<link rel="stylesheet" href="styles/main.css"/>
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.min.css"/>
<!--Libraries -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<script src="bower_components/jquery/dist/jquery.min.js"></script>
<script src="bower_components/angular-route/angular-route.min.js"></script>
<script src="bower_components/angular-loader/angular-loader.min.js"></script>
<script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="bower_components/d3/d3.min.js"></script>
<!--Module -->
<script src="scripts/modules/module.js"></script>
<script src="scripts/modules/d3.module.js"></script>
<!--Controllers -->
<script src="scripts/controllers/mainHeroController.js"></script>
<script src="scripts/controllers/workHistoryController.js"></script>
<!--Directives-->
<script src="scripts/directives/mainHero.directive.js"></script>
<script src="scripts/directives/mainNavbar.directive.js"></script>
<script src="scripts/directives/workHistory.directive.js"></script>
</head>
<!--Main Landing Page-->
<body ng-app="webApp">
<div id="container1">
<work-history chart-data="myData"></work-history>
</div>
<div id="container2">
Container 2
</div>
</body>
</html>
workHistory.directive.js
(function()
{
'use strict';
angular
.module('webApp')
.directive('workHistory', workHistory);
function workHistory()
{
var directive =
{
restrict: 'EA',
controller: 'WorkHistoryController',
//controllerAs: 'workhistory',
scope: {data: '=chartData'},
template: "<svg width='850' height='200'></svg>",
link: workHistoryLink,
};
return directive;
}
function workHistoryLink(scope, element/*, attrs, ctrl, tfn*/)
{
var chart = d3.select(element[0]);
chart.append("div").attr("class", "chart")
.selectAll('div')
.data(scope.data).enter().append("div")
.transition().ease("elastic")
.style("width", function(d) { return d + "%"; })
.text(function(d) { return d + "%"; });
}
})();
main.css
.axis path,
.axis line{
fill: none;
stroke:black;
shape-rendering:crispEdge;
}
.axis text{
font-family: sans-serif;
font-size: 10px;
}
h1{
font-family: sans-serif;
font-weight: bold;
font-size: 16px;
}
.tick
{
stroke-dasharray: 1, 2;
}
问题: 使用此代码,不会显示任何内容。我收到以下错误:
angular.js:13920TypeError: chart.append(...).attr(...).selectAll(...).data(...).enter is not a function
有人可以帮助我了解如何正确设置吗? (奖金,如果有人可以解释我如何将可折叠树 d3 图表配置到自定义指令中。
谢谢。
最佳答案
您的代码中有几个错误:
- 你的模板不好:你制作了一个 svg,但是你在里面插入了标准的 html 标签。它不可能工作。在这种情况下,您应该制作一个带有 div 标签的模板作为根节点。
- 如果您想像您一样提供初始模板,则应通过将指令的 replace 属性设置为 true 使其成为根节点。
- 然后,如果您希望通过 d3 添加的 div 可见,您应该通过设置背景或带有“.style('background', 'blue')”的边框来使它们可见
- 我不明白您可以在 Controller “WorkHistoryController”中做什么。根据我的说法,在这样的指令中,您应该避免同时提供链接和 Controller 。
- 最后,如果您希望整个想法始终有效,您应该将 D3 代码放入一个 $watch 中,以确保在范围内设置数据后触发生成。
- 作为补充,现在你的图形总是观察数组,如果数组比以前小,它应该处理不需要的元素的删除:“.exit().remove();”
指令应该看起来像这样:
angular
.module('app', [])
.directive('workHistory', workHistory);
function workHistory()
{
var directive =
{
restrict: 'EA',
scope: {data: '=chartData'},
replace:true,
template: "<div style='width:100%'></div>",
link: workHistoryLink,
};
return directive;
}
function workHistoryLink(scope, element)
{
scope.$watch('data', function(){
var chart = d3.select(element[0]);
chart.append("div").attr("class", "chart")
.selectAll('div')
.data(scope.data).enter().append("div")
.style('background', 'blue')
.transition().ease("elastic")
.style("width", function(d) { return d + "%"; })
.text(function(d) { return d + "%"; })
.exit().remove();
}, true);
}
这里有一个 jsbin 来说明我的观点:http://jsbin.com/vegesigevi/edit?html,js,output
希望对你有帮助
关于javascript - 如何在 Angular 中的自定义指令内设置 d3 图表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39559920/