nvd3 pie chart when no data and for value zero - angularjs

I have created a pie chart using nvd3.
Here is my code :
<nvd3-pie-chart
data="examplePieData"
id="exampleId"
showLabels="true"
labelType="value"
x="xPieFunction()"
y="yPieFunction()"
donut="true"
donutRatio=".5"
tooltips="true"
noData="Data aint here"
tooltipcontent="toolTipContentFunction()"
color="pieColorFunction()"
donutLabelsOutside="false">
<svg height="200" style="margin-left: -121px; margin-top: -49px;"></svg>
</nvd3-pie-chart>
and
$scope.examplePieData = [
{
key: "First",
y: 5
},
{
key: "Second",
y: 3
},
{
key: "Third",
y: 1
}
];
$scope.toolTipContentFunction = function(){
return function(key, x, y, e, graph) {
return '<p>' + key +" "+ y.value + '</p>'
}
}
$scope.xPieFunction = function(){
return function(d) {
return d.key;
};
}
$scope.yPieFunction = function(){
return function(d) {
return d.y;
};
}
var pieColorArray = [ '#5EA9DD','#e76060', '#008000'];
$scope.pieColorFunction = function() {
return function(d, i) {
return pieColorArray[i];
};
}
Here I want to display a message when there is no data. I have tried with noDate = "Message" but it is not working. And I want to show pic chart even for y value is zero (y :0). Finally, how to adjust tooltip distance and same color for the tooltip when mouseover on the perticular field in pie chart. Help me. Thank you.

For no data, try with chart.noData() function. For me it is perfectly working,
HTML:
<div id="chart">
<svg></svg>
</div>
Javascript:
var h = 300;
var r = h/2;
var data = [];
var colors = [
'rgb(178, 55, 56)',
'rgb(213, 69, 70)',
'rgb(230, 125, 126)',
'rgb(239, 183, 182)'
];
nv.addGraph(function() {
var chart = nv.models.pieChart()
.x(function(d) { return d.label })
.y(function(d) { return d.value })
.color(colors)
.showLabels(true)
.labelType("percent");
chart.noData("No data");
d3.select("#chart svg")
.datum(data)
.transition().duration(1200)
.call(chart)
;
return chart;
});

Related

How to call d3 pie chart on button click in angularjs?

I am trying to display pie chart using d3.js charts in angularjs . As far as the examples i have seen so far implements pie chart on load . But here i want to display pie chart based on the response from service which is called on a button click . Need some guidance to start
my user.html
<h1>Group by users</h1><br>
<select name="users" id="search" ng-model="searchItem">
<option value="">Search By</option>
<option value="admin">admin</option>
<option value="superAdmin">superAdmin</option>
</select>
<button ng-click="search()">Search</button>
<div pie-chart="" style="width:100%;height:460px;" data="data"></div>
my user.js
'use strict';
angular.module('myApp.employee',['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/employee', {
templateUrl: 'employee/employee.html',
controller: 'EmployeeCtrl'
});
}])
.controller('EmployeeCtrl', ['$scope','$http',function($scope,$http) {
$scope.search = function(){
var search=angular.element(document.getElementById("search"));
//var data ;
$scope.searchItem =search.val();
console.log($scope.searchItem);
$http.get("/assets/empDetails.json").then(function(response){
// $scope.empDetail=response.data
console.log(response.data);
console.log();
// function groupBy(arr, prop) {
// const map = new Map(Array.from(arr, obj => [obj[prop], []]));
// arr.forEach(obj => map.get(obj[prop]).push(obj));
// return Array.from(map.values());
// }
// console.log(groupBy(response.data,$scope.searchItem ));
var rows = response.data;
var keyName =$scope.searchItem;
groupBy(keyName);
function groupBy(keyName) {
console.log("Group By :: ", keyName)
var occurences = rows.reduce(function (r, row) {
r[row[keyName]] = ++r[row[keyName]] || 1;
return r;
}, {});
var result = Object.keys(occurences).map(function (key) {
return { key: key, value: occurences[key] };
});
console.log(result);
//data = result ;
$scope.data = [
{
name : "Blue",
value : 10,
color : "#4a87ee"
},
{
name : "Green",
value : 40,
color : "#66cc33"
},
{
name : "Orange",
value : 70,
color : "#f0b840"
},
{
name : "Red",
value : 2,
color : "#ef4e3a"
}
];
}
})
}
}])
.directive ("pieChart", function () {
return {
restrict : "A",
scope : {
data : "="
},
link : function (scope, element) {
var width,
height,
radius,
pie,
arc,
svg,
path;
width = element[0].clientWidth;
height = element[0].clientHeight;
radius = Math.min (width, height) / 2;
pie = d3.layout.pie ()
.value (function (d) {return d.value;})
.sort (null);
arc = d3.svg.arc ()
.outerRadius (radius - 20)
.innerRadius (radius - 80);
svg = d3.select (element[0])
.append ("svg")
.attr ({width : width, height : height})
.append ("g")
.attr ("transform", "translate(" + width * 0.5 + "," + height * 0.5 + ")");
path = svg.datum (scope.data)
.selectAll ("path")
.data (pie)
.enter ()
.append ("path")
.attr ({
fill : function (d, i) {return scope.data [i].color;},
d : arc
});
scope.$watch (
"data",
function () {
pie.value (function (d) {return d.value;});
path = path.data(pie);
path.attr("d", arc);
},
true
);
}
};
})
i have used this https://embed.plnkr.co/plunk/jDvdSh as reference . All i want to implement is on search i want perform the service call and then manipulate the response and render it as a pie chart.or someone please explain how the pie chart directive is called in the above plnkr reference that would be more helpful

Dots persist on D3 graph for angularjs

I am using NVD3 for my graphs and I have this issue where the dots that show up on hover will start to persist as you over over the line. Does anyone have any idea on how to make sure these disappear when the move moves away from them?
Here is the component:
;(function() {
angular.module('canopy.common.components.largeStandardChart')
.component('largeStandardChart', {
templateUrl: 'app/common/components/chart-components/large-standard-chart/large-standard-chart.html',
controller: LargeStandardChartController,
controllerAs: 'vm',
bindings: {
kpi: "<",
updateGraph: '=',
frequency: '<'
}
});
LargeStandardChartController.$inject = ['$rootScope', 'BanyanUtilsService', 'ConfigurationService', '$timeout'];
function LargeStandardChartController($rootScope, UtilsService, CS, $timeout) {
var vm = this;
vm.kpiTrend = [];
vm.kpiTargetTrend = [];
vm.kpiProjectedTrend = [];
vm.predictedDate = null;
var allTrends = vm.kpi.trend.length && vm.kpi.trend[0].values.length ? vm.kpi.trend[0].values : [];
vm.chart = {
chartOptions: {
chart: {
type: 'lineChart',
height: 250,
area: CS.getOrgConfig().graph.general.fillArea,
margin : {
top: 15,
right: 40,
bottom: 50,
left: 70
},
x: (function(d) { return d.time }),
y: (function(d) { return d.value }),
clipVoronoi: false,
xAxis: {
showMaxMin: false,
staggerLabels: vm.frequency === 'DAY' ? false : true,
tickFormat: function(d) {
return vm.frequency === 'DAY'
? d3.time.format(CS.getOrgConfig().dateTime.d3DateFormat)(new Date(d))
: d3.time.format(CS.getOrgConfig().dateTime.d3DateTimeFormat)(new Date(d));
}
},
yAxis: {
showMaxMin: true,
tickFormat: function (d) {
return vm.kpi.kpiMeasure === 'NUMBER' && d ? d.toFixed(1) : UtilsService.getFormattedData(d, vm.kpi.kpiMeasure);
}
},
tooltip: {
hideDelay: 0
},
showXAxis: CS.getOrgConfig().graph.xAxis.showXAxis,
showYAxis: CS.getOrgConfig().graph.yAxis.showYAxis,
showLegend: false,
transitionDuration: 350,
useInteractiveGuideline: false
}
}
};
vm.$onInit = function() {
if(vm.updateGraph) { vm.updateGraph.handler = vm.updateGraphData; }
if (!vm.kpi) { vm.kpi = { trend: vm.kpiTrend, kpiMeasure: "PERCENTAGE" } }
setTrends();
d3.select(window).on('mouseout', function () {
d3.selectAll('.nvtooltip').style('opacity', '0');
});
};
function setTrends() {
_.set(vm.chart, 'chartData', []);
vm.kpiTrend = [];
vm.kpiProjectedTrend = [];
_.forEach(allTrends, function(kpi) {
if (_.has(kpi, 'predict')) {
vm.kpiProjectedTrend.push(kpi);
} else {
if (CS.getOrgConfig().graph.general.showNullValues) {
vm.kpiTrend.push(kpi);
} else {
if (kpi.value) { vm.kpiTrend.push(kpi) }
}
}
});
if (!vm.kpi.hideTarget && !vm.kpiProjectedTrend.length) {
vm.chart.chartData.push({
key: CS.getOrgConfig().labels.target.single,
classed: "dashed",
color: $rootScope.branding.canopyBrandColor,
seriesIndex: 2,
strokeWidth: 1,
values: getTargetValues()
});
}
if (vm.kpiTrend.length) {
vm.chart.chartData.push({
key: 'Value',
classed: "solid",
area: CS.getOrgConfig().graph.general.fillArea,
color: $rootScope.branding.canopyBrandColor,
seriesIndex: 0,
strokeWidth: 2,
values: vm.kpiTrend
});
}
if (vm.kpiProjectedTrend.length) {
vm.chart.chartOptions.chart.useInteractiveGuideline = false;
var lastCurrentValue = angular.copy(vm.kpiTrend).pop();
var firstPredictedValue = angular.copy(vm.kpiTrend).pop();
vm.kpiProjectedTrend.unshift(firstPredictedValue);
vm.endDate = moment.unix(allTrends[ allTrends.length - 1 ].time / 1000).format(CS.getOrgConfig().dateTime.dateFormat); // Divide by 1000 for miliseconds coming from server
vm.chart.chartData.push({
key:'Projected',
classed: "dashed",
color: $rootScope.branding.canopyBrandColor,
strokeWidth: 1,
seriesIndex: 3,
values: vm.kpiProjectedTrend
});
var top = 0, bottom = 0;
if (allTrends.length) {
var top = _.maxBy(allTrends, function(tr) { return tr.value }).value;
var bottom = _.minBy(allTrends, function(tr) { return tr.value }).value;
}
var yTop = vm.kpi.kpiMeasure === 'PERCENTAGE' ? 103 : top + ((top - bottom) * 0.07);
var yBottom = vm.kpi.kpiMeasure === 'PERCENTAGE' ? 0 : bottom - ((top - bottom) * 0.04);
vm.chart.chartData.push({
classed: "solid",
strokeWidth: 1,
seriesIndex: 4,
values: [
{time: lastCurrentValue.time, value: yTop},
{time: lastCurrentValue.time, value: yBottom},
],
color: '#ff0005'
});
}
setDomain();
}
function setDomain () {
var top = 0, bottom = 0;
if (allTrends.length) {
top = _.maxBy(allTrends, function(tr) { return tr.value }).value;
bottom = _.minBy(allTrends, function(tr) { return tr.value }).value;
}
bottom = bottom < 1 && bottom > 0 ? 0 : bottom;
if (top === bottom) { bottom = top - bottom; }
if (top + bottom === 0) { top = 1; }
var yTop = vm.kpi.kpiMeasure === 'PERCENTAGE' ? 103 : top + ((top - bottom) * 0.05);
var yBottom = vm.kpi.kpiMeasure === 'PERCENTAGE' ? 0 : bottom - ((top - bottom) * 0.05);
vm.chart.chartOptions.chart.yDomain = [yBottom, yTop];
}
vm.updateGraphData = function(trend) {
allTrends = trend.length && trend[0].values.length ? trend[0].values : [];
setTrends();
vm.api.updateWithOptions(vm.chart.chartOptions);
vm.api.updateWithData(trend);
vm.api.refresh();
};
function getTargetValues() {
var trend = angular.copy(allTrends);
_.forEach(trend, function(t) {
t.value = vm.kpi.targetValue;
});
return trend;
}
}
})();
and here is what it looks like when I hover:
For anyone having this issue I have finally found the solution. I had to add a listener on the mouseout event and remove the hover class that is added to the .nv-point which is the dot. It looks like this:
d3.select(window).on('mouseout', function () {
d3.selectAll('.nv-point').classed('hover', false);
});

Recreating collapsible force layout using d3 v4

I've been trying to create a Collapsible force layout using d3js v4, similar to this one: https://mbostock.github.io/d3/talk/20111116/force-collapsible.html
I've been able to create the layout itself. But not able to update it. Can anyone help?
Here's my js code:
var width = 960,
height = 600;
var root = {
"name": "server1900",
"children": [{
"name": "server913",
"_children": null,
"children": [{
"name": "server948"
}, {
"name": "server946"
}]
}, {
"name": "server912",
"_children": null,
"children": [{
"name": "server984"
}, {
"name": "server983"
}]
}, {
"name": "server911",
"_children": null,
"children": [{
"name": "server999",
"_children": null,
"children": [{
"name": "server992"
}]
}]
}]
};
root = d3.hierarchy(root);
var i = 0;
var transform = d3.zoomIdentity;;
var nodeSvg, linkSvg, simulation, nodeEnter, linkEnter ;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.call(d3.zoom().scaleExtent([1 / 2, 8]).on("zoom", zoomed))
.append("g")
.attr("transform", "translate(40,0)");
function zoomed() {
svg.attr("transform", d3.event.transform);
}
simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(function(d) { return d.id; }))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(width / 2, height / 2))
.on("tick", ticked);
update();
function update() {
var nodes = flatten(root);
var links = root.links();
simulation
.nodes(nodes)
simulation.force("link")
.links(links);
linkSvg = svg.selectAll(".link")
.data(links, function(d) { return d.target.id; })
linkSvg.exit().remove();
linkSvg = linkSvg.enter()
.append("line")
.attr("class", "link");
nodeSvg = svg.selectAll(".node")
.data(nodes, function(d) { return d.id; })
nodeSvg.exit().remove();
nodeSvg = nodeSvg.enter()
.append("g")
.attr("class", "node")
.on("click", click)
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended))
nodeSvg.append("circle")
.attr("r", 4 )
.append("title")
.text(function(d) { return d.data.name; })
nodeSvg.append("text")
.attr("dy", 3)
.attr("x", function(d) { return d.children ? -8 : 8; })
.style("text-anchor", function(d) { return d.children ? "end" : "start"; })
.text(function(d) { return d.data.name; });
}
function ticked() {
linkSvg
.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
nodeSvg
.attr("transform", function(d) { return "translate(" + d.x + ", " + d.y + ")"; });
}
function click(d) {
if (d.children) {
d._children = d.children;
d.children = null;
update();
simulation.restart();
} else {
d.children = d._children;
d._children = null;
update();
simulation.restart();
}
}
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart()
simulation.fix(d);
}
function dragged(d) {
simulation.fix(d, d3.event.x, d3.event.y);
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
simulation.unfix(d);
}
function flatten (root) {
// hierarchical data to flat data for force layout
var nodes = [];
function recurse(node) {
if (node.children) node.children.forEach(recurse);
if (!node.id) node.id = ++i;
else ++i;
nodes.push(node);
}
recurse(root);
return nodes;
}
line {
stroke: #666;
}
.node {
pointer-events: all;
}
circle {
stroke: none;
stroke-width: 40px;
}
.node text {
font: 8px sans-serif;
}
<script src="https://d3js.org/d3.v4.0.0-alpha.50.min.js"></script>
Here's my fiddle. https://jsfiddle.net/t4vzg650/4/
Thanks
I forgot to merge old nodes after enter().
link = svg.selectAll(".link").data(links, function(d) { return d.target.id; })
var linkEnter = link.enter().append("line").attr("class", "link");
link = linkEnter.merge(link);
Thanks to Mike Bostock for helping me with this problem. I thought there was an issue with d3 v4, turns out I didn't read changes fully :|
Refer this for more info: https://github.com/d3/d3-force/issues/37
Fixed fiddle: https://jsfiddle.net/t4vzg650/6/

angular-google-maps not showing infowindow on mouseover event

I am using angularjs-google-map http://angular-ui.github.io/angular-google-maps/#!/api
I can add multiple markers with showing infoWindow by cliking on a marker, but now I need to show the marker infoWindow when the mouse enters the area of the marker icon and hide it when the mouse leaves the area of the marker icon instead of using the click event.
You can look on this example on Jsfiddle https://jsfiddle.net/meher12/bgb36q7b/ to get idea about my purpose !
My HTML code:
<ui-gmap-google-map center="map.center" zoom="map.zoom" dragging="map.dragging" bounds="map.bounds"
events="map.events" options="map.options" pan="true" control="map.control">
<ui-gmap-markers models="map.randomMarkers" coords="'self'" icon="'icon'"
doCluster="map.doClusterRandomMarkers" clusterOptions="map.clusterOptions" modelsbyref="true"
events="map.markersEvents" options="'options'"
>
<ui-gmap-windows show="'showWindow'" ng-cloak>
<div>
<p>This is an info window</p>
</div>
</ui-gmap-windows>
</ui-gmap-markers>
</ui-gmap-google-map>
</div>
My JS code:
myApp.controller('MainController', function ($scope,uiGmapGoogleMapApi) {
$scope.numOfMarkers = 25;
uiGmapGoogleMapApi.then(function(maps) { $scope.googleVersion = maps.version; });
$scope.map = {
center: {
latitude: 45,
longitude: -73
},
zoom: 10,
options: {
streetViewControl: false,
panControl: false,
maxZoom: 20,
minZoom: 3
},
dragging: false,
bounds: {},
randomMarkers: [],
doClusterRandomMarkers: true,
currentClusterType: 'standard',
clusterOptions: {
title: 'Hi I am a Cluster!', gridSize: 60, ignoreHidden: true, minimumClusterSize: 2
}
};
$scope.map.markersEvents = {
mouseover: function (marker, eventName, model, args) {
model.options.labelContent = "Position - lat: " + model.latitude + " lon: " + model.longitude;
marker.showWindow = true;
$scope.$apply();
},
mouseout: function (marker, eventName, model, args) {
model.options.labelContent = " ";
marker.showWindow = false;
$scope.$apply();
}
};
var genRandomMarkers = function (numberOfMarkers, scope) {
var markers = [];
for (var i = 0; i < numberOfMarkers; i++) {
markers.push(createRandomMarker(i, scope.map.bounds))
}
scope.map.randomMarkers = markers;
};
var createRandomMarker = function (i, bounds, idKey) {
var lat_min = bounds.southwest.latitude,
lat_range = bounds.northeast.latitude - lat_min,
lng_min = bounds.southwest.longitude,
lng_range = bounds.northeast.longitude - lng_min;
if (idKey == null)
idKey = "id";
var latitude = lat_min + (Math.random() * lat_range);
var longitude = lng_min + (Math.random() * lng_range);
var ret = {
latitude: latitude,
longitude: longitude,
title: 'm' + i,
showWindow: false,
options: {
labelContent: ' ',
labelAnchor: "22 0",
labelClass: "marker-labels",
draggable: true
}
};
ret[idKey] = i;
return ret;
};
$scope.genRandomMarkers = function (numberOfMarkers) {
genRandomMarkers(numberOfMarkers, $scope);
};
$scope.removeMarkers = function () {
$scope.map.randomMarkers = [];
};
});
Like you see on my JS code I have created markerEvents and I can get the marker label changed on mouse events but still not showing the infoWindow attached to each marker on the map when the mouse Event is fired, despite its value is changing and take the correct value.
Someone Have an idea to resolve this issue ?
Feel free to put your changes to my Jsfiddle code :)
You must set model.showWindow instead of marker.showWindow
You can set model.show = true instead of model.showWindow, in html remove show =showWindow.

How to draw a d3.js line chart using angularjs directives

How to use angular directives to load the d3.js graph using scope json data instead of using graph.html file.I had referred this urlurl.But unable to do it for line chart.
Can anyone please help me out regarding this issue ...
My graph.html:
function getDate(d) {
var dt = new Date(d.date);
dt.setHours(0);
dt.setMinutes(0);
dt.setSeconds(0);
dt.setMilliseconds(0);
return dt;
}
function showData(obj, d) {
var coord = d3.mouse(obj);
var infobox = d3.select(".infobox");
// now we just position the infobox roughly where our mouse is
infobox.style("left", (coord[0] + 100) + "px" );
infobox.style("top", (coord[1] - 175) + "px");
$(".infobox").html(d);
$(".infobox").show();
}
function hideData() {
$(".infobox").hide();
}
var drawChart = function(data) {
// define dimensions of graph
var m = [10, 20, 10, 50]; // margins
var w = 250 - m[1] - m[3]; // width
var h = 100 - m[0] - m[2]; // height
data.sort(function(a, b) {
var d1 = getDate(a);
var d2 = getDate(b);
if (d1 == d2) return 0;
if (d1 > d2) return 1;
return -1;
});
var minDate = getDate(data[0]),
maxDate = getDate(data[data.length-1]);
var x = d3.time.scale().domain([minDate, maxDate]).range([0, w]);
var y = d3.scale.linear().domain([0, d3.max(data, function(d) { return d.trendingValue; } )]).range([h, 0]);
var line = d3.svg.line()
.x(function(d, i) {
return x(getDate(d)); //x(i);
})
.y(function(d) {
return y(d.trendingValue);
});
function xx(e) { return x(getDate(e)); };
function yy(e) { return y(e.trendingValue); };
var graph = d3.select("#chart").append("svg:svg")
.attr("width", w + m[1] + m[3])
.attr("height", h + m[0] + m[2])
.append("svg:g")
.attr("transform", "translate(" + m[3] + "," + m[0] + ")");
var xAxis = d3.svg.axis().scale(x).ticks(d3.time.months, 1).tickSize(-h).tickSubdivide(true);
var yAxisLeft = d3.svg.axis().scale(y).ticks(10).orient("left"); //.tickFormat(formalLabel);
graph
.selectAll("circle")
.data(data)
.enter().append("circle")
.attr("fill", "steelblue")
.attr("r", 5)
.attr("cx", xx)
.attr("cy", yy)
.on("mouseover", function(d) { showData(this, d.trendingValue);})
.on("mouseout", function(){ hideData();});
graph.append("svg:path").attr("d", line(data));
$("#chart").append("<div class='infobox' style='display:none;'>Test</div>");
}
My directive:(which I had tried but unable to draw a graph)
angular.module( 'chart').directive( 'crD3Bars', [
function () {
return {
restrict: 'E',
scope: {
data: '='
},
link: function (scope, element) {
function getDate(d) {
var dt = new Date(d.date);
dt.setHours(0);
dt.setMinutes(0);
dt.setSeconds(0);
dt.setMilliseconds(0);
return dt;
}
function showData(obj, d) {
var coord = d3.mouse(obj);
var infobox = d3.select(".infobox");
// now we just position the infobox roughly where our mouse is
infobox.style("left", (coord[0] + 100) + "px" );
infobox.style("top", (coord[1] - 175) + "px");
$(".infobox").html(d);
$(".infobox").show();
}
function hideData() {
$(".infobox").hide();
}
var drawChart = function(data) {
// define dimensions of graph
var m = [10, 20, 10, 50]; // margins
var w = 250 - m[1] - m[3]; // width
var h = 100 - m[0] - m[2]; // height
data.sort(function(a, b) {
var d1 = getDate(a);
var d2 = getDate(b);
if (d1 == d2) return 0;
if (d1 > d2) return 1;
return -1;
});
var minDate = getDate(data[0]),
maxDate = getDate(data[data.length-1]);
var x = d3.time.scale().domain([minDate, maxDate]).range([0, w]);
var y = d3.scale.linear().domain([0, d3.max(data, function(d) { return d.trendingValue; } )]).range([h, 0]);
var line = d3.svg.line()
.x(function(d, i) {
return x(getDate(d)); //x(i);
})
.y(function(d) {
return y(d.trendingValue);
});
function xx(e) { return x(getDate(e)); };
function yy(e) { return y(e.trendingValue); };
var graph = d3.select("#chart").append("svg:svg")
.attr("width", w + m[1] + m[3])
.attr("height", h + m[0] + m[2])
.append("svg:g")
.attr("transform", "translate(" + m[3] + "," + m[0] + ")");
var xAxis = d3.svg.axis().scale(x).ticks(d3.time.months, 1).tickSize(-h).tickSubdivide(true);
var yAxisLeft = d3.svg.axis().scale(y).ticks(10).orient("left"); //.tickFormat(formalLabel);
graph
.selectAll("circle")
.data(data)
.enter().append("circle")
.attr("fill", "steelblue")
.attr("r", 5)
.attr("cx", xx)
.attr("cy", yy)
.on("mouseover", function(d) { showData(this, d.trendingValue);})
.on("mouseout", function(){ hideData();});
graph.append("svg:path").attr("d", line(data));
$("#graphDiv3").append("<div class='infobox' style='display:none;'>Test</div>");
}
drawchart(data);
}
};
}
]);
Instead of mashing up two blocks of code and hoping it works, I'd recommend you follow some simple angular tutorials to get a better grasp of the basics. Also, some simple debugging would have gone a long way here.
You do not declare your module.
You do not seem to pass in your data anywhere (like in a controller which also doesn't exist).
The function is drawChart, you are calling drawchart
In your directive, you select a div with id of chart, this doesn't exist. Since it's a directive and they act on elements use d3.select(element[0])
All that said once you work through these relatively simple mistakes, you get some working code:
var myAppModule = angular.module('chart', []);
angular.module('chart').controller('chartCtrl', function ($scope) {
$scope.myData = [{
"date": "2015-10-01",
"trendingValue": "244"
},
{
"date": "2015-07-01",
"trendingValue": "0"
},
{
"date": "2015-06-01",
"trendingValue": "117"
},
{
"date": "2015-05-01",
"trendingValue": "5353"
},
{
"date": "2015-04-01",
"trendingValue": "11159"
},
{
"date": "2015-03-01",
"trendingValue": "7511"
},
{
"date": "2015-02-01",
"trendingValue": "6906"
},
{
"date": "2015-01-01",
"trendingValue": "10816"
},
{
"date": "2014-12-01",
"trendingValue": "3481"
},
{
"date": "2014-11-01",
"trendingValue": "1619"
},
{
"date": "2014-10-01",
"trendingValue": "4084"
},
{
"date": "2014-09-01",
"trendingValue": "1114"
}];
});
angular.module('chart').directive('crD3Bars', [
function() {
return {
restrict: 'E',
scope: {
data: '='
},
link: function(scope, element) {
function getDate(d) {
var dt = new Date(d.date);
dt.setHours(0);
dt.setMinutes(0);
dt.setSeconds(0);
dt.setMilliseconds(0);
return dt;
}
function showData(obj, d) {
var coord = d3.mouse(obj);
var infobox = d3.select(".infobox");
// now we just position the infobox roughly where our mouse is
infobox.style("left", (coord[0] + 100) + "px");
infobox.style("top", (coord[1] - 175) + "px");
$(".infobox").html(d);
$(".infobox").show();
}
function hideData() {
$(".infobox").hide();
}
var drawChart = function(data) {
// define dimensions of graph
var m = [10, 20, 10, 50]; // margins
var w = 250 - m[1] - m[3]; // width
var h = 100 - m[0] - m[2]; // height
data.sort(function(a, b) {
var d1 = getDate(a);
var d2 = getDate(b);
if (d1 == d2) return 0;
if (d1 > d2) return 1;
return -1;
});
var minDate = getDate(data[0]),
maxDate = getDate(data[data.length - 1]);
var x = d3.time.scale().domain([minDate, maxDate]).range([0, w]);
var y = d3.scale.linear().domain([0, d3.max(data, function(d) {
return d.trendingValue;
})]).range([h, 0]);
var line = d3.svg.line()
.x(function(d, i) {
return x(getDate(d)); //x(i);
})
.y(function(d) {
return y(d.trendingValue);
});
function xx(e) {
return x(getDate(e));
}
function yy(e) {
return y(e.trendingValue);
}
var graph = d3.select(element[0]).append("svg:svg")
.attr("width", w + m[1] + m[3])
.attr("height", h + m[0] + m[2])
.append("svg:g")
.attr("transform", "translate(" + m[3] + "," + m[0] + ")");
var xAxis = d3.svg.axis().scale(x).ticks(d3.time.months, 1).tickSize(-h).tickSubdivide(true);
var yAxisLeft = d3.svg.axis().scale(y).ticks(10).orient("left"); //.tickFormat(formalLabel);
graph
.selectAll("circle")
.data(data)
.enter().append("circle")
.attr("fill", "steelblue")
.attr("r", 5)
.attr("cx", xx)
.attr("cy", yy)
.on("mouseover", function(d) {
showData(this, d.trendingValue);
})
.on("mouseout", function() {
hideData();
});
graph.append("svg:path").attr("d", line(data));
$("#graphDiv3").append("<div class='infobox' style='display:none;'>Test</div>");
};
drawChart(scope.data);
}
};
}
]);
<!DOCTYPE html>
<html ng-app="chart">
<head>
<script data-require="angular.js#1.4.8" data-semver="1.4.8" src="https://code.angularjs.org/1.4.8/angular.js"></script>
<script data-require="d3#3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
<script data-require="jquery#2.1.4" data-semver="2.1.4" src="https://code.jquery.com/jquery-2.1.4.js"></script>
<script src="script.js"></script>
</head>
<body>
<div id="graphDiv3" ng-controller="chartCtrl">
<cr-d3-bars data="myData"></cr-d3-bars>
</div>
</body>
</html>

Resources