/*////////////////////////////////////////////////////////// ////////////////// Set up the Data ///////////////////////// //////////////////////////////////////////////////////////*/ var NameProvider = ["Apple","HTC","Huawei","LG","Nokia","Samsung","Sony","Other"]; var matrix = [ [9.6899,0.8859,0.0554,0.443,2.5471,2.4363,0.5537,2.5471], /*Apple 19.1584*/ [0.1107,1.8272,0,0.4983,1.1074,1.052,0.2215,0.4983], /*HTC 5.3154*/ [0.0554,0.2769,0.2215,0.2215,0.3876,0.8306,0.0554,0.3322], /*Huawei 2.3811*/ [0.0554,0.1107,0.0554,1.2182,1.1628,0.6645,0.4983,1.052], /*LG 4.8173*/ [0.2215,0.443,0,0.2769,10.4097,1.2182,0.4983,2.8239], /*Nokia 15.8915*/ [1.1628,2.6024,0,1.3843,8.7486,16.8328,1.7165,5.5925], /*Samsung 38.0399*/ [0.0554,0.4983,0,0.3322,0.443,0.8859,1.7719,0.443], /*Sony 4.4297*/ [0.2215,0.7198,0,0.3322,1.6611,1.495,0.1107,5.4264] /*Other 9.9667*/ ]; /*Sums up to exactly 100*/ var colors = ["#C4C4C4","#69B40F","#EC1D25","#C8125C","#008FC8","#10218B","#134B24","#737373"]; /*Initiate the color scale*/ var fill = d3.scale.ordinal() .domain(d3.range(NameProvider.length)) .range(colors); /*////////////////////////////////////////////////////////// /////////////// Initiate Chord Diagram ///////////////////// //////////////////////////////////////////////////////////*/ var margin = {top: 30, right: 25, bottom: 20, left: 25}, width = 650 - margin.left - margin.right, height = 600 - margin.top - margin.bottom, innerRadius = Math.min(width, height) * .39, outerRadius = innerRadius * 1.04; /*Initiate the SVG*/ var svg = d3.select("#chart").append("svg:svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("svg:g") .attr("transform", "translate(" + (margin.left + width/2) + "," + (margin.top + height/2) + ")"); var chord = d3.layout.chord() .padding(.04) .sortSubgroups(d3.descending) /*sort the chords inside an arc from high to low*/ .sortChords(d3.descending) /*which chord should be shown on top when chords cross. Now the biggest chord is at the bottom*/ .matrix(matrix); /*////////////////////////////////////////////////////////// ////////////////// Draw outer Arcs ///////////////////////// //////////////////////////////////////////////////////////*/ var arc = d3.svg.arc() .innerRadius(innerRadius) .outerRadius(outerRadius); var g = svg.selectAll("g.group") .data(chord.groups) .enter().append("svg:g") .attr("class", function(d) {return "group " + NameProvider[d.index];}); g.append("svg:path") .attr("class", "arc") .style("stroke", function(d) { return fill(d.index); }) .style("fill", function(d) { return fill(d.index); }) .attr("d", arc) .style("opacity", 0) .transition().duration(1000) .style("opacity", 0.4); /*////////////////////////////////////////////////////////// ////////////////// Initiate Ticks ////////////////////////// //////////////////////////////////////////////////////////*/ var ticks = svg.selectAll("g.group").append("svg:g") .attr("class", function(d) {return "ticks " + NameProvider[d.index];}) .selectAll("g.ticks") .attr("class", "ticks") .data(groupTicks) .enter().append("svg:g") .attr("transform", function(d) { return "rotate(" + (d.angle * 180 / Math.PI - 90) + ")" + "translate(" + outerRadius+40 + ",0)"; }); /*Append the tick around the arcs*/ ticks.append("svg:line") .attr("x1", 1) .attr("y1", 0) .attr("x2", 5) .attr("y2", 0) .attr("class", "ticks") .style("stroke", "#FFF"); /*Add the labels for the %'s*/ ticks.append("svg:text") .attr("x", 8) .attr("dy", ".35em") .attr("class", "tickLabels") .attr("transform", function(d) { return d.angle > Math.PI ? "rotate(180)translate(-16)" : null; }) .style("text-anchor", function(d) { return d.angle > Math.PI ? "end" : null; }) .text(function(d) { return d.label; }) .attr('opacity', 0); /*////////////////////////////////////////////////////////// ////////////////// Initiate Names ////////////////////////// //////////////////////////////////////////////////////////*/ g.append("svg:text") .each(function(d) { d.angle = (d.startAngle + d.endAngle) / 2; }) .attr("dy", ".35em") .attr("class", "titles") .attr("text-anchor", function(d) { return d.angle > Math.PI ? "end" : null; }) .attr("transform", function(d) { return "rotate(" + (d.angle * 180 / Math.PI - 90) + ")" + "translate(" + (innerRadius + 55) + ")" + (d.angle > Math.PI ? "rotate(180)" : ""); }) .attr('opacity', 0) .text(function(d,i) { return NameProvider[i]; }); /*////////////////////////////////////////////////////////// //////////////// Initiate inner chords ///////////////////// //////////////////////////////////////////////////////////*/ var chords = svg.selectAll("path.chord") .data(chord.chords) .enter().append("svg:path") .attr("class", "chord") .style("stroke", function(d) { return d3.rgb(fill(d.source.index)).darker(); }) .style("fill", function(d) { return fill(d.source.index); }) .attr("d", d3.svg.chord().radius(innerRadius)) .attr('opacity', 0); /*////////////////////////////////////////////////////////// ///////////// Initiate Progress Bar //////////////////////// //////////////////////////////////////////////////////////*/ /*Initiate variables for bar*/ var progressColor = ["#D1D1D1","#949494"], progressClass = ["prgsBehind","prgsFront"], prgsWidth = 0.4*650, prgsHeight = 3; /*Create SVG to visualize bar in*/ var progressBar = d3.select("#progress").append("svg") .attr("width", prgsWidth) .attr("height", 3*prgsHeight); /*Create two bars of which one has a width of zero*/ progressBar.selectAll("rect") .data([prgsWidth, 0]) .enter() .append("rect") .attr("class", function(d,i) {return progressClass[i];}) .attr("x", 0) .attr("y", 0) .attr("width", function (d) {return d;}) .attr("height", prgsHeight) .attr("fill", function(d,i) {return progressColor[i];}); /*////////////////////////////////////////////////////////// /////////// Initiate the Center Texts ////////////////////// //////////////////////////////////////////////////////////*/ /*Create wrapper for center text*/ var textCenter = svg.append("g") .attr("class", "explanationWrapper"); /*Starting text middle top*/ var middleTextTop = textCenter.append("text") .attr("class", "explanation") .attr("text-anchor", "middle") .attr("x", 0 + "px") .attr("y", -24*10/2 + "px") .attr("dy", "1em") .attr("opacity", 1) .text("For the Dutch version of the Deloitte Global Mobile Consumer Survey, Deloitte asked 2000 residents of the Netherlands about their mobile phone behavior") .call(wrap, 350); /*Starting text middle bottom*/ var middleTextBottom = textCenter.append("text") .attr("class", "explanation") .attr("text-anchor", "middle") .attr("x", 0 + "px") .attr("y", 24*3/2 + "px") .attr("dy", "1em") .attr('opacity', 1) .text("The respondents gave us information about the brand of their current main phone, and the brand of their previous main phone") .call(wrap, 350); /*////////////////////////////////////////////////////////// //////////////// Storyboarding Steps /////////////////////// //////////////////////////////////////////////////////////*/ var counter = 1, buttonTexts = ["Ok","Go on","Continue","Okay","Go on","Continue","Okay","Continue", "Continue","Continue","Continue","Continue","Continue","Finish"], opacityValueBase = 0.8, opacityValue = 0.4; /*Reload page*/ d3.select("#reset") .on("click", function(e) {location.reload();}); /*Skip to final visual right away*/ d3.select("#skip") .on("click", finalChord); /*Order of steps when clicking button*/ d3.select("#clicker") .on("click", function(e){ if(counter == 1) Draw1(); else if(counter == 2) Draw2(); else if(counter == 3) Draw3(); else if(counter == 4) Draw4(); else if(counter == 5) Draw5(); else if(counter == 6) Draw6(); else if(counter == 7) Draw7(); else if(counter == 8) Draw8(); else if(counter == 9) Draw9(); else if(counter == 10) Draw10(); else if(counter == 11) Draw11(); else if(counter == 12) Draw12(); else if(counter == 13) Draw13(); else if(counter == 14) Draw14(); else if(counter == 15) finalChord(); counter = counter + 1; }); /*////////////////////////////////////////////////////////// //Introduction ///////////////////////////////////////////////////////////*/ function Draw1(){ /*First disable click event on clicker button*/ stopClicker(); /*Show and run the progressBar*/ runProgressBar(time=700*11); changeTopText(newText = "These days most people switch phones every few years. " + "Some people stay loyal, but many also switch to a different phone brand...", loc = 4/2, delayDisappear = 0, delayAppear = 1); changeTopText(newText = "In the next few steps I would like to introduce you to the flows of people between the phone brands ", loc = 8/2, delayDisappear = 9, delayAppear = 10, finalText = true); changeBottomText(newText = "Let's start by drawing out the division of the 1846 respondents, that have had at least 2 phones, among the biggest 7 brands ", loc = 1/2, delayDisappear = 0, delayAppear = 10); //Remove arcs again d3.selectAll(".arc") .transition().delay(9*700).duration(2100) .style("opacity", 0) .each("end", function() {d3.selectAll(".arc").remove();}); };/*Draw1*/ /*////////////////////////////////////////////////////////// //Show Arc of Apple //////////////////////////////////////////////////////////*/ function Draw2(){ /*First disable click event on clicker button*/ stopClicker(); /*Show and run the progressBar*/ runProgressBar(time=700*2); /*Initiate all arcs but only show the Apple arc (d.index = 0)*/ g.append("svg:path") .style("stroke", function(d) { return fill(d.index); }) .style("fill", function(d) { return fill(d.index); }) .transition().duration(700) .attr("d", arc) .attrTween("d", function(d) { if(d.index == 0) { var i = d3.interpolate(d.startAngle, d.endAngle); return function(t) { d.endAngle = i(t); return arc(d); } } }); /*Show the tick around the Apple arc*/ d3.selectAll("g.group").selectAll("line") .transition().delay(700).duration(1000) .style("stroke", function(d, i, j) {return j ? 0 : "#000"; }); /*Add the labels for the %'s at Apple*/ d3.selectAll("g.group").selectAll(".tickLabels") .transition().delay(700).duration(2000) .attr("opacity", function(d, i, j) {return j ? 0 : 1; }); /*Show the Apple name*/ d3.selectAll(".titles") .transition().duration(2000) .attr("opacity", function(d, i) {return d.index ? 0 : 1; }); /*Switch text*/ changeTopText(newText = "According to the survey 19% owns an iPhone as their main phone", loc = 1/2, delayDisappear = 0, delayAppear = 1, finalText = true); changeBottomText(newText = "", loc = 0/2, delayDisappear = 0, delayAppear = 1) ; };/*Draw2*/ /*/////////////////////////////////////////////////////////// //Draw the other arcs as well //////////////////////////////////////////////////////////*/ function Draw3(){ /*First disable click event on clicker button*/ stopClicker(); var arcDelay = [0,1,2,12,13,23,33,34,35,40,47]; /*Show and run the progressBar*/ runProgressBar(time=700*(arcDelay[(arcDelay.length-1)]+1)); /*Fill in the other arcs*/ svg.selectAll("g.group").select("path") .transition().delay(function(d, i) { return 700*arcDelay[i];}).duration(1000) .attrTween("d", function(d) { if(d.index != 0) { var i = d3.interpolate(d.startAngle, d.endAngle); return function(t) { d.endAngle = i(t); return arc(d); } } }); /*Make the other strokes black as well*/ svg.selectAll("g.group") .transition().delay(function(d,i) { return 700*arcDelay[i]; }).duration(700) .selectAll("g").selectAll("line").style("stroke", "#000"); /*Same for the %'s*/ svg.selectAll("g.group") .transition().delay(function(d,i) { return 700*arcDelay[i]; }).duration(700) .selectAll("g").selectAll("text").style("opacity", 1); /*And the Names of each Arc*/ svg.selectAll("g.group") .transition().delay(function(d,i) { return 700*arcDelay[i]; }).duration(700) .selectAll("text").style("opacity", 1); /*Change the text of the top section inside the circle accordingly*/ /*HTC*/ changeTopText(newText = "HTC has 5% of the market share", loc = 6/2, delayDisappear = 0, delayAppear = arcDelay[2]); /*LG*/ changeTopText(newText = "LG has almost 5% of the market", loc = 6/2, delayDisappear = arcDelay[3], delayAppear = arcDelay[4]); /*Samsung*/ changeTopText(newText = "Samsung has the biggest share by far, with 38% of respondents using a Samsung as their main phone", loc = 3/2, delayDisappear = (arcDelay[5]-1), delayAppear = arcDelay[5]); /*Sony*/ changeTopText(newText = "Sony has slightly more than 4% share", loc = 4/2, delayDisappear = arcDelay[6], delayAppear = (arcDelay[8]-1)); /*100%*/ changeTopText(newText = "Together that sums up to 100%", loc = 1/2, delayDisappear = (arcDelay[9]-1), delayAppear = arcDelay[9]); /*Chord intro*/ changeTopText(newText = "This circle shows how the respondents are currently divided between the brands", loc = 8/2, delayDisappear = (arcDelay[10]-1), delayAppear = arcDelay[10], finalText = true); /*Change the text of the bottom section inside the circle accordingly*/ /*Huawei*/ changeBottomText(newText = "Huawei came from practically no share in 2013 to 2.4% in 2014 thereby taking its place in the biggest 7 brands in the Netherlands", loc = -2/2, delayDisappear = 0, delayAppear = arcDelay[2]); /*Nokia*/ changeBottomText(newText = "Nokia is still owned by 15% of the respondents. However practically all of these phones are ordinary phones, not smartphones", loc = -1/2, delayDisappear = arcDelay[3], delayAppear = arcDelay[4]); /*Other*/ changeBottomText(newText = "Brands combined in \"Other\" are Blackberry, Motorola, Google Nexus and Operator branded", loc = -1/2, delayDisappear = (arcDelay[5]-1), delayAppear = (arcDelay[8]-1)); /*Chord intro*/ changeBottomText(newText = "Now we're going to look at how these respondents flowed from their previous phone to their present one", loc = 1/2, delayDisappear = (arcDelay[9]-1), delayAppear = arcDelay[10]); };/*Draw3*/ /*/////////////////////////////////////////////////////////// //Show the chord between Samsung and Nokia //////////////////////////////////////////////////////////*/ function Draw4(){ /*First disable click event on clicker button*/ stopClicker(); /*Show and run the progressBar*/ runProgressBar(time=700*2); /*Samsung and Nokia intro text*/ changeTopText(newText = "First, let's only look at the respondents that now own a Samsung, but whose previous phone was a Nokia and vice versa", loc = 5, delayDisappear = 0, delayAppear = 1, finalText = true); /*Bottom text disappear*/ changeBottomText(newText = "", loc = 0, delayDisappear = 0, delayAppear = 1); /*Make the non Samsung & Nokia arcs less visible*/ svg.selectAll("g.group").select("path") .transition().duration(1000) .style("opacity", function(d) { if(d.index != 4 && d.index != 5) {return opacityValue;} }); /*Make the other strokes less visible*/ d3.selectAll("g.group").selectAll("line") .transition().duration(700) .style("stroke",function(d,i,j) {if (j == 5 || j == 4) {return "#000";} else {return "#DBDBDB";}}); /*Same for the %'s*/ svg.selectAll("g.group") .transition().duration(700) .selectAll(".tickLabels").style("opacity",function(d,i,j) {if (j == 5 || j == 4) {return 1;} else {return opacityValue;}}); /*And the Names of each Arc*/ svg.selectAll("g.group") .transition().duration(700) .selectAll(".titles").style("opacity", function(d) { if(d.index == 4 || d.index == 5) {return 1;} else {return opacityValue;}}); /*Show only the Samsung Nokia chord*/ chords.transition().duration(2000) .attr("opacity", function(d, i) { if(d.source.index == 5 && d.target.index == 4) {return opacityValueBase;} else {return 0;} }); };/*Draw4*/ /*//////////////////////////////////////////////////////////////////////////*/ function Draw5(){ /*First disable click event on clicker button*/ stopClicker(); /*Show and run the progressBar*/ runProgressBar(time=700*2); /*Samsung and Nokia text*/ changeTopText(newText = "On the left, touching the arc of Samsung, we can see that the chord runs from 17% to almost 26%. Which is a thickness spanning 9%", loc = 5, delayDisappear = 0, delayAppear = 1, finalText = true); /*Make the non Samsung & Nokia arcs less visible*/ svg.selectAll("g.group").select("path") .transition().duration(1000) .style("opacity", opacityValue); /*Show only the Samsung Nokia part at Samsung*/ var arcSamsung = d3.svg.arc() .innerRadius(innerRadius) .outerRadius(outerRadius) .startAngle(4.040082626337902) .endAngle(4.561777856121815); svg.append("path") .attr("class","SamsungToNokiaArc") .attr("d", arcSamsung) .attr("fill", colors[5]) .style('stroke', colors[5]); repeat(); /*Repeatedly let an arc change colour*/ function repeat() { d3.selectAll(".SamsungToNokiaArc") .transition().duration(700) .attr("fill", "#9FA6D0") .style('stroke', "#9FA6D0") .transition().duration(700) .attr("fill", colors[5]) .style('stroke', colors[5]) .each("end", repeat) ; }; };/*Draw5*/ /*//////////////////////////////////////////////////////////////////////////*/ function Draw6(){ /*First disable click event on clicker button*/ stopClicker(); /*Show and run the progressBar*/ runProgressBar(time=700*2); /*Samsung and Nokia text*/ changeTopText(newText = "These 9% of the respondents now own a Samsung and by following the chord we can see what brand they used to own, which in this case, is Nokia", loc = 5, delayDisappear = 0, delayAppear = 1, finalText = true); /*Show only the Samsung Nokia part at Nokia*/ var arcNokia = d3.svg.arc() .innerRadius(innerRadius) .outerRadius(outerRadius) .startAngle(2.837816067671451) .endAngle(2.9104595910835127); svg.append("path") .attr("class","NokiaToSamsungArc") .attr("d", arcNokia) .attr("opacity", 0) .attr("fill", colors[4]) .transition().duration(700) .attr("opacity", 1) .attr("stroke", colors[4]); };/*Draw6*/ /*//////////////////////////////////////////////////////////////////////////*/ function Draw7(){ /*First disable click event on clicker button*/ stopClicker(); /*Show and run the progressBar*/ runProgressBar(time=700*11); /*Samsung and Nokia text*/ changeTopText(newText = "At the Nokia side, the arc is much thinner, only spanning 1.2% (of respondents)", loc = 4, delayDisappear = 0, delayAppear = 1); changeTopText(newText = "These 1.2% now own a Nokia, but by following the chord we can see that they had a Samsung before", loc = 4, delayDisappear = 9, delayAppear = 10, finalText = true); /*Stop the color changing on the Samsung side*/ d3.selectAll(".SamsungToNokiaArc") .transition().duration(700) .attr("fill", colors[5]) .style("stroke", colors[5]); /*Repeatedly let an arc change colour*/ repeat(); function repeat() { d3.selectAll(".NokiaToSamsungArc") .transition().duration(700) .attr("fill", "#99D2E9") .style('stroke', "#99D2E9") .transition().duration(700) .attr("fill", colors[4]) .style("stroke", colors[4]) .each("end", repeat) ; }; };/*Draw7*/ /*//////////////////////////////////////////////////////////////////////////*/ function Draw8(){ /*First disable click event on clicker button*/ stopClicker(); /*Show and run the progressBar*/ runProgressBar(time=700*11); /*Samsung and Nokia text*/ changeTopText(newText = "Since the chord is much wider at the Samsung side, Samsung has taken a lot more clients from Nokia than Nokia managed to take from Samsung", loc = 5, delayDisappear = 0, delayAppear = 1); changeTopText(newText = "Therefore, the chord is the color of Samsung blue, since Samsung has the net gain from the exchange of people between Nokia and Samsung", loc = 5, delayDisappear = 9, delayAppear = 10, finalText = true); /*Stop the colour changing on the Nokia side*/ d3.selectAll(".NokiaToSamsungArc") .transition().duration(700) .attr("fill", colors[4]) .style("stroke", colors[4]); };/*Draw8*/ /*/////////////////////////////////////////////////////////// //Show Loyalty hills //////////////////////////////////////////////////////////*/ function Draw9(){ /*First disable click event on clicker button*/ stopClicker(); /*Show and run the progressBar*/ runProgressBar(time=700*20); /*Samsung Loyal text*/ changeTopText(newText = "There are also people that stay loyal and did not switch brands between their previous and current phone", loc = 4/2, delayDisappear = 0, delayAppear = 1, finalText = false, xloc=-50, w=300); changeTopText(newText = "These loyal respondents are represented by the hills at each brand", loc = 3/2, delayDisappear = 9, delayAppear = 10, finalText = false, xloc=-50, w=300); changeTopText(newText = "You can also envision this as a chord beginning and ending on itself", loc = 2/2, delayDisappear = 18, delayAppear = 19, finalText = true, xloc=-50, w=300); /*Remove the arcs*/ d3.selectAll(".NokiaToSamsungArc") .transition().duration(2000) .attr("opacity", 0) .each("end", function() {d3.selectAll(".NokiaToSamsungArc").remove();}); d3.selectAll(".SamsungToNokiaArc") .transition().duration(2000) .attr("opacity", 0) .each("end", function() {d3.selectAll(".SamsungToNokiaArc").remove();}); /*Show only the loyal chords*/ chords.transition().duration(2000) .attr("opacity", function(d, i) { if(d.source.index == 0 && d.target.index == 0) {return opacityValueBase;} else if(d.source.index == 1 && d.target.index == 1) {return opacityValueBase;} else if(d.source.index == 2 && d.target.index == 2) {return opacityValueBase;} else if(d.source.index == 3 && d.target.index == 3) {return opacityValueBase;} else if(d.source.index == 4 && d.target.index == 4) {return opacityValueBase;} else if(d.source.index == 5 && d.target.index == 5) {return opacityValueBase;} else if(d.source.index == 6 && d.target.index == 6) {return opacityValueBase;} else if(d.source.index == 7 && d.target.index == 7) {return opacityValueBase;} else {return 0;} }); /*Show all ticks and texts again*/ /*Ticks*/ d3.selectAll("g.group").selectAll("line") .transition().duration(700) .style("stroke", "#000"); /*Same for the %'s*/ svg.selectAll("g.group") .transition().duration(700) .selectAll(".tickLabels").style("opacity", 1); /*And the Names of each Arc*/ svg.selectAll("g.group") .transition().duration(700) .selectAll(".titles").style("opacity", 1); };/*Draw9*/ /*//////////////////////////////////////////////////////////////////////////*/ function Draw10(){ /*First disable click event on clicker button*/ stopClicker(); /*Show and run the progressBar*/ runProgressBar(time=700*11); changeTopText(newText = "10% of respondents have a Nokia right now, but also used to own a Nokia before that", loc = 7/2, delayDisappear = 0, delayAppear = 1); changeTopText(newText = "Seeing that currently Nokia is owned by almost 16% of respondents, this means "+ "that about 2/3 of current Nokia owners are people who stayed loyal", loc = 7/2, delayDisappear = 9, delayAppear = 10, finalText = true); /*Show only the Nokia Loyal arc*/ var arcNokia = d3.svg.arc() .innerRadius(innerRadius) .outerRadius(outerRadius) .startAngle(2.048671976860533) .endAngle(2.6694216777820063); svg.append("path") .attr("class","NokiaLoyalArc") .attr("d", arcNokia) .attr("opacity", 1) .attr("stroke", colors[4]) .attr("fill", colors[4]); /*Repeatedly let an arc change colour*/ repeat(); function repeat() { d3.selectAll(".NokiaLoyalArc") .transition().duration(700) .attr("fill", "#99D2E9") .style('stroke', "#99D2E9") .transition().duration(700) .attr("fill", colors[4]) .style("stroke", colors[4]) .each("end", repeat); }; /*Show only the Nokia loyal chord*/ chords.transition().duration(2000) .attr("opacity", function(d, i) { if(d.source.index == 4 && d.target.index == 4) {return opacityValueBase;} else {return 0;} }); /*Make the other strokes less visible*/ d3.selectAll("g.group").selectAll("line") .transition().duration(700) .style("stroke",function(d,i,j) {if (j == 4) {return "#000";} else {return "#DBDBDB";}}); /*Same for the %'s*/ svg.selectAll("g.group") .transition().duration(700) .selectAll(".tickLabels").style("opacity",function(d,i,j) {if (j == 4) {return 1;} else {return opacityValue;}}); /*And the Names of each Arc*/ svg.selectAll("g.group") .transition().duration(700) .selectAll(".titles").style("opacity", function(d) { if(d.index == 4) {return 1;} else {return opacityValue;}}); };/*Draw10*/ /*////////////////////////////////////////////////////////// //Show all chords that are connected to Apple //////////////////////////////////////////////////////////*/ function Draw11(){ /*First disable click event on clicker button*/ stopClicker(); /*Show and run the progressBar*/ runProgressBar(time=700*2); changeTopText(newText = "Here are all the chords for those respondents that currently own "+ "an iPhone or that used to own an iPhone", loc = 3/2, delayDisappear = 0, delayAppear = 1, finalText = true, xloc=-80, w=200); /*Remove the Nokia arc*/ d3.selectAll(".NokiaLoyalArc") .transition().duration(1000) .attr("opacity", 0) .each("end", function() {d3.selectAll(".NokiaLoyalArc").remove();}); /*Only show the chords of Apple*/ chords.transition().duration(2000) .attr("opacity", function(d, i) { if(d.source.index == 0 || d.target.index == 0) {return opacityValueBase;} else {return 0;} }); /*Highlight arc of Apple*/ svg.selectAll("g.group").select("path") .transition().duration(2000) .style("opacity", function(d) { if(d.index != 0) {return opacityValue;} }); /*Show only the ticks and text at Apple*/ /*Make the other strokes less visible*/ d3.selectAll("g.group").selectAll("line") .transition().duration(700) .style("stroke",function(d,i,j) {if (j == 0) {return "#000";} else {return "#DBDBDB";}}); /*Same for the %'s*/ svg.selectAll("g.group") .transition().duration(700) .selectAll(".tickLabels").style("opacity",function(d,i,j) {if (j == 0) {return 1;} else {return opacityValue;}}); /*And the Names of each Arc*/ svg.selectAll("g.group") .transition().duration(700) .selectAll(".titles").style("opacity", function(d) { if(d.index == 0) {return 1;} else {return opacityValue;}}); };/*Draw11*/ function Draw12(){ /*First disable click event on clicker button*/ stopClicker(); /*Show and run the progressBar*/ runProgressBar(time=700*11); changeTopText(newText = "One thing that stands out for Apple is that all chords connected to " + "Apple are the color of the Apple arc: grey", loc = 3/2, delayDisappear = 0, delayAppear = 1, finalText = false, xloc=-80, w=210); changeTopText(newText = "This means that Apple has always had the net gain. " + "They received more customers from other brands than they lost to them", loc = 3/2, delayDisappear = 9, delayAppear = 10, finalText = true, xloc=-80, w=210); };/*Draw12*/ function Draw13(){ /*First disable click event on clicker button*/ stopClicker(); /*Show and run the progressBar*/ runProgressBar(time=700*11); changeTopText(newText = "Even more so, apart from the chord to Samsung, all other chords are extremely narrow at the other end from Apple", loc = 3/2, delayDisappear = 0, delayAppear = 1, finalText = false, xloc=-80, w=200); changeTopText(newText = "This means that Apple has lost virtually nobody to any other brand", loc = 3/2, delayDisappear = 9, delayAppear = 10, finalText = true, xloc=-80, w=200); /*Repeatedly let specific chords change colour*/ repeat(); function repeat() { chords .transition().duration(1000) .style("opacity",function (d){ if(d.source.index == 0) { if(d.target.index == 0 || d.target.index == 5) {return opacityValueBase;} else {return 0.2;} } else {return 0;} }) .transition().duration(1000) .style("opacity",function (d){ if(d.source.index == 0) {return opacityValueBase;} else {return 0;} }) .each("end", repeat); }; };/*Draw13*/ function Draw14(){ /*First disable click event on clicker button*/ stopClicker(); /*Show and run the progressBar*/ /*runProgressBar(time=700*2);*/ changeTopText(newText = "Thank you for staying with me so far! After these examples I think you're absolutely " + "ready to face the full impact of all chords simultaneously", loc = 8/2, delayDisappear = 0, delayAppear = 1, finalText = true); changeBottomText(newText = "I'm looking forward to hearing about the insights that you have discovered on your own", loc = 3/2, delayDisappear = 0, delayAppear = 1); /*Only show the chords of Apple*/ chords.transition().duration(1000) .style("opacity", 0.1); /*Hide all the text*/ d3.selectAll("g.group").selectAll("line") .transition().duration(700) .style("stroke","#DBDBDB"); /*Same for the %'s*/ svg.selectAll("g.group") .transition().duration(700) .selectAll(".tickLabels").style("opacity",0.4); /*And the Names of each Arc*/ svg.selectAll("g.group") .transition().duration(700) .selectAll(".titles").style("opacity",0.4); };/*Draw14*/ /*/////////////////////////////////////////////////////////// //Draw the original Chord diagram ///////////////////////////////////////////////////////////*/ /*Go to the final bit*/ function finalChord() { /*Remove button*/ d3.select("#clicker") .style("visibility", "hidden"); d3.select("#skip") .style("visibility", "hidden"); d3.select("#progress") .style("visibility", "hidden"); /*Remove texts*/ changeTopText(newText = "", loc = 0, delayDisappear = 0, delayAppear = 1); changeBottomText(newText = "", loc = 0, delayDisappear = 0, delayAppear = 1); /*Create arcs or show them, depending on the point in the visual*/ if (counter <= 4 ) { g.append("svg:path") .style("stroke", function(d) { return fill(d.index); }) .style("fill", function(d) { return fill(d.index); }) .attr("d", arc) .style("opacity", 0) .transition().duration(1000) .style("opacity", 1); } else { /*Make all arc visible*/ svg.selectAll("g.group").select("path") .transition().duration(1000) .style("opacity", 1); }; /*Make mouse over and out possible*/ d3.selectAll(".group") .on("mouseover", fade(.02)) .on("mouseout", fade(.80)); /*Show all chords*/ chords.transition().duration(1000) .style("opacity", opacityValueBase); /*Show all the text*/ d3.selectAll("g.group").selectAll("line") .transition().duration(100) .style("stroke","#000"); /*Same for the %'s*/ svg.selectAll("g.group") .transition().duration(100) .selectAll(".tickLabels").style("opacity",1); /*And the Names of each Arc*/ svg.selectAll("g.group") .transition().duration(100) .selectAll(".titles").style("opacity",1); };/*finalChord*/ /*////////////////////////////////////////////////////////// ////////////////// Extra Functions ///////////////////////// //////////////////////////////////////////////////////////*/ /*Returns an event handler for fading a given chord group*/ function fade(opacity) { return function(d, i) { svg.selectAll("path.chord") .filter(function(d) { return d.source.index != i && d.target.index != i; }) .transition() .style("stroke-opacity", opacity) .style("fill-opacity", opacity); }; };/*fade*/ /*Returns an array of tick angles and labels, given a group*/ function groupTicks(d) { var k = (d.endAngle - d.startAngle) / d.value; return d3.range(0, d.value, 1).map(function(v, i) { return { angle: v * k + d.startAngle, label: i % 5 ? null : v + "%" }; }); };/*groupTicks*/ /*Taken from https://groups.google.com/forum/#!msg/d3-js/WC_7Xi6VV50/j1HK0vIWI-EJ //Calls a function only after the total transition ends*/ function endall(transition, callback) { var n = 0; transition .each(function() { ++n; }) .each("end", function() { if (!--n) callback.apply(this, arguments); }); };/*endall*/ /*Taken from http://bl.ocks.org/mbostock/7555321 //Wraps SVG text*/ function wrap(text, width) { var text = d3.select(this)[0][0], words = text.text().split(/\s+/).reverse(), word, line = [], lineNumber = 0, lineHeight = 1.4, y = text.attr("y"), x = text.attr("x"), dy = parseFloat(text.attr("dy")), tspan = text.text(null).append("tspan").attr("x", x).attr("y", y).attr("dy", dy + "em"); while (word = words.pop()) { line.push(word); tspan.text(line.join(" ")); if (tspan.node().getComputedTextLength() > width) { line.pop(); tspan.text(line.join(" ")); line = [word]; tspan = text.append("tspan").attr("x", x).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word); }; }; }; /*Transition the top circle text*/ function changeTopText (newText, loc, delayDisappear, delayAppear, finalText, xloc, w) { /*If finalText is not provided, it is not the last text of the Draw step*/ if(typeof(finalText)==='undefined') finalText = false; if(typeof(xloc)==='undefined') xloc = 0; if(typeof(w)==='undefined') w = 350; middleTextTop /*Current text disappear*/ .transition().delay(700 * delayDisappear).duration(700) .attr('opacity', 0) /*New text appear*/ .call(endall, function() { middleTextTop.text(newText) .attr("y", -24*loc + "px") .attr("x", xloc + "px") .call(wrap, w); }) .transition().delay(700 * delayAppear).duration(700) .attr('opacity', 1) .call(endall, function() { if (finalText == true) { d3.select("#clicker") .text(buttonTexts[counter-2]) .style("pointer-events", "auto") .transition().duration(400) .style("border-color", "#363636") .style("color", "#363636"); }; }); };/*changeTopText */ /*Transition the bottom circle text*/ function changeBottomText (newText, loc, delayDisappear, delayAppear) { middleTextBottom /*Current text disappear*/ .transition().delay(700 * delayDisappear).duration(700) .attr('opacity', 0) /*New text appear*/ .call(endall, function() { middleTextBottom.text(newText) .attr("y", 24*loc + "px") .call(wrap, 350); }) .transition().delay(700 * delayAppear).duration(700) .attr('opacity', 1); ;}/*changeTopText*/ /*Stop clicker from working*/ function stopClicker() { d3.select("#clicker") .style("pointer-events", "none") .transition().duration(400) .style("border-color", "#D3D3D3") .style("color", "#D3D3D3"); };/*stopClicker*/ /*Run the progress bar during an animation*/ function runProgressBar(time) { /*Make the progress div visible*/ d3.selectAll("#progress") .style("visibility", "visible"); /*Linearly increase the width of the bar //After it is done, hide div again*/ d3.selectAll(".prgsFront") .transition().duration(time).ease("linear") .attr("width", prgsWidth) .call(endall, function() { d3.selectAll("#progress") .style("visibility", "hidden"); }); /*Reset to zero width*/ d3.selectAll(".prgsFront") .attr("width", 0); };/*runProgressBar*/