使用 angularjs 和 d3.js 在一页中显示多个图表
Multiple graphs in one single page using angularjs and d3.js
我刚刚开始学习 AngularJS 和 D3.js 绘制条形图。我成功地在一页中绘制了一个条形图。但是我在用不同数据绘制多个图表时遇到了问题。例如:我的 app.js
看起来如下:
// Module name to be included in html app
var app = angular.module('App', []);
// FundamoCtrl controller which holds the data from the JSON
app.controller("FundamoCtrl", function($scope) {
$scope.tags = [
{'#text': "author-vimal", '@pass': 4},
{'#text': "author-raj", '@pass': 8},
{'#text': "tt-positive", '@pass': 15},
{'#text': "tt-negative", '@pass': 16},
{'#text': "author-selvam", '@pass': 23},
{'#text': "author-inba", '@pass': 42}
];
});
// Custom filter for the json data
app.filter('filterData', function() {
return function(data, searchFor) {
var property = Object.keys(searchFor)[0];
var result = [];
for (var i = 0; i < data.length; i++) {
if (data[i][property].indexOf(searchFor[property]) > -1) {
result.push(data[i]);
}
}
return result;
};
});
// Bar Graph to show the result
app.directive('barGraph', [
'$filter',
function($filter) {
return {
restrict: 'EA',
scope: {
data: '=',
filtername: '=',
filtervalue: '=',
},
link: function(scope, element, attrs) {
var margin = {top: 20, right: 30, bottom: 30, left: 40},
width = 500 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(5);
var svg = d3.select(element[0])
.append("svg")
.attr("class", "chart");
scope.render = function(data) {
x.domain(data.map(function(d) { return d['#text']; }));
y.domain([0, d3.max(data, function(d) { return d['@pass']; })]);
var chart = d3.select(".chart")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var bar = chart.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("transform", function(d, i) { return "translate(" + x(d['#text']) + ", 0)"; });
bar.append("rect")
.attr("class", "rect-bar")
.attr("y", function(d) { return y(d['@pass']); })
.attr("height", function(d) { return height - y(d['@pass']); })
.attr("width", x.rangeBand());
bar.append("text")
.attr("x", x.rangeBand() / 2)
.attr("y", function(d) { return y(d['@pass']) + 15; })
.attr("dy", ".5em")
.text(function(d) { return d['@pass']; })
.attr("class", "bar-text");
chart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
chart.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 0 - margin.left)
.attr("x", 0 - (height / 2))
.attr("dy", "1em")
.style("text-anchor", "middle")
.text("Pass Count");
};
scope.$watch('data', function(data) {
data = $filter(scope.filtername)(data, scope.filtervalue);
scope.render(data);
}, true);
}
};
}
]);
在正文部分下的 html 模板中,我有如下内容:
<div ng-controller="MyCtrl">
<bar-graph id="bar1" data="tags" filtername="'filterData'" filterValue="{'#text': 'author-'}"></bar-graph>
<bar-graph id="bar2" data="tags" filtername="'filterData'" filterValue="{'#text': 'tt-'}"></bar-graph>
</div>
在输出中,bar2 散布在 bar1 的顶部。我想将 bar2 放在 bar1 旁边,但我做不到。请帮我解决这个问题。
有关详细信息,请参阅此 Plunker
好的,所以我找到了问题所在。我将 g
标记附加到 class
属性,其中 class 值为 chart
。所以它需要第一个 chart
并一次又一次地附加到同一个图表。所以乱七八糟的。
现在我正在创建一个动态 ID,它将在运行时附加到 svg
元素,从而解决了上述问题。
有关详细信息,请参阅 Plunker。
我刚刚开始学习 AngularJS 和 D3.js 绘制条形图。我成功地在一页中绘制了一个条形图。但是我在用不同数据绘制多个图表时遇到了问题。例如:我的 app.js
看起来如下:
// Module name to be included in html app
var app = angular.module('App', []);
// FundamoCtrl controller which holds the data from the JSON
app.controller("FundamoCtrl", function($scope) {
$scope.tags = [
{'#text': "author-vimal", '@pass': 4},
{'#text': "author-raj", '@pass': 8},
{'#text': "tt-positive", '@pass': 15},
{'#text': "tt-negative", '@pass': 16},
{'#text': "author-selvam", '@pass': 23},
{'#text': "author-inba", '@pass': 42}
];
});
// Custom filter for the json data
app.filter('filterData', function() {
return function(data, searchFor) {
var property = Object.keys(searchFor)[0];
var result = [];
for (var i = 0; i < data.length; i++) {
if (data[i][property].indexOf(searchFor[property]) > -1) {
result.push(data[i]);
}
}
return result;
};
});
// Bar Graph to show the result
app.directive('barGraph', [
'$filter',
function($filter) {
return {
restrict: 'EA',
scope: {
data: '=',
filtername: '=',
filtervalue: '=',
},
link: function(scope, element, attrs) {
var margin = {top: 20, right: 30, bottom: 30, left: 40},
width = 500 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(5);
var svg = d3.select(element[0])
.append("svg")
.attr("class", "chart");
scope.render = function(data) {
x.domain(data.map(function(d) { return d['#text']; }));
y.domain([0, d3.max(data, function(d) { return d['@pass']; })]);
var chart = d3.select(".chart")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var bar = chart.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("transform", function(d, i) { return "translate(" + x(d['#text']) + ", 0)"; });
bar.append("rect")
.attr("class", "rect-bar")
.attr("y", function(d) { return y(d['@pass']); })
.attr("height", function(d) { return height - y(d['@pass']); })
.attr("width", x.rangeBand());
bar.append("text")
.attr("x", x.rangeBand() / 2)
.attr("y", function(d) { return y(d['@pass']) + 15; })
.attr("dy", ".5em")
.text(function(d) { return d['@pass']; })
.attr("class", "bar-text");
chart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
chart.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 0 - margin.left)
.attr("x", 0 - (height / 2))
.attr("dy", "1em")
.style("text-anchor", "middle")
.text("Pass Count");
};
scope.$watch('data', function(data) {
data = $filter(scope.filtername)(data, scope.filtervalue);
scope.render(data);
}, true);
}
};
}
]);
在正文部分下的 html 模板中,我有如下内容:
<div ng-controller="MyCtrl">
<bar-graph id="bar1" data="tags" filtername="'filterData'" filterValue="{'#text': 'author-'}"></bar-graph>
<bar-graph id="bar2" data="tags" filtername="'filterData'" filterValue="{'#text': 'tt-'}"></bar-graph>
</div>
在输出中,bar2 散布在 bar1 的顶部。我想将 bar2 放在 bar1 旁边,但我做不到。请帮我解决这个问题。
有关详细信息,请参阅此 Plunker
好的,所以我找到了问题所在。我将 g
标记附加到 class
属性,其中 class 值为 chart
。所以它需要第一个 chart
并一次又一次地附加到同一个图表。所以乱七八糟的。
现在我正在创建一个动态 ID,它将在运行时附加到 svg
元素,从而解决了上述问题。
有关详细信息,请参阅 Plunker。