(function () { 'use strict'; angular.module('badge-chart', []) .directive('badgeChart', ['$document', function ($document) { return { restrict : 'A', scope : false, link : function (scope, element, attr) { var container = element[0]; // console.log($(container).width()+'px') $(container).css({ 'height' : $(container).width() + 'px' }) var width = !container ? 240 : $(container).width(); var height= !container ? 240 : $(container).height(); var artistid = scope.artist.artistid; // console.log(attr.badgeContext, attr.badgeProgress, scope.artist) scope.$watch('artist', function (a) { if (a) { CreateArtistBadgesChart(container, attr.badgeContext, attr.badgeProgress) } }) function CreateArtistBadgesChart (container, badgesContext, userProgress) { //console.log('badge chart', container, badgesContext, userProgress, artistid) // userProgress = 20; // badgesContext = 'Overdubs received'; var dataset; var level1label,level2label,level3label; var level1count, level2count, level3count; var songtreeGreen = '#14a29d'; var badgesActive = true; var remainingContainer; if (badgesContext == 'Overdubs') { level1label = 'Performer'; level2label = 'Top performer'; level3label = 'Virtuoso'; level1count = 10; level2count = 40; level3count = 200; // remainingContainer = '#profile_next_badge_overdubs'+artistid+''; } if (badgesContext == 'newsongs') { level1label = 'Rookie'; level2label = 'Songwriter'; level3label = 'Composer'; level1count = 20; level2count = 50; level3count = 320; // remainingContainer = '#profile_next_badge_newsongs'+artistid+''; } if (badgesContext == 'overdubsreceived') { level1label = 'Songsmith'; level2label = 'Band leader'; level3label = 'Maestro'; level1count = 5; level2count = 30; level3count = 200; // remainingContainer = '#profile_next_badge_overdubsreceived'+artistid+''; } var level1 = level1count; var level2 = level2count - level1count; var level3 = level3count - level2count; dataset = [ { level: 1, label: level1label, count: level1, raw: level1count }, { level: 2, label: level2label, count: level2, raw: level2count }, { level: 3, label: level3label, count: level3, raw: level3count }, ]; var nextBadgeToWin; var missingToNextBadge; if (userProgress < level1count) { nextBadgeToWin = level1label; missingToNextBadge = level1count - userProgress; } if (userProgress >= level1count && userProgress < level2count ) { nextBadgeToWin = level2label; missingToNextBadge = level2count - userProgress; } if (userProgress >= level2count) { nextBadgeToWin = level3label; missingToNextBadge = level3count - userProgress; } scope.nextLevelMsg = ''+missingToNextBadge+' more to '+nextBadgeToWin+''; scope.endMsg = 'You Rock!'; var total = level1+level2+level3; var userProgressArc = userProgress; $(remainingContainer).empty(); //this is needed for updating the chart on resizing window if (userProgress > total) { userProgressArc = total; scope.showEndMsg = true; //$(remainingContainer).append(endMsg) } else { scope.showNextLevelMsg = true; //$(remainingContainer).append(nextLevelMsg) } var progressDataSet = [ {label: 'User', count: userProgressArc}, {label: 'Total', count: total - userProgressArc} ] var margin = 7; //console.log('your progres, ', userProgress, 'next badge to win:', nextBadgeToWin, "missing to next badge:", missingToNextBadge); var radius = Math.min(width, height) / 2 - margin; var idString = badgesContext.toLowerCase().replace(/ /g, "_"); var labelr = radius + 30; var donutWidth = 30; //var color = d3.scale.category20b(); var svg = d3.select(container) .append('svg') .attr('id', function () { return 'artist_badges_chart_'+badgesContext+'_'+artistid+''; }) .attr('class', 'artist_badges_chart') .attr('width', width+5) .attr('height', height+5) .append('g') .attr('transform', 'translate(' + ((width+5) / 2) + ',' + ((height+5) / 2) + ')'); var centerLabel = svg.append('text') .attr('text-anchor', 'middle') .text(userProgress) .attr('fill', songtreeGreen) .attr('id', function () { return idString + "_count" + artistid; }) .style('font-size', '20px') .style('font-weight', 'bold') .attr('y', '7px') var svg2 = svg.append('g'); var arc = d3.svg.arc() .innerRadius(radius - donutWidth + 10) .outerRadius(radius); var arc2inner = radius+3; var arc2outer = radius + 10; if (!badgesActive) { arc2inner = radius; } var arc2 = d3.svg.arc() .innerRadius(arc2inner) .outerRadius(arc2outer); var tooltip = d3.select("body") .append("div") .attr("class", "tooltip") .attr("id", function () { 'chart_tooltip_'+badgesContext+'_'+artistid+''; }) .style("position", "fixed") .style("background", "black") .style("color", "white") .style('padding', '5px') .style('border-radius', '5px') var degree = Math.PI/180; var pie = d3.layout.pie() .startAngle(-150*degree).endAngle(150*degree) .value(function(d) { return d.count; }) .sort(null) var path = svg.selectAll('path') .data(pie(dataset)) .enter() .append('path') .attr('d', arc) .style('display', function(){ if (!badgesActive) { return 'none'; } }) .attr('fill', function(d, i) { if (!badgesActive) { return 'transparent'; } if (d.data.level == 1) { return "#2B2C2F"; } if (d.data.level == 2) { return "#3F4044"; } if (d.data.level == 3) { return "#4E5056"; } }) .on("mousemove",function(d){ var mouseVal = d3.mouse(this); d3.select(this).transition().duration(300).attr('fill', songtreeGreen); tooltip.style("display","none"); tooltip .html(d.data.raw + " " + badgesContext + " - Complete this stage to become a " + d.data.label ) .style("left", (d3.event.pageX) + "px") .style("top", (d3.event.pageY) - $document.scrollTop() + "px") .style("opacity", 1) .style("display","block"); }) .on("mouseout",function(){ tooltip.html(" ").style("display","none"); d3.select(this).transition().duration(200).attr('fill', function(d) { if (d.data.level == 1) { return "#2B2C2F"; } if (d.data.level == 2) { return "#3F4044"; } if (d.data.level == 3) { return "#4E5056"; } }) }) var path2 = svg2.selectAll('path') .data(pie(progressDataSet)) .enter() .append('path') .attr('d', arc2) .attr('fill', function (d, i) { if (d.data.label == 'User') { return songtreeGreen; } else { return '#282A2B'; } }) .transition().duration(1500) .attrTween('d', function(d) { if (d.data.label == 'User') { var i = d3.interpolate(d.startAngle+0.1, d.endAngle); return function(t) { d.endAngle = i(t); return arc2(d); } } else { return; } }); //animate and display numeric value note: displaying at every step and at end of anim $({countNum: 0}).animate({countNum: userProgress}, { duration: 1500, easing:'linear', step: function() { // $('#'+idString+'_count'+artistid+'').text(Math.floor(this.countNum)); }, complete: function() { //$('#'+idString+'_count'+artistid+'').text(this.countNum); } }); } } } //angular.forEach(data.songs, function(go, key) { // console.log(go,key) //}); }]) .directive('rankGraph', ['$document', '$state', function ($document, $state) { return { restrict : 'E', template: '
', scope: { data: '=' }, link: function (scope, element, attrs) { scope.$watch('data', function (d, od) { if (d) { DrawGraph(); } }) function DrawGraph() { var container = element.children()[0]; var data = []; angular.forEach(scope.data, function (k, v) { console.log('each data', k, v) data.unshift({ genre: v, rank: k }) }) /* data = [ {'Rock': 3}, {'Pop': 5}, {'Ambient': 10}, {'Electronic': 52}, {'Metal': 1}, {'Rap': 84}, {'Other': 99}, {'Overall': 5} */ //var div = d3.select(container).append("div").attr("class", "toolTip"); console.log('will draw rank graph', data) var axisMargin = 20, margin = 50, valueMargin = 4, width = $(container).width(), barHeight = 20,//(height-axisMargin-margin*2)* 0.5/data.length, barPadding = 5, height=(barHeight+barPadding)*data.length + margin, bar, svg, scale, xAxis, labelWidth = 0; max = 1 //d3.max(data, function(d) { return d.rank; }); svg = d3.select(container) .append("svg") .attr("width", width) .attr("height", height); bar = svg.selectAll("g") .data(data) .enter() .append("g"); bar.attr("class", "bar") .attr("cx",0) .attr("transform", function(d, i) { return "translate(" + margin + "," + (i * (barHeight + barPadding) + barPadding) + ")"; }) .on('click', function (d) { $state.transitionTo('songs.topartists', {genre: d.genre}) }) bar.append("text") .attr("class", "label") .attr("y", barHeight / 2) .attr("dx", "-4px") .attr("dy", ".35em") //vertical align middle .text(function(d){ return d.genre }).each(function() { labelWidth = Math.ceil(Math.max(labelWidth, this.getBBox().width)); }); scale = d3.scale.linear() .domain([100, 1]) .range([0, width - margin*2 - labelWidth]); xAxis = d3.svg.axis() .scale(scale) .tickSize(-height + 2*margin + axisMargin) .orient("bottom"); bar.append("rect") .attr("transform", "translate("+labelWidth+", 0)") .attr("height", barHeight) .attr("width", function (d) { return scale(d.rank); // console.log( d, Object.values(d), scale(d.rank), 'scale') }) .style('fill', function (d) { console.log('BAR D', d) return '#14a29d'; }) .style('opacity', function (d) { console.log('BAR D', d) if (d.rank <= 3) {return 1} else { var factor = d.rank/100; factor = factor.toFixed(2); var alph = 1 - ( factor ); if (alph < .3) {alph=.3} //console.log('alpha for ', d.genre, ': ', alph) return alph; } }) .on('mouseover', function () { d3.select(this).transition().duration(200).style('fill', 'rgb(21, 168, 163)'); }) .on('mouseleave', function () { d3.select(this).transition().duration(200).style('fill', '#14a29d'); }) bar.append("text") .attr("class", "value") .attr("y", barHeight / 2) .attr("dx", -valueMargin + labelWidth) //margin right .attr("dy", ".35em") //vertical align middle .attr("text-anchor", "end") .text(function(d){ return d.genre + ' chart position: ' + d.rank; }) .attr("x", function(d){ var width = this.getBBox().width; return Math.max(width + valueMargin, scale(d.rank)); }) .style('font-size', '12px') .style('font-weight', 'bold') /* bar .on("mousemove", function(d){ div.style("left", d3.event.pageX+10+"px"); div.style("top", d3.event.pageY-25+"px"); div.style("display", "inline-block"); div.html((d.genre)+"