Skip to content

Instantly share code, notes, and snippets.

@nbremer
Last active November 18, 2019 16:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save nbremer/75c76f4be60fce435aba to your computer and use it in GitHub Desktop.
Save nbremer/75c76f4be60fce435aba to your computer and use it in GitHub Desktop.
Phone Brand Switching - Chord Diagram - 2014
height: 2700

The full blog about the 2014 version of the Chord Diagram created for the Global Mobile Consumer Survey held by Deloitte each year. It was featured on the Deloitte Netherlands webpage. It shows the flows of people between the phone brand of their previous phone and the current phone

For an explanation on how to understand this chart, please take a look at my "Storytelling" version of the same Chord Diagram but with 2013 data

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>Chord Diagram - Phone Brand Switching Behavior</title>
<script src="http://d3js.org/d3.v3.min.js"></script>
<!-- <link type="text/css" rel="stylesheet" href="style.css"/> -->
<style>
body {
/*overflow: hidden;*/
margin: 0;
font-size: 14px;
font-family: "Helvetica Neue", Helvetica;
}
#Title {
position: absolute;
top: 0;
z-index: 1;
display: block;
font-size: 36px;
font-weight: 300;
text-shadow: 0 1px 0 #fff;
top: 30px;
left: 30px;
text-align: left;
font-family: "Trebuchet MS", Helvetica, sans-serif;
}
.subtitle {
font-size: 24px;
color: #404040;
}
.hint {
width: 500px;
font-size: 12px;
color: #999;
}
#chart_lastYear {
position: absolute;
left: 30px;
}
#chart_thisYear {
position: absolute;
left: 600px;
}
#SideText{
position: absolute;
display: block;
font-size: 12px;
color: #474747;
top: 400px;
left: 950px;
width: 200px;
}
#BelowText{
position: absolute;
font-size: 14px;
color: #474747;
top: 160px;
left: 30px;
width: 1170px;
}
line {
stroke: #000;
stroke-width: 1.px;
}
text {
font-size: 10px;
}
.years{
font-size: 32px;
font-weight: 300;
text-shadow: 0 1px 0 #fff;
text-anchor: middle;
font-family: "Trebuchet MS", Helvetica, sans-serif;
}
.titles{
font-size: 14px;
}
.list{
font-size: 12px;
}
li:not(:last-child) {
margin-bottom: 5px;
}
p {
margin-top: 0em;
margin-bottom: 0.75em;
}
h4 {
margin-top: 2em;
margin-bottom: 0.75em;
}
.titles_LY{
font-size: 12px;
}
.annotate{
font-size: 11px;
fill: #474747;
}
path.chord {
fill-opacity: .80;
}
.pTitle {
font-size: 16px;
text-shadow: 0 1px 0 #fff;
fill: #474747;
font-weight: bold;
}
.survey {
font-size: 10px;
}
</style>
</head>
<body>
<div id="body">
<div id="Title">
Switching behavior between phone brands of the Dutch <br>
<div class="subtitle">2014 Edition</div>
<div class="hint">
<br>
<span>Analyzing the results of the Deloitte Mobile Consumer Survey - Netherlands Edition<span/></br>
<span>Mouse over a brand to highlight</span>
</div>
</div>
<div id="SideText">
<p id="p0" class="pTitle Side">Chord Diagram</p>
<p id="p1" class="Side">This chord diagram shows relationships in terms of switching behaviour among phone brands.</p>
<p id="p2" class="Side">The chords are directed: for example, while 8.7% of respondents who now have a Samsung used to have a Nokia, only 1.2% have the opposite; 1.2% now have a Nokia and used to have a Samsung phone.</p>
<p id="p3" class="Side">The thickness of chords between brands encodes the percentage of respondents that switched between two brands: thicker chords represent a higher percentage of respondents that made that switch.</p>
<p id="p4" class="Side">This diagram reveals asymmetries: if a chord is tapered, there are more respondents switching to one brand from the other than vice versa.</p>
<p id="p5" class="Side">Mouse over a brand name to focus on switching behaviour to and from other brands concerning that specific brand.</p>
</div>
<div id="BelowText">
<p>
While almost everyone in the Netherlands has a phone, many consumers switch to a new phone whenever their contract allows it. But how do people switch? And how does this differ per brand?
To understand the complete flows of people switching phone brands (or staying loyal) we have analysed the connection between the respondent's current and previous main phone brand by visualizing the data in the Chord Diagram above.
The chord diagram's outer ring represents the current main brand shares of all the respondents while the chords help to show what the brand of the previous was used to be.
</p>
<h4>EXPLAINING THE CHORD DIAGRAM</h4>
<p>
The circle is split up into 8 brands with the arc length of each group scaled to the current brand’s market share.
The percentages along the outer rim of the chord Diagram give the share-per-brand.
This shows that Samsung dominates the installed base with a 38% share, Apple is 2nd with 19% and Nokia is 3rd with 16%.
</p>
<p>
The chords between the arcs visualize the switching behaviour of the respondents between brands in both directions.
For example, the big dark blue chord connecting Samsung and Nokia in the lower left section shows the part of respondents that moved from Samsung to Nokia and from Nokia to Samsung.
The figure shows that Nokia has lost its installed base share to Samsung, as 8.7% of all respondents that used to own a Nokia now own a Samsung.
At the same time, only 1.2% of the Nokia owners previously owned a Samsung.
</p>
<div id="chart"></div>
<p>
The color of the chord shows which brand has been the net gainer, thus the brand that managed to gain more customers from the connected brand than it has lost to this brand.
With this in mind, we can see that Apple is a true net gainer; all its chords are 'Apple grey'.
Even more so, besides the chord to Samsung, all chords at Apple are extremely thin at the other side, thus Apple has lost virtually no customers to other brands except Samsung.
</p>
<p>
There are also chords that connect each brand to itself.
These 'hill-like' chords represent the respondents who did not switch brands, but stayed loyal to their brand.
</p>
<p>
Hover over a brand name or arc to see only the chords of that brand highlighted and an extra piece of information regarding that brand to the right of the Chord Diagram.
</p>
<p>
Note: This analysis refers only to respondents' main phone
</p>
<h4>INSIGHTS FROM THE 2014 GLOBAL MOBILE CONSUMER SURVEY - NETHERLANDS EDITION</h4>
<p>
When studying the flows between brands we can come to several interesting conclusions:
<ul class="list">
<li>Apple and Samsung are capturing users from mainly Nokia and Other</li>
<li>Apple is losing few users, except to Samsung; even so, the number gained is twice the number lost</li>
<li>HTC is acquiring users from Nokia and LG, yet losing users to Samsung and Huawei</li>
<li>Nokia is still acquiring more users from Other than it loses</li>
<li>Huawei stands out as a new brand that is gaining small numbers of users from all brands, particularly Samsung.
Huawei reported 120% growth in handset shipments in Europe<sup>1</sup> and has become the 3rd brand in worldwide shipments, leaving Nokia, HTC and LG behind<sup>2</sup></li>
</ul>
</p>
<h4>COMPARING 2014 TO LAST YEAR'S RESULTS</h4>
<p>
Since this is the 2nd year that we have created a Chord Diagram from the GMCS data, we can compare the years to find changes that have occurred since last year.
Below you can see the Chord diagram from last year on the left and the one from 2014 (thus the same as the big one at the top of the page) on the right:</p>
<div id="Comparison_Charts" style="height:600px">
<div id="chart_lastYear"></div>
<div id="chart_thisYear"></div>
</div>
<p>Several points stand out by comparing these two Chord Diagrams
<ul class="list">
<li>Blackberry has decreased its share to only 1.5% and is now added to the "Other" category, while Huawei has grown significantly (from 0.2% last year to 2.4% in 2014) to take its place</li>
<li>Apple has grown its share of being the main phone of the respondents from 13% to almost 20%. More so, its share of people remaining loyal to the iPhone is also increasing</li>
<li>Nokia keeps losing share, from 20% last year to 15% this year (of which 12% is a non-smartphone Nokia), thus losing its place as 2nd biggest brand to Apple</li>
<li>Nokia, Samsung, Sony and HTC have all lost share since last year, while Apple, Huawei and more smaller brands in Other have grown</li>
<li>Very interestingly, although shares among brands have shifted, the most interesting flows from last year show less difference.
Apple is still taking more clients from every other brand than losing to them. Nokia is still losing its biggest share by far to Samsung and only winning a bit from the "Other" category.
However, in 2014 Samsung is taking more clients from HTC while HTC had a net win last year
</ul>
</p>
<h4>FINAL NOTE</h4>
</p>
<p>
These examples are a handful of the interesting facts that can be gained from the study. I encourage you to study the chord diagram by yourself to find even more insights and play with the interactive version.
Finally, this analysis is but a small piece of the total report based on the yearly Global Mobile Consumer Survey - Netherlands Edition that Deloitte performed.
Please feel free to contact any of the team members for more information or the complete report and also how you can discuss this with your clients.
</p>
<br>
<p>
Analysis and Visualization created by Nadieh Bremer. See her other blogs on <a href="http://www.visualcinnamon.com/">Visual Cinnamon</a>
</p>
<br>
<p class="survey">
(1) http://www.zdnet.com/huawei-sees-massive-handset-growth-outside-china-7000032074/<br>
(2) IDC 2014 Weighted Base: All adults 18-75 who have a phone or smartphone (n=1846) <br><br>
<b>Survey</b></br>
Deloitte has carried out the Global Mobile Consumer Survey – an annual snapshot of the mobile consumer, based on insights from more than 37.000 respondents in more than 22 countries.
This analysis is based on the Dutch mobile market anno 2014, based on over 2000 respondents from the Netherlands, where this sample is nationally representative.
All research has been undertaken via online research. Fieldwork took place between May to June 2014.
The questions for this survey were written by Deloitte member firms. The multinational online research program was managed by Ipsos MORI.</p>
<p class="survey"><b>Project team</b></br>
Stephen Ward (sponsoring partner), Gagandeep Sethi (Project Manager), Arseni Storojev, Remco Gaykema, Jessica Abad Kelly, Morris Boermann & Nadieh Bremer
</p>
<br><br>
</div>
</div>
<!-- Big Chord Diagram -->
<script type="text/javascript">
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*/
[0.1107,1.8272,0,0.4983,1.1074,1.052,0.2215,0.4983], /*HTC*/
[0.0554,0.2769,0.2215,0.2215,0.3876,0.8306,0.0554,0.3322], /*Huawei*/
[0.0554,0.1107,0.0554,1.2182,1.1628,0.6645,0.4983,1.052], /*LG*/
[0.2215,0.443,0,0.2769,10.4097,1.2182,0.4983,2.8239], /*Nokia*/
[1.1628,2.6024,0,1.3843,8.7486,16.8328,1.7165,5.5925], /*Samsung*/
[0.0554,0.4983,0,0.3322,0.443,0.8859,1.7719,0.443], /*Sony*/
[0.2215,0.7198,0,0.3322,1.6611,1.495,0.1107,5.4264] /*Other*/
];
var colors = ["#C4C4C4","#69B40F","#EC1D25","#C8125C","#008FC8","#10218B","#134B24","#737373"];
var chord = d3.layout.chord()
.padding(.04)
.sortSubgroups(d3.descending)
.sortChords(d3.descending)
.matrix(matrix);
var width = 900,
height = 650,
innerRadius = Math.min(width, height) * .39,
outerRadius = innerRadius * 1.09;
var fill = d3.scale.ordinal()
.domain(d3.range(NameProvider.length))
.range(colors);
var arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius);
var svg = d3.select("#chart").append("svg:svg")
.attr("width", width)
.attr("height", height+170)
.append("svg:g")
.attr("transform", "translate(" + (width / 2 + 30) + "," + (height / 2+90) + ")");
/*//////////////////////////////////////////////////////////
////////////////// Draw outer Arcs /////////////////////////
//////////////////////////////////////////////////////////*/
var g = svg.selectAll("g.group")
.data(chord.groups)
.enter().append("svg:g")
.attr("class", "group")
.on("mouseover", fadeIn(.02))
.on("mouseout", fadeOut(.80));
g.append("svg:path")
.style("stroke", function(d) { return fill(d.index); })
.style("fill", function(d) { return fill(d.index); })
.attr("d", arc);
/*//////////////////////////////////////////////////////////
////////////////// Append Ticks ////////////////////////////
//////////////////////////////////////////////////////////*/
var ticks = svg.append("svg:g").selectAll("g.ticks")
.data(chord.groups)
.enter().append("svg:g").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)";
});
ticks.append("svg:line")
.attr("x1", 1)
.attr("y1", 0)
.attr("x2", 5)
.attr("y2", 0)
.style("stroke", "#000");
ticks.append("svg:text")
.attr("x", 8)
.attr("dy", ".35em")
.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; });
/*//////////////////////////////////////////////////////////
////////////////// Append 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)" : "");
})
.text(function(d,i) { return NameProvider[i]; });
/*//////////////////////////////////////////////////////////
////////////////// Draw inner 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));
/*//////////////////////////////////////////////////////////
////////////////////// Annotate ////////////////////////////
//////////////////////////////////////////////////////////*/
/*From Nokia to Samsung*/
svg.append("svg:text")
.attr("class", "annotate")
.attr("x", -445)
.attr("y", 83)
.text("8.7% of respondents switched");
svg.append("svg:text")
.attr("class", "annotate")
.attr("x", -445)
.attr("y", 96)
.text("from Nokia to Samsung");
svg.append("svg:text")
.attr("class", "annotate")
.attr("x", -445)
.attr("y", 109)
.text("Taking a substantial part");
svg.append("svg:text")
.attr("class", "annotate")
.attr("x", -445)
.attr("y", 122)
.text("of those that used to have Nokia");
svg.append("svg:line")
.attr("class", "annotate")
.attr("x1", -445)
.attr("y1", 70)
.attr("x2", -280)
.attr("y2", 70)
.style("stroke", "#858585");
/*From Samsung to Nokia*/
svg.append("svg:text")
.attr("class", "annotate")
.attr("x", 73)
.attr("y", 340)
.text("Only 1.2% of respondents");
svg.append("svg:text")
.attr("class", "annotate")
.attr("x", 73)
.attr("y", 353)
.text("switched from Samsung to Nokia");
svg.append("svg:line")
.attr("class", "annotate")
.attr("x1", 68)
.attr("y1", 280)
.attr("x2", 68)
.attr("y2", 354)
.style("stroke", "#858585");
/*Huawei*/
svg.append("svg:text")
.attr("class", "annotate")
.attr("x", 420)
.attr("y", 38)
.attr("text-anchor","end")
.text("Huawei, not present");
svg.append("svg:text")
.attr("class", "annotate")
.attr("x", 420)
.attr("y", 51)
.attr("text-anchor","end")
.text("last year, is now");
svg.append("svg:text")
.attr("class", "annotate")
.attr("x", 420)
.attr("y", 64)
.attr("text-anchor","end")
.text("the main phone of");
svg.append("svg:text")
.attr("class", "annotate")
.attr("x", 420)
.attr("y", 77)
.attr("text-anchor","end")
.text("2.4% of respondents");
svg.append("svg:line")
.attr("class", "annotate")
.attr("x1", 285)
.attr("y1", 25)
.attr("x2", 420)
.attr("y2", 25)
.style("stroke", "#858585");
/*Apple*/
svg.append("svg:text")
.attr("class", "annotate")
.attr("x", 63)
.attr("y", -383)
.text("Almost 10% of respondents have stayed loyal to Apple");
svg.append("svg:text")
.attr("class", "annotate")
.attr("x", 63)
.attr("y", -370)
.text("and again bought an iPhone.");
svg.append("svg:text")
.attr("class", "annotate")
.attr("x", 63)
.attr("y", -357)
.text("That is half of Apple's current base");
svg.append("svg:line")
.attr("class", "annotate")
.attr("x1", 58)
.attr("y1", -282)
.attr("x2", 58)
.attr("y2", -393)
.style("stroke", "#858585");
/*//////////////////////////////////////////////////////////
////////////////// Extra Functions /////////////////////////
//////////////////////////////////////////////////////////*/
/*Returns an event handler for fading a given chord group*/
function fadeIn(opacity) {
return function(d, i) {
d3.selectAll(".Side")
.transition()
.duration(200)
.style("opacity", 0.0001);
d3.selectAll(".annotate")
.transition()
.duration(200)
.style("opacity", 0.0001);
d3.select("#p0").transition().duration(200).delay(200).style("opacity", 1).text(NameProvider[i]);
if(i == 0) { //Apple
d3.select("#p1").transition().duration(200).delay(200).style("opacity", 1).text("All chords connected to Apple are ‘Apple grey’, thus showing that Apple has been able to take more customers from all other brands than vice versa, making it the most successful net gainer of all brands in this analysis");
d3.select("#p2").transition().duration(200).delay(200).style("opacity", 1).text("Furthermore, the chords from Apple are very tapered to all brands except Samsung (the width is much larger at Apple while almost non-existent at the other ends). This implies that Apple is losing virtually no customers to other brands except Samsung.");
d3.select("#p3").transition().duration(200).delay(200).style("opacity", 1).text("Additionally, almost half of the current iPhone owners also previously had an iPhone, implying significant loyalty among Apple owners. More interestingly, the group of loyal iPhone owners has grown to almost twice its size from last year (from 5% to almost 10%). This is in line with the finding from the survey that almost a third have bought an iPhone because of the brand.");
d3.select("#p4").transition().duration(200).delay(200).style("opacity", 1).text(" ");
d3.select("#p5").transition().duration(200).delay(200).style("opacity", 1).text(" ");
} else if (i == 1) { //Blackberry
d3.select("#p1").transition().duration(200).delay(200).style("opacity", 1).text("HTC has lost almost half of its share since last year and is now only gaining from Nokia");
d3.select("#p2").transition().duration(200).delay(200).style("opacity", 1).text(" ");
d3.select("#p3").transition().duration(200).delay(200).style("opacity", 1).text(" ");
d3.select("#p4").transition().duration(200).delay(200).style("opacity", 1).text(" ");
d3.select("#p5").transition().duration(200).delay(200).style("opacity", 1).text(" ");
} else if (i == 2) { //HTC
d3.select("#p1").transition().duration(200).delay(200).style("opacity", 1).text("Huawei is new this year, having replaced Blackberry as the 7th largest brand, having grown from virtually no share in 2013 to 2.4% in 2014");
d3.select("#p2").transition().duration(200).delay(200).style("opacity", 1).text("Its biggest share has come from Samsung, but it has gained pratically no share from Apple.");
d3.select("#p3").transition().duration(200).delay(200).style("opacity", 1).text(" ");
d3.select("#p4").transition().duration(200).delay(200).style("opacity", 1).text(" ");
d3.select("#p5").transition().duration(200).delay(200).style("opacity", 1).text(" ");
} else if (i == 3) { //LG
d3.select("#p1").transition().duration(200).delay(200).style("opacity", 1).text("Having a relatively stable share compared to the other small brands since 2013, LG is (still) currently owned by 4% of the respondents.");
d3.select("#p2").transition().duration(200).delay(200).style("opacity", 1).text("While mostly a net gainer last year, it now has a mix; losing more to Samsing, Apple, HTC and Huawei while gaining more from Nokia, Sony and Other.");
d3.select("#p3").transition().duration(200).delay(200).style("opacity", 1).text(" ");
d3.select("#p4").transition().duration(200).delay(200).style("opacity", 1).text(" ");
d3.select("#p5").transition().duration(200).delay(200).style("opacity", 1).text(" ");
} else if (i == 4) { //Nokia
d3.select("#p1").transition().duration(200).delay(200).style("opacity", 1).text("Nokia is now the 3rd-largest brand in the mobile phone installed base, having lost its 2nd place to Apple since 2013.");
d3.select("#p2").transition().duration(200).delay(200).style("opacity", 1).text("They have a share of 15% among respondents, which now practically only consists of respondents with standard mobile phones (non-smartphones).");
d3.select("#p3").transition().duration(200).delay(200).style("opacity", 1).text("Compared to other brand owners, Nokia owners are still particularly interested in the device price when purchasing their latest devices, being the most often chosen main reason for purchasing a phone.");
d3.select("#p4").transition().duration(200).delay(200).style("opacity", 1).text("Nokia is a net loser compared to almost all other main brands. The most dramatic loss is to Samsung; when comparing sizes, Nokia lost about half of its current share to Samsung alone.");
d3.select("#p5").transition().duration(200).delay(200).style("opacity", 1).text(" ");
} else if (i == 5) { //Samsung
d3.select("#p1").transition().duration(200).delay(200).style("opacity", 1).text("Samsung is dominating the mobile phone installed base, with almost 40% of respondents currently using a Samsung phone. ");
d3.select("#p2").transition().duration(200).delay(200).style("opacity", 1).text("They are a net gainer from all other brands except Apple and Huawei. Especially the net gains from Nokia and Other are large, which can be seen be the chord being much wider at Samsung than Nokia or Other.");
d3.select("#p3").transition().duration(200).delay(200).style("opacity", 1).text("Samsung has also been very successful in keeping their customers loyal; slightly less than half of the current Samsung share had a Samsung as their previous phone.");
d3.select("#p4").transition().duration(200).delay(200).style("opacity", 1).text("According to our survey results, Samsung owners were paying more attention to purchasing criteria like device price, cost of contract, large screen size and the quality of the camera than Apple users.");
d3.select("#p5").transition().duration(200).delay(200).style("opacity", 1).text("Compared to last year we now see that Battery Life is longer an important point for Samsung alone, but for all other brands as well");
} else if (i == 6) { //Sony
d3.select("#p1").transition().duration(200).delay(200).style("opacity", 1).text("Sony is losing more to Samsung, Apple, Nokia, LG and Huawei than gaining from them, although the net gain seems almost zero for Nokia and LG since the chords at both sides have the same width.");
d3.select("#p2").transition().duration(200).delay(200).style("opacity", 1).text("Sony is the only top-7 brand that is not gaining a much larger portion from Nokia than losing from them, it is actually losing a slightly larger share to Nokia than gaining.");
d3.select("#p3").transition().duration(200).delay(200).style("opacity", 1).text(" ");
d3.select("#p4").transition().duration(200).delay(200).style("opacity", 1).text(" ");
d3.select("#p5").transition().duration(200).delay(200).style("opacity", 1).text(" ");
} else if (i == 7) { //Other
d3.select("#p1").transition().duration(200).delay(200).style("opacity", 1).text("Brands that have been grouped in the 'Other' category have a current 'Main phone' share which does not put them in the top 7. Thus a share smaller than Huawei.");
d3.select("#p2").transition().duration(200).delay(200).style("opacity", 1).text("They include; Blackberry (1.6%), Motorola (0.6%), Google Nexus (0.4%) and Operator branded (0.3%).");
d3.select("#p3").transition().duration(200).delay(200).style("opacity", 1).text("A big portion is also comprised by the choice 'Other' (4.1%), including brands that were not a separate choice on the survey.");
d3.select("#p4").transition().duration(200).delay(200).style("opacity", 1).text(" ");
d3.select("#p5").transition().duration(200).delay(200).style("opacity", 1).text(" ");
};
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);
};
}/*fadeIn*/
/*Returns an event handler for fading a given chord group*/
function fadeOut(opacity) {
return function(d, i) {
d3.selectAll(".Side")
.transition()
.duration(200)
.style("opacity", 0.0001);
d3.selectAll(".annotate")
.transition()
.duration(200)
.style("opacity", 1);
d3.select("#p0").transition().duration(200).delay(200).style("opacity", 1).text("Chord Diagram")
d3.select("#p1").transition().duration(200).delay(200).style("opacity", 1).text("This chord diagram shows relationships in terms of switching behaviour among phone brands.")
d3.select("#p2").transition().duration(200).delay(200).style("opacity", 1).text("The chords are directed: for example, while 8.7% of respondents who now have a Samsung used to have a Nokia, only 1.2% have the opposite; 1.2% now have a Nokia and used to have a Samsung phone.")
d3.select("#p3").transition().duration(200).delay(200).style("opacity", 1).text("The thickness of chords between brands encodes the percentage of respondents that switched between two brands: thicker chords represent a higher percentage of respondents that made that switch.")
d3.select("#p4").transition().duration(200).delay(200).style("opacity", 1).text("This diagram reveals asymmetries: if a chord is tapered, there are more respondents switching to one brand from the other than vice versa.")
d3.select("#p5").transition().duration(200).delay(200).style("opacity", 1).text("Mouse over a brand name to focus on switching behaviour to and from other brands concerning that specific brand.")
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);
};
}/*fadeOut*/
/*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*/
</script>
<!-- The small 2013 Chord Diagram -->
<script>
var NameProvider = ["Apple","Blackberry","HTC","LG","Nokia","Samsung","Sony","Other"];
var matrix = [
[5.0858,1.777,0.7353,0.4902,2.6348,1.6544,0.5515,0.4289], /*Apple*/
[0.0613,1.2868,0.2451,0,0.7353,0.6127,0.1225,0], /*Blackberry*/
[0.1225,0.3676,2.5735,0.1225,2.2672,1.8382,0.7353,0.0613], /*HTC*/
[0.0613,0.1225,0.2451,0.6127,1.348,0.9804,0.3676,0.5515], /*LG*/
[0.2451,0.3064,0.1838,0.6127,14.951,1.8382,0.4289,1.777], /*Nokia*/
[1.4706,1.8382,1.777,2.3897,12.2549,17.8922,2.2059,1.7157], /*Samsung*/
[0.0613,0.2451,0.5515,0.2451,1.348,0.7966,1.777,0.3064], /*Sony*/
[0,0,0.1225,0.3064,1.1642,0.6127,0.4902,1.2868] /*Other*/
];
var colors = ["#C4C4C4","#000000","#69B40F","#C8125C","#008FC8","#10218B","#134B24","#737373"];
var chord = d3.layout.chord()
.padding(.04)
.sortSubgroups(d3.descending)
.sortChords(d3.descending)
.matrix(matrix);
var width = 500,
height = 500,
innerRadius = Math.min(width, height) * .39,
outerRadius = innerRadius * 1.09;
var fill = d3.scale.ordinal()
.domain(d3.range(NameProvider.length))
.range(colors);
var arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius);
var svg_LY = d3.select("#chart_lastYear").append("svg:svg")
.attr("width", width+60)
.attr("height", height+80)
.append("svg:g")
.attr("transform", "translate(" + (width / 2 + 30) + "," + (height / 2 + 75) + ")");
/*A label for the year*/
var title = svg_LY.append("text")
.attr("class", "years")
.attr("transform", "translate(" + 0 + "," + -295 + ")")
.text(2013);
/*//////////////////////////////////////////////////////////
////////////////// Draw outer Arcs /////////////////////////
//////////////////////////////////////////////////////////*/
var g = svg_LY.selectAll("g.group")
.data(chord.groups)
.enter().append("svg:g")
.attr("class", "group")
.on("mouseover", fade(.02))
.on("mouseout", fade(.80));
g.append("svg:path")
.style("stroke", function(d) { return fill(d.index); })
.style("fill", function(d) { return fill(d.index); })
.attr("d", arc);
/*//////////////////////////////////////////////////////////
////////////////// Append Ticks ////////////////////////////
//////////////////////////////////////////////////////////*/
var ticks = svg_LY.append("svg:g").selectAll("g.ticks")
.data(chord.groups)
.enter().append("svg:g").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)";
});
ticks.append("svg:line")
.attr("x1", 1)
.attr("y1", 0)
.attr("x2", 4)
.attr("y2", 0)
.style("stroke", "#000");
ticks.append("svg:text")
.attr("x", 8)
.attr("dy", ".35em")
.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; })
.style("font-size", "10px")
.text(function(d) { return d.label; });
/*//////////////////////////////////////////////////////////
////////////////// Append Names ////////////////////////////
//////////////////////////////////////////////////////////*/
g.append("svg:text")
.each(function(d) { d.angle = (d.startAngle + d.endAngle) / 2; })
.attr("dy", ".35em")
.attr("class", "titles_LY")
.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 + 50) + ")"
+ (d.angle > Math.PI ? "rotate(180)" : "");
})
.text(function(d,i) { return NameProvider[i]; });
/*//////////////////////////////////////////////////////////
////////////////// Draw inner chords ///////////////////////
//////////////////////////////////////////////////////////*/
svg_LY.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));
/*//////////////////////////////////////////////////////////
////////////////// Extra Functions /////////////////////////
//////////////////////////////////////////////////////////*/
/*Returns an event handler for fading a given chord group*/
function fade(opacity) {
return function(d, i) {
svg_LY.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*/
</script>
<!-- The small 2014 Chord Diagram -->
<script>
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*/
[0.1107,1.8272,0,0.4983,1.1074,1.052,0.2215,0.4983], /*HTC*/
[0.0554,0.2769,0.2215,0.2215,0.3876,0.8306,0.0554,0.3322], /*Huawei*/
[0.0554,0.1107,0.0554,1.2182,1.1628,0.6645,0.4983,1.052], /*LG*/
[0.2215,0.443,0,0.2769,10.4097,1.2182,0.4983,2.8239], /*Nokia*/
[1.1628,2.6024,0,1.3843,8.7486,16.8328,1.7165,5.5925], /*Samsung*/
[0.0554,0.4983,0,0.3322,0.443,0.8859,1.7719,0.443], /*Sony*/
[0.2215,0.7198,0,0.3322,1.6611,1.495,0.1107,5.4264] /*Other*/
];
var colors = ["#C4C4C4","#69B40F","#EC1D25","#C8125C","#008FC8","#10218B","#134B24","#737373"];
var chord = d3.layout.chord()
.padding(.04)
.sortSubgroups(d3.descending)
.sortChords(d3.descending)
.matrix(matrix);
var width = 500,
height = 500,
innerRadius = Math.min(width, height) * .39,
outerRadius = innerRadius * 1.09;
var fill = d3.scale.ordinal()
.domain(d3.range(NameProvider.length))
.range(colors);
var arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius);
var svg_TY = d3.select("#chart_thisYear").append("svg:svg")
.attr("width", width+60)
.attr("height", height+80)
.append("svg:g")
.attr("transform", "translate(" + (width / 2 + 20) + "," + (height / 2 + 75) + ")");
/*A label for the year*/
var title = svg_TY.append("text")
.attr("class", "years")
.attr("transform", "translate(" + 0 + "," + -295 + ")")
.text(2014);
/*//////////////////////////////////////////////////////////
////////////////// Draw outer Arcs /////////////////////////
//////////////////////////////////////////////////////////*/
var g = svg_TY.selectAll("g.group")
.data(chord.groups)
.enter().append("svg:g")
.attr("class", "group")
.on("mouseover", fade(.02))
.on("mouseout", fade(.80));
g.append("svg:path")
.style("stroke", function(d) { return fill(d.index); })
.style("fill", function(d) { return fill(d.index); })
.attr("d", arc);
/*//////////////////////////////////////////////////////////
////////////////// Append Ticks ////////////////////////////
//////////////////////////////////////////////////////////*/
var ticks = svg_TY.append("svg:g").selectAll("g.ticks")
.data(chord.groups)
.enter().append("svg:g").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)";
});
ticks.append("svg:line")
.attr("x1", 1)
.attr("y1", 0)
.attr("x2", 4)
.attr("y2", 0)
.style("stroke", "#000");
ticks.append("svg:text")
.attr("x", 8)
.attr("dy", ".35em")
.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; })
.style("font-size", "10px")
.text(function(d) { return d.label; });
/*//////////////////////////////////////////////////////////
////////////////// Append Names ////////////////////////////
//////////////////////////////////////////////////////////*/
g.append("svg:text")
.each(function(d) { d.angle = (d.startAngle + d.endAngle) / 2; })
.attr("dy", ".35em")
.attr("class", "titles_LY")
.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 + 50) + ")"
+ (d.angle > Math.PI ? "rotate(180)" : "");
})
.text(function(d,i) { return NameProvider[i]; });
/*//////////////////////////////////////////////////////////
////////////////// Draw inner chords ///////////////////////
//////////////////////////////////////////////////////////*/
svg_TY.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));
/*//////////////////////////////////////////////////////////
////////////////// Extra Functions /////////////////////////
//////////////////////////////////////////////////////////*/
/*Returns an event handler for fading a given chord group*/
function fade(opacity) {
return function(d, i) {
svg_TY.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*/
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment