I am stuck with this error, am having a custom directive for creating a bar chart, which gets generated from a json file.
Here is my code, I have a Index.Html page, where one view is routed inside based on the navigation here is the
Index.Html
<head>
<title>DiginRt</title>
<body ng-app="DiginRt" class=" pace-done" cz-shortcut-listen="true">
<div id="header-topbar-option-demo" class="page-header-topbar">
<div id="page-wrapper">
<div id="title-breadcrumb-option-demo" class="page-title-breadcrumb">
<div class="page-header pull-left">
<div class="page-title"> Dashboard</div>
</div>
<div class="clearfix"> </div>
</div>
<div class="page-content" ui-view> // Here i load the view for the dashboards </div>
</div>
</div>
</div>
<script src="script/jquery-1.10.2.min.js"></script>
<script src="script/jquery-ui.js"></script>
<script type="text/javascript">
var $j = jQuery.noConflict();
</script>
<script type="text/javascript" src="script/prototype.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.6/angular.js"></script>
<script type="text/javascript" src="script/d3.js"></script>
<script src="script/angular-ui-router.min.js"></script>
<script type="text/javascript" src="script/jquery.jsPlumb-1.4.1-all-min.js"></script>
<script type="text/javascript" src="script/plumb.js"></script>
<script type="text/javascript" src="script/app.js"></script>
</body>
</html>
Dashboard.HTML:
<body ng-controller="DashboardCtrl">
<div id="main_wrapper">
<div id="toolboxControl">
<div id="containerChart">
<ul>
<li> <a ng-click="addWidget()" href="#controlflow">Charts</a>
<div id="controlflow" class="containerChart">
<input ng-model="searchCommonValue" class="form-control" type="search" placeholder="Search controls...">
<div plumb-menu-item ng-repeat="widget in dashboard.widgets | filter : searchCommonValue" class="menu-item" data-identifier="{{widget.id}}" data-title="{{widget.name}}" draggable> <img class="toolheader" src="{{widget.Icon}}">
<div class="toolcontent">{{widget.name}}</div>
</div>
</div>
</li>
</ul>
</div>
</div>
<div ng-controller="CustomWidgetCtrl" id="container" class="drop-container" ng-click="addEvent($event)" droppable>
<div plumb-item class="item" style="margin: 20px; top: 60px; left: 200px; height: 300px; width: 500px;" ng-repeat="widget in dashboard.widgets" ng-style="{ 'left':widget.sizeX, 'top':widget.sizeY }" data-identifier="{{widget.id}}">
<div class="box">
<div class="box-header">
<h3>{{ widget.name }}</h3>
<div class="box-header-btns pull-right"> <a title="settings" ng-click="openSettings(widget)"><i class="glyphicon glyphicon-cog"></i></a> <a title="Remove widget" ng-click="remove(widget)"><i class="glyphicon glyphicon-trash"></i></a> </div>
</div>
<div class="box-content">
<!-- <bars data="40,4,55,15,16,33,52,20"></bars> -->
<bargraph id="d3bar" datajson="sample.json" xaxis-name="Year" xaxis-pos="905" yaxis-name="Frequency" yaxis-pos="12" d3-format=".0%">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</span>
</div>
App.Js:
var routerApp = angular.module('DiginRt', ['ui.bootstrap', 'ui.router']);
routerApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/dashboard');
$stateProvider.state('dashboard', {
url: '/dashboard',
templateUrl: 'Charts.html',
controller: 'DashboardCtrl'
})
});
routerApp.controller('DashboardCtrl', ['$scope', '$timeout',
function($scope, $timeout) {
$scope.gridsterOptions = {
margins: [20, 20],
columns: 4,
draggable: {
handle: 'h3'
}
};
$scope.dashboards = {
'1': {
id: '1',
icon: 'images/icons/chart_line.png',
name: 'Home',
widgets: [{
col: 0,
row: 0,
sizeY: 1,
sizeX: 1,
icon: 'images/icons/chart_line.png',
name: "Stocks per store"
}]
}
};
}
])
routerApp.controller('CustomWidgetCtrl', ['$scope', '$modal',
function($scope, $modal) {
$scope.remove = function(widget) {
$scope.dashboard.widgets.splice($scope.dashboard.widgets.indexOf(widget), 1);
};
$scope.openSettings = function(widget) {
$modal.open({
scope: $scope,
templateUrl: 'chart_settings.html',
controller: 'chartSettingsCtrl',
resolve: {
widget: function() {
return widget;
}
}
});
};
}
])
var BarGraph = Class.create({
initialize: function(datajson, xaxisName, xaxisPos, yaxisName, yaxisPos, d3Format) {
this.datajson = datajson;
this.xaxisName = xaxisName;
this.xaxisPos = xaxisPos;
this.yaxisName = yaxisName;
this.yaxisPos = yaxisPos;
this.d3Format = d3Format;
},
workOnElement: function(element) {
this.element = element;
},
generateGraph: function() {
//d3 specific coding
var margin = {
top: 20,
right: 20,
bottom: 30,
left: 40
},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var formatPercent = d3.format(this.d3Format);
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").tickFormat(formatPercent);
var svg = d3.select(this.element).append("svg").attr("width", width + margin.left + margin.right).attr("height", height + margin.top + margin.bottom).append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.tsv(this.datajson, function(error, data) {
if (error) return console.warn(error);
//console.log(this.xaxisName);
x.domain(data.map(function(d) {
return d.letter;
}));
y.domain([0, d3.max(data, function(d) {
return +d.frequency;
})]);
svg.append("g").attr("class", "x axis").attr("transform", "translate(0," + height + ")").call(xAxis).append("text").attr("x", this.xaxisPos).attr("dx", ".71em").style("text-anchor", "end").text(this.xaxisName);
svg.append("g").attr("class", "y axis").call(yAxis).append("text").attr("transform", "rotate(-90)").attr("y", this.yaxisPos).attr("dy", ".71em").style("text-anchor", "end").text(this.yaxisName);
svg.selectAll(".bar").data(data).enter().append("rect").attr("class", "bar").attr("x", function(d) {
return x(d.letter);
}).attr("width", x.rangeBand()).attr("y", function(d) {
return y(d.frequency);
}).attr("height", function(d) {
return height - y(d.frequency);
});
}.bind(this));
}
});
routerApp.directive('bargraph', function() { // Angular Directive
return {
restrict: 'EA', // Directive Scope is Element
replace: true, // replace original markup with template
transclude: false, // not to copy original HTML DOM
compile: function(elem, attrs) { // the compilation of DOM is done here.
// It is responsible for produce HTML DOM or it returns a combined link function
// Further Docuumentation on this - http://docs.angularjs.org/guide/directive
console.log(attrs.id);
console.log(attrs.datajson);
var html = "<div id='" + attrs.id + "' ></div>"; // the HTML to be produced
var newElem = $(html);
elem.replaceWith(newElem); // Replacement of the element.
var ourGraph = new BarGraph(attrs.datajson, attrs.xaxisName, attrs.xaxisPos, attrs.yaxisName, attrs.yaxisPos, attrs.d3Format);
ourGraph.workOnElement('#' + attrs.id);
// Work on particular element
ourGraph.generateGraph(); // here is the error!
}
}
});
There was some angular code missing from your html and script. A couple of things I did:
<html ng-app="routerApp">
to the html pagevar routerApp = angular.module('routerApp', []);
to the js fileI created a PLUNK with the results. The only other difference to your code is that it was easier for me to find a TSV sample file rather than the JSON file you referenced in your code. So, I changed from d3.json
to d3.tsv
, but that is really not important here. I hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With