Laura Wagner commited on
Commit
7103328
·
1 Parent(s): d9c29ce

adjusted d3js code

Browse files
jupyter_notebooks/Section_2-3-4__Figure_8b_sunburst_profession.ipynb CHANGED
@@ -9,7 +9,7 @@
9
  },
10
  {
11
  "cell_type": "code",
12
- "execution_count": 13,
13
  "metadata": {},
14
  "outputs": [
15
  {
@@ -31,7 +31,7 @@
31
  "sunburst_path = current_dir.parent / \"public/json/sunburst_countries_A.json\"\n",
32
  "\n",
33
  "# Load consensus CSV\n",
34
- "consensus_file = current_dir.parent / \"data/CSV/improved_consensus.csv\"\n",
35
  "df = pd.read_csv(consensus_file)\n",
36
  "\n",
37
  "# ============================================================\n",
@@ -84,20 +84,11 @@
84
  " }\n",
85
  " return mapping.get(x, \"Other\")\n",
86
  "\n",
87
- "df[\"profession_clean\"] = df[\"consensus_profession\"].apply(normalize_profession)\n",
88
  "\n",
89
- "# Only keep the top 7 professions (excluding Other)\n",
90
- "top_prof = (\n",
91
- " df[df[\"profession_clean\"] != \"Other\"][\"profession_clean\"]\n",
92
- " .value_counts()\n",
93
- " .nlargest(7)\n",
94
- " .index.tolist()\n",
95
- ")\n",
96
  "\n",
97
- "# Re-limit professions, everything else → Other\n",
98
- "df[\"profession_limited\"] = df[\"profession_clean\"].apply(\n",
99
- " lambda x: x if x in top_prof else \"Other\"\n",
100
- ")\n",
101
  "\n",
102
  "# ============================================================\n",
103
  "# 3. GROUP INTO SUNBURST STRUCTURE\n",
@@ -156,14 +147,14 @@
156
  },
157
  {
158
  "cell_type": "code",
159
- "execution_count": 14,
160
  "metadata": {},
161
  "outputs": [
162
  {
163
  "name": "stdout",
164
  "output_type": "stream",
165
  "text": [
166
- "✓ Filtered to 17356 records published on or before December 31, 2024\n",
167
  "✓ Saved sunburst_countries_A.json (2024 data only)\n"
168
  ]
169
  }
@@ -178,7 +169,7 @@
178
  "sunburst_path = current_dir.parent / \"public/json/sunburst_countries_A.json\"\n",
179
  "\n",
180
  "# Load consensus CSV\n",
181
- "consensus_file = current_dir.parent / \"data/CSV/improved_consensus.csv\"\n",
182
  "df = pd.read_csv(consensus_file)\n",
183
  "\n",
184
  "# ============================================================\n",
@@ -233,21 +224,26 @@
233
  " \"singer/musician\": \"Singer, Musician\",\n",
234
  " \"online personality\": \"Online Personality\",\n",
235
  " \"sports professional\": \"Sports Professional\",\n",
236
- " \"voice actor/asmr\": \"Voice Actor\", # ← fixed key\n",
237
- " \"public figure\": \"Public Figure\", # ← now its own category\n",
238
  " \"tv personality\": \"Other\",\n",
239
  " }\n",
240
  " return mapping.get(x, \"Other\")\n",
241
  "\n",
242
- "df[\"profession_clean\"] = df[\"consensus_profession\"].apply(normalize_profession)\n",
243
- "\n",
244
- "# Only keep the top 7 professions (excluding Other)\n",
245
- "top_prof = (\n",
246
- " df[df[\"profession_clean\"] != \"Other\"][\"profession_clean\"]\n",
247
- " .value_counts()\n",
248
- " .nlargest(7)\n",
249
- " .index.tolist()\n",
250
- ")\n",
 
 
 
 
 
251
  "\n",
252
  "# Re-limit professions, everything else → Other\n",
253
  "df[\"profession_limited\"] = df[\"profession_clean\"].apply(\n",
 
9
  },
10
  {
11
  "cell_type": "code",
12
+ "execution_count": 9,
13
  "metadata": {},
14
  "outputs": [
15
  {
 
31
  "sunburst_path = current_dir.parent / \"public/json/sunburst_countries_A.json\"\n",
32
  "\n",
33
  "# Load consensus CSV\n",
34
+ "consensus_file = current_dir.parent / \"data/CSV/analyzed_llm_agreement_consensus_va.csv\"\n",
35
  "df = pd.read_csv(consensus_file)\n",
36
  "\n",
37
  "# ============================================================\n",
 
84
  " }\n",
85
  " return mapping.get(x, \"Other\")\n",
86
  "\n",
87
+ "df[\"profession_clean\"] = df[\"consensus_primary_profession\"].apply(normalize_profession)\n",
88
  "\n",
 
 
 
 
 
 
 
89
  "\n",
90
+ "df[\"profession_limited\"] = df[\"profession_clean\"]\n",
91
+ "\n",
 
 
92
  "\n",
93
  "# ============================================================\n",
94
  "# 3. GROUP INTO SUNBURST STRUCTURE\n",
 
147
  },
148
  {
149
  "cell_type": "code",
150
+ "execution_count": 10,
151
  "metadata": {},
152
  "outputs": [
153
  {
154
  "name": "stdout",
155
  "output_type": "stream",
156
  "text": [
157
+ "✓ Filtered to 16059 records published on or before December 31, 2024\n",
158
  "✓ Saved sunburst_countries_A.json (2024 data only)\n"
159
  ]
160
  }
 
169
  "sunburst_path = current_dir.parent / \"public/json/sunburst_countries_A.json\"\n",
170
  "\n",
171
  "# Load consensus CSV\n",
172
+ "consensus_file = current_dir.parent / \"data/CSV/analyzed_llm_agreement_consensus_va.csv\"\n",
173
  "df = pd.read_csv(consensus_file)\n",
174
  "\n",
175
  "# ============================================================\n",
 
224
  " \"singer/musician\": \"Singer, Musician\",\n",
225
  " \"online personality\": \"Online Personality\",\n",
226
  " \"sports professional\": \"Sports Professional\",\n",
227
+ " \"voice actor/asmr\": \"Voice Actor\",\n",
228
+ " \"public figure\": \"Public Figure\",\n",
229
  " \"tv personality\": \"Other\",\n",
230
  " }\n",
231
  " return mapping.get(x, \"Other\")\n",
232
  "\n",
233
+ "df[\"profession_clean\"] = df[\"consensus_primary_profession\"].apply(normalize_profession)\n",
234
+ "\n",
235
+ "# Define top professions to keep\n",
236
+ "top_prof = [\n",
237
+ " \"Actor\",\n",
238
+ " \"Model\", \n",
239
+ " \"Adult Performer\",\n",
240
+ " \"Singer, Musician\",\n",
241
+ " \"Online Personality\",\n",
242
+ " \"Sports Professional\",\n",
243
+ " \"Voice Actor\",\n",
244
+ " \"Public Figure\",\n",
245
+ " \"Other\"\n",
246
+ "]\n",
247
  "\n",
248
  "# Re-limit professions, everything else → Other\n",
249
  "df[\"profession_limited\"] = df[\"profession_clean\"].apply(\n",
public/Figure_8a_barchart.html CHANGED
@@ -46,43 +46,65 @@
46
  <svg id="chart"></svg>
47
  <script src="https://d3js.org/d3.v6.min.js"></script>
48
  <script>
 
 
 
49
  const colorMap = {
50
  "Adult Performer": "#8A2BE2",
51
  "Model": "#DC143C",
52
  "Actor": "#FF7F50",
53
- "Performer": "magenta",
54
  "Singer, Musician": "wheat",
55
- "TV Personality": "#708090",
56
  "Sports Professional": "gold",
57
- "Public Figure": "maroon",
58
  "Voice Actor": "lightgreen",
59
  "Online Personality": "#4682B4",
60
  "Other": "#ccc"
61
  };
62
 
63
- const professionOrder = [
64
- "Adult Performer", "Actor", "Singer, Musician", "Model", "Online Personality", "Public Figure", "Sports Professional", "Voice Actor", "TV Personality", "Other"
65
- ];
66
-
67
  const genderOrder = ["Female", "Male", "Other"];
68
 
69
- d3.json("json/sunburst_gender_profession.json").then(data => {
70
- // Transform hierarchical data into flat array
 
 
 
71
  const flatData = [];
72
 
73
  data.children.forEach(gender => {
74
  if (gender.children) {
75
- gender.children.forEach(profession => {
76
  flatData.push({
77
  gender: gender.name,
78
- profession: profession.name,
79
- value: profession.value
80
  });
81
  });
82
  }
83
  });
84
 
85
- // Group by gender and calculate totals
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  const genderData = d3.rollup(
87
  flatData,
88
  v => ({
@@ -92,17 +114,19 @@ d3.json("json/sunburst_gender_profession.json").then(data => {
92
  d => d.gender
93
  );
94
 
95
- // Convert to array and sort by gender order
96
  const genders = Array.from(genderData.keys()).sort((a, b) => {
97
- const aIndex = genderOrder.indexOf(a);
98
- const bIndex = genderOrder.indexOf(b);
99
- return (aIndex === -1 ? Infinity : aIndex) - (bIndex === -1 ? Infinity : bIndex);
100
  });
101
 
102
- // Set up dimensions - responsive to window size
103
- const margin = {top: 40, right: 200, bottom: 150, left: 80};
104
- const width = Math.max(800, window.innerWidth - 100) - margin.left - margin.right;
105
- const height = 800 - margin.top - margin.bottom;
 
 
106
 
107
  const svg = d3.select("#chart")
108
  .attr("width", width + margin.left + margin.right)
@@ -110,7 +134,9 @@ d3.json("json/sunburst_gender_profession.json").then(data => {
110
  .append("g")
111
  .attr("transform", `translate(${margin.left},${margin.top})`);
112
 
113
- // Create stacked data
 
 
114
  const stack = d3.stack()
115
  .keys(professionOrder)
116
  .value((d, key) => {
@@ -120,7 +146,9 @@ d3.json("json/sunburst_gender_profession.json").then(data => {
120
 
121
  const series = stack(Array.from(genderData));
122
 
123
- // Scales
 
 
124
  const x = d3.scaleBand()
125
  .domain(genders)
126
  .range([0, width])
@@ -131,36 +159,27 @@ d3.json("json/sunburst_gender_profession.json").then(data => {
131
  .nice()
132
  .range([height, 0]);
133
 
134
- // X axis
135
  svg.append("g")
136
- .attr("class", "axis")
137
  .attr("transform", `translate(0,${height})`)
138
  .call(d3.axisBottom(x))
139
  .selectAll("text")
140
- .attr("transform", "rotate(-90)")
141
- .style("text-anchor", "end")
142
- .style("font-size", "11px")
143
  .style("font-weight", "bold")
144
- .attr("dx", "-0.5em")
145
- .attr("dy", "-0.5em");
146
 
147
- // Y axis
148
  svg.append("g")
149
- .attr("class", "axis")
150
  .call(d3.axisLeft(y));
151
 
152
- // Y axis label
153
  svg.append("text")
154
  .attr("transform", "rotate(-90)")
155
  .attr("y", 0 - margin.left + 20)
156
- .attr("x", 0 - (height / 2))
157
- .attr("dy", "1em")
158
- .style("text-anchor", "middle")
159
- .style("font-size", "14px")
160
  .style("font-weight", "bold")
161
  .text("Count");
162
 
163
- // Draw bars
 
 
164
  svg.append("g")
165
  .selectAll("g")
166
  .data(series)
@@ -176,24 +195,18 @@ d3.json("json/sunburst_gender_profession.json").then(data => {
176
  .attr("width", x.bandwidth())
177
  .append("title")
178
  .text(d => {
179
- const profession = series.find(s => s.find(item => item === d))?.key;
180
- return `${d.data[0]} - ${profession}: ${d[1] - d[0]}`;
181
  });
182
 
183
- // Count total values per profession
184
- const professionCounts = {};
185
- flatData.forEach(d => {
186
- professionCounts[d.profession] = (professionCounts[d.profession] || 0) + d.value;
187
- });
188
-
189
- // Legend
190
  const legend = svg.append("g")
191
- .attr("class", "legend")
192
  .attr("transform", `translate(${width + 20}, 0)`);
193
 
194
  professionOrder.forEach((prof, i) => {
195
- const row = legend.append("g")
196
- .attr("transform", `translate(0,${i * 22})`);
197
 
198
  row.append("rect")
199
  .attr("width", 18)
@@ -204,41 +217,37 @@ d3.json("json/sunburst_gender_profession.json").then(data => {
204
  .attr("x", 24)
205
  .attr("y", 9)
206
  .attr("dy", "0.35em")
207
- .style("font-size", "12px")
208
  .text(`${prof} (${professionCounts[prof] || 0})`);
209
  });
210
 
211
- // Download button functionality
 
 
212
  document.getElementById("downloadBtn").addEventListener("click", () => {
213
  const svgNode = document.querySelector("#chart");
214
- const clonedSvg = svgNode.cloneNode(true);
215
 
216
- clonedSvg.setAttribute("xmlns", "http://www.w3.org/2000/svg");
217
 
218
- // Inline styles
219
- const allElements = clonedSvg.querySelectorAll("*");
220
- allElements.forEach(el => {
221
  const style = window.getComputedStyle(el);
222
- el.setAttribute("style", `
223
- font: ${style.font};
224
- fill: ${style.fill};
225
- stroke: ${style.stroke};
226
- stroke-width: ${style.strokeWidth};
227
- `);
228
  });
229
 
230
- const svgData = new XMLSerializer().serializeToString(clonedSvg);
231
- const svgBlob = new Blob([svgData], { type: "image/svg+xml;charset=utf-8" });
232
- const url = URL.createObjectURL(svgBlob);
233
  const a = document.createElement("a");
 
234
  a.href = url;
235
- a.download = "bar_chart_gender.svg";
236
- document.body.appendChild(a);
237
  a.click();
238
- document.body.removeChild(a);
239
  URL.revokeObjectURL(url);
240
  });
 
241
  });
242
  </script>
 
243
  </body>
244
- </html>
 
46
  <svg id="chart"></svg>
47
  <script src="https://d3js.org/d3.v6.min.js"></script>
48
  <script>
49
+ /* --------------------------------------------------------
50
+ 1. PROFESSION COLORS
51
+ -------------------------------------------------------- */
52
  const colorMap = {
53
  "Adult Performer": "#8A2BE2",
54
  "Model": "#DC143C",
55
  "Actor": "#FF7F50",
56
+ "Public Figure": "#20B2AA",
57
  "Singer, Musician": "wheat",
 
58
  "Sports Professional": "gold",
 
59
  "Voice Actor": "lightgreen",
60
  "Online Personality": "#4682B4",
61
  "Other": "#ccc"
62
  };
63
 
64
+ /* --------------------------------------------------------
65
+ 2. GENDER ORDER
66
+ -------------------------------------------------------- */
 
67
  const genderOrder = ["Female", "Male", "Other"];
68
 
69
+ /* --------------------------------------------------------
70
+ 3. LOAD JSON + TRANSFORM IT
71
+ -------------------------------------------------------- */
72
+ d3.json("json/sunburst_gender_A.json").then(data => {
73
+
74
  const flatData = [];
75
 
76
  data.children.forEach(gender => {
77
  if (gender.children) {
78
+ gender.children.forEach(prof => {
79
  flatData.push({
80
  gender: gender.name,
81
+ profession: prof.name,
82
+ value: prof.value
83
  });
84
  });
85
  }
86
  });
87
 
88
+ /* --------------------------------------------------------
89
+ 3a. CALCULATE PROFESSION ORDER BY TOTAL OCCURRENCE
90
+ -------------------------------------------------------- */
91
+ const professionCounts = {};
92
+ flatData.forEach(d => {
93
+ professionCounts[d.profession] = (professionCounts[d.profession] || 0) + d.value;
94
+ });
95
+
96
+ // Sort professions by count (descending), but put "Other" last
97
+ const professionOrder = Object.entries(professionCounts)
98
+ .sort((a, b) => {
99
+ // If either is "Other", it goes last
100
+ if (a[0] === "Other") return 1;
101
+ if (b[0] === "Other") return -1;
102
+ // Otherwise sort by count descending
103
+ return b[1] - a[1];
104
+ })
105
+ .map(entry => entry[0]);
106
+
107
+ // Group per gender
108
  const genderData = d3.rollup(
109
  flatData,
110
  v => ({
 
114
  d => d.gender
115
  );
116
 
117
+ // Sort according to gender ordering
118
  const genders = Array.from(genderData.keys()).sort((a, b) => {
119
+ const ai = genderOrder.indexOf(a);
120
+ const bi = genderOrder.indexOf(b);
121
+ return (ai === -1 ? Infinity : ai) - (bi === -1 ? Infinity : bi);
122
  });
123
 
124
+ /* --------------------------------------------------------
125
+ 4. SVG SETUP
126
+ -------------------------------------------------------- */
127
+ const margin = {top: 40, right: 200, bottom: 80, left: 80};
128
+ const width = 800 - margin.left - margin.right;
129
+ const height = 600 - margin.top - margin.bottom;
130
 
131
  const svg = d3.select("#chart")
132
  .attr("width", width + margin.left + margin.right)
 
134
  .append("g")
135
  .attr("transform", `translate(${margin.left},${margin.top})`);
136
 
137
+ /* --------------------------------------------------------
138
+ 5. STACKED DATA
139
+ -------------------------------------------------------- */
140
  const stack = d3.stack()
141
  .keys(professionOrder)
142
  .value((d, key) => {
 
146
 
147
  const series = stack(Array.from(genderData));
148
 
149
+ /* --------------------------------------------------------
150
+ 6. AXES
151
+ -------------------------------------------------------- */
152
  const x = d3.scaleBand()
153
  .domain(genders)
154
  .range([0, width])
 
159
  .nice()
160
  .range([height, 0]);
161
 
 
162
  svg.append("g")
 
163
  .attr("transform", `translate(0,${height})`)
164
  .call(d3.axisBottom(x))
165
  .selectAll("text")
166
+ .style("text-anchor", "middle")
 
 
167
  .style("font-weight", "bold")
168
+ .style("font-size", "14px");
 
169
 
 
170
  svg.append("g")
 
171
  .call(d3.axisLeft(y));
172
 
 
173
  svg.append("text")
174
  .attr("transform", "rotate(-90)")
175
  .attr("y", 0 - margin.left + 20)
176
+ .attr("x", 0 - height / 2)
 
 
 
177
  .style("font-weight", "bold")
178
  .text("Count");
179
 
180
+ /* --------------------------------------------------------
181
+ 7. DRAW BARS
182
+ -------------------------------------------------------- */
183
  svg.append("g")
184
  .selectAll("g")
185
  .data(series)
 
195
  .attr("width", x.bandwidth())
196
  .append("title")
197
  .text(d => {
198
+ const profKey = series.find(s => s.includes(d))?.key;
199
+ return `${d.data[0]} – ${profKey}: ${d[1] - d[0]}`;
200
  });
201
 
202
+ /* --------------------------------------------------------
203
+ 8. LEGEND (ordered by occurrence)
204
+ -------------------------------------------------------- */
 
 
 
 
205
  const legend = svg.append("g")
 
206
  .attr("transform", `translate(${width + 20}, 0)`);
207
 
208
  professionOrder.forEach((prof, i) => {
209
+ const row = legend.append("g").attr("transform", `translate(0,${i * 22})`);
 
210
 
211
  row.append("rect")
212
  .attr("width", 18)
 
217
  .attr("x", 24)
218
  .attr("y", 9)
219
  .attr("dy", "0.35em")
 
220
  .text(`${prof} (${professionCounts[prof] || 0})`);
221
  });
222
 
223
+ /* --------------------------------------------------------
224
+ 9. DOWNLOAD SVG BUTTON
225
+ -------------------------------------------------------- */
226
  document.getElementById("downloadBtn").addEventListener("click", () => {
227
  const svgNode = document.querySelector("#chart");
228
+ const clone = svgNode.cloneNode(true);
229
 
230
+ clone.setAttribute("xmlns", "http://www.w3.org/2000/svg");
231
 
232
+ const all = clone.querySelectorAll("*");
233
+ all.forEach(el => {
 
234
  const style = window.getComputedStyle(el);
235
+ el.setAttribute("style", `font:${style.font}; fill:${style.fill}; stroke:${style.stroke};`);
 
 
 
 
 
236
  });
237
 
238
+ const svgData = new XMLSerializer().serializeToString(clone);
239
+ const blob = new Blob([svgData], { type: "image/svg+xml;charset=utf-8" });
240
+ const url = URL.createObjectURL(blob);
241
  const a = document.createElement("a");
242
+
243
  a.href = url;
244
+ a.download = "gender_bar_chart.svg";
 
245
  a.click();
 
246
  URL.revokeObjectURL(url);
247
  });
248
+
249
  });
250
  </script>
251
+
252
  </body>
253
+ </html>
public/Figure_8b_barchart.html CHANGED
@@ -47,13 +47,13 @@
47
  <script src="https://d3js.org/d3.v6.min.js"></script>
48
  <script>
49
  /* --------------------------------------------------------
50
- 1. PROFESSION COLORS + ORDER
51
  -------------------------------------------------------- */
52
  const colorMap = {
53
  "Adult Performer": "#8A2BE2",
54
  "Model": "#DC143C",
55
  "Actor": "#FF7F50",
56
- "Public Figure": "#20B2AA", // ← add this (or pick your color)
57
  "Singer, Musician": "wheat",
58
  "Sports Professional": "gold",
59
  "Voice Actor": "lightgreen",
@@ -61,60 +61,8 @@ const colorMap = {
61
  "Other": "#ccc"
62
  };
63
 
64
- // IMPORTANT → this now matches exactly the categories
65
- // that your updated Python script produces.
66
- const professionOrder = [
67
- "Actor",
68
- "Adult Performer",
69
- "Singer, Musician",
70
- "Model",
71
- "Online Personality",
72
- "Sports Professional",
73
- "Voice Actor",
74
- "Public Figure",
75
- "Other"
76
- ];
77
-
78
- //#DC143C
79
-
80
- /* --------------------------------------------------------
81
- 2. COUNTRY ORDER (unchanged)
82
- -------------------------------------------------------- */
83
- const manualOrder = [
84
- "United States",
85
- "Japan",
86
- "United Kingdom",
87
- "South Korea",
88
- "Russia",
89
- "India",
90
- "France",
91
- "China",
92
- "Canada",
93
- "Brazil",
94
- "Germany",
95
- "Italy",
96
- "Australia",
97
- "Spain",
98
- "Ukraine",
99
- "Turkey",
100
- "Netherlands",
101
- "Indonesia",
102
- "Poland",
103
- "Czech Republic",
104
- "Argentina",
105
- "Sweden",
106
- "Mexico",
107
- "Taiwan",
108
- "Thailand",
109
- "Ireland",
110
- "Philippines",
111
- "Hong Kong",
112
- "Macau",
113
- "Other"
114
- ];
115
-
116
  /* --------------------------------------------------------
117
- 3. LOAD JSON + TRANSFORM IT
118
  -------------------------------------------------------- */
119
  d3.json("json/sunburst_countries_A.json").then(data => {
120
 
@@ -132,7 +80,26 @@ d3.json("json/sunburst_countries_A.json").then(data => {
132
  }
133
  });
134
 
135
- // Group per country
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  const countryData = d3.rollup(
137
  flatData,
138
  v => ({
@@ -142,15 +109,23 @@ d3.json("json/sunburst_countries_A.json").then(data => {
142
  d => d.country
143
  );
144
 
145
- // Sort according to manual ordering
146
- const countries = Array.from(countryData.keys()).sort((a, b) => {
147
- const ai = manualOrder.indexOf(a);
148
- const bi = manualOrder.indexOf(b);
149
- return (ai === -1 ? Infinity : ai) - (bi === -1 ? Infinity : bi);
150
- });
 
 
 
 
 
 
 
 
151
 
152
  /* --------------------------------------------------------
153
- 4. SVG SETUP
154
  -------------------------------------------------------- */
155
  const margin = {top: 40, right: 200, bottom: 150, left: 80};
156
  const width = Math.max(800, window.innerWidth - 100) - margin.left - margin.right;
@@ -163,7 +138,7 @@ d3.json("json/sunburst_countries_A.json").then(data => {
163
  .attr("transform", `translate(${margin.left},${margin.top})`);
164
 
165
  /* --------------------------------------------------------
166
- 5. STACKED DATA
167
  -------------------------------------------------------- */
168
  const stack = d3.stack()
169
  .keys(professionOrder)
@@ -175,10 +150,8 @@ d3.json("json/sunburst_countries_A.json").then(data => {
175
  const series = stack(Array.from(countryData));
176
 
177
  /* --------------------------------------------------------
178
- 6. AXES
179
  -------------------------------------------------------- */
180
- const topCountries = countries.slice(0, 25);
181
-
182
  const x = d3.scaleBand()
183
  .domain(topCountries)
184
  .range([0, width])
@@ -210,7 +183,7 @@ d3.json("json/sunburst_countries_A.json").then(data => {
210
  .text("Count");
211
 
212
  /* --------------------------------------------------------
213
- 7. DRAW BARS
214
  -------------------------------------------------------- */
215
  svg.append("g")
216
  .selectAll("g")
@@ -232,13 +205,8 @@ d3.json("json/sunburst_countries_A.json").then(data => {
232
  });
233
 
234
  /* --------------------------------------------------------
235
- 8. LEGEND
236
  -------------------------------------------------------- */
237
- const professionCounts = {};
238
- flatData.forEach(d => {
239
- professionCounts[d.profession] = (professionCounts[d.profession] || 0) + d.value;
240
- });
241
-
242
  const legend = svg.append("g")
243
  .attr("transform", `translate(${width + 20}, 0)`);
244
 
@@ -247,18 +215,18 @@ d3.json("json/sunburst_countries_A.json").then(data => {
247
 
248
  row.append("rect")
249
  .attr("width", 18)
250
- .attr("height", 18)
251
- .attr("fill", colorMap[prof]);
252
 
253
  row.append("text")
254
- .attr("x", 24)
255
- .attr("y", 9)
256
- .attr("dy", "0.35em")
257
  .text(`${prof} (${professionCounts[prof] || 0})`);
258
  });
259
 
260
  /* --------------------------------------------------------
261
- 9. DOWNLOAD SVG BUTTON
262
  -------------------------------------------------------- */
263
  document.getElementById("downloadBtn").addEventListener("click", () => {
264
  const svgNode = document.querySelector("#chart");
@@ -286,5 +254,6 @@ d3.json("json/sunburst_countries_A.json").then(data => {
286
  });
287
  </script>
288
 
 
289
  </body>
290
- </html>
 
47
  <script src="https://d3js.org/d3.v6.min.js"></script>
48
  <script>
49
  /* --------------------------------------------------------
50
+ 1. PROFESSION COLORS
51
  -------------------------------------------------------- */
52
  const colorMap = {
53
  "Adult Performer": "#8A2BE2",
54
  "Model": "#DC143C",
55
  "Actor": "#FF7F50",
56
+ "Public Figure": "#20B2AA",
57
  "Singer, Musician": "wheat",
58
  "Sports Professional": "gold",
59
  "Voice Actor": "lightgreen",
 
61
  "Other": "#ccc"
62
  };
63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  /* --------------------------------------------------------
65
+ 2. LOAD JSON + TRANSFORM IT
66
  -------------------------------------------------------- */
67
  d3.json("json/sunburst_countries_A.json").then(data => {
68
 
 
80
  }
81
  });
82
 
83
+ /* --------------------------------------------------------
84
+ 3. CALCULATE PROFESSION ORDER (Other last)
85
+ -------------------------------------------------------- */
86
+ const professionCounts = {};
87
+ flatData.forEach(d => {
88
+ professionCounts[d.profession] = (professionCounts[d.profession] || 0) + d.value;
89
+ });
90
+
91
+ const professionOrder = Object.entries(professionCounts)
92
+ .filter(entry => entry[0] !== "Other")
93
+ .sort((a, b) => b[1] - a[1])
94
+ .map(entry => entry[0]);
95
+
96
+ if (professionCounts["Other"]) {
97
+ professionOrder.push("Other");
98
+ }
99
+
100
+ /* --------------------------------------------------------
101
+ 4. GROUP DATA BY COUNTRY
102
+ -------------------------------------------------------- */
103
  const countryData = d3.rollup(
104
  flatData,
105
  v => ({
 
109
  d => d.country
110
  );
111
 
112
+ /* --------------------------------------------------------
113
+ 5. SORT COUNTRIES BY TOTAL — but put "Other" last
114
+ -------------------------------------------------------- */
115
+ let countries = Array.from(countryData.entries())
116
+ .sort((a, b) => b[1].total - a[1].total)
117
+ .map(d => d[0]);
118
+
119
+ // Move country named "Other" to the final position
120
+ countries = countries.filter(c => c !== "Other");
121
+ if (countryData.has("Other")) {
122
+ countries.push("Other");
123
+ }
124
+
125
+ const topCountries = countries.slice(0, 25);
126
 
127
  /* --------------------------------------------------------
128
+ 6. SVG SETUP
129
  -------------------------------------------------------- */
130
  const margin = {top: 40, right: 200, bottom: 150, left: 80};
131
  const width = Math.max(800, window.innerWidth - 100) - margin.left - margin.right;
 
138
  .attr("transform", `translate(${margin.left},${margin.top})`);
139
 
140
  /* --------------------------------------------------------
141
+ 7. STACK LAYOUT
142
  -------------------------------------------------------- */
143
  const stack = d3.stack()
144
  .keys(professionOrder)
 
150
  const series = stack(Array.from(countryData));
151
 
152
  /* --------------------------------------------------------
153
+ 8. AXES
154
  -------------------------------------------------------- */
 
 
155
  const x = d3.scaleBand()
156
  .domain(topCountries)
157
  .range([0, width])
 
183
  .text("Count");
184
 
185
  /* --------------------------------------------------------
186
+ 9. DRAW STACKED BARS
187
  -------------------------------------------------------- */
188
  svg.append("g")
189
  .selectAll("g")
 
205
  });
206
 
207
  /* --------------------------------------------------------
208
+ 10. LEGEND
209
  -------------------------------------------------------- */
 
 
 
 
 
210
  const legend = svg.append("g")
211
  .attr("transform", `translate(${width + 20}, 0)`);
212
 
 
215
 
216
  row.append("rect")
217
  .attr("width", 18)
218
+ .attr("height": 18)
219
+ .attr("fill": colorMap[prof]);
220
 
221
  row.append("text")
222
+ .attr("x": 24)
223
+ .attr("y": 9)
224
+ .attr("dy": "0.35em")
225
  .text(`${prof} (${professionCounts[prof] || 0})`);
226
  });
227
 
228
  /* --------------------------------------------------------
229
+ 11. DOWNLOAD SVG BUTTON
230
  -------------------------------------------------------- */
231
  document.getElementById("downloadBtn").addEventListener("click", () => {
232
  const svgNode = document.querySelector("#chart");
 
254
  });
255
  </script>
256
 
257
+
258
  </body>
259
+ </html>
public/json/sunburst_countries_A.json CHANGED
@@ -6,39 +6,39 @@
6
  "children": [
7
  {
8
  "name": "Actor",
9
- "value": 3816
10
  },
11
  {
12
  "name": "Adult Performer",
13
- "value": 385
14
  },
15
  {
16
  "name": "Model",
17
- "value": 263
18
  },
19
  {
20
  "name": "Online Personality",
21
- "value": 177
22
  },
23
  {
24
  "name": "Public Figure",
25
- "value": 210
26
  },
27
  {
28
  "name": "Singer, Musician",
29
- "value": 681
30
  },
31
  {
32
  "name": "Sports Professional",
33
- "value": 92
34
  },
35
  {
36
  "name": "Voice Actor",
37
- "value": 2
38
  },
39
  {
40
  "name": "Other",
41
- "value": 86
42
  }
43
  ]
44
  },
@@ -47,39 +47,39 @@
47
  "children": [
48
  {
49
  "name": "Actor",
50
- "value": 313
51
  },
52
  {
53
  "name": "Adult Performer",
54
- "value": 655
55
  },
56
  {
57
  "name": "Model",
58
- "value": 249
59
  },
60
  {
61
  "name": "Online Personality",
62
- "value": 105
63
  },
64
  {
65
  "name": "Public Figure",
66
- "value": 29
67
  },
68
  {
69
  "name": "Singer, Musician",
70
- "value": 429
71
  },
72
  {
73
  "name": "Sports Professional",
74
- "value": 14
75
  },
76
  {
77
  "name": "Voice Actor",
78
- "value": 332
79
  },
80
  {
81
  "name": "Other",
82
- "value": 11
83
  }
84
  ]
85
  },
@@ -88,113 +88,105 @@
88
  "children": [
89
  {
90
  "name": "Actor",
91
- "value": 995
92
  },
93
  {
94
  "name": "Adult Performer",
95
- "value": 41
96
  },
97
  {
98
  "name": "Model",
99
- "value": 81
100
  },
101
  {
102
  "name": "Online Personality",
103
- "value": 16
104
  },
105
  {
106
  "name": "Public Figure",
107
- "value": 41
108
  },
109
  {
110
  "name": "Singer, Musician",
111
- "value": 147
112
  },
113
  {
114
  "name": "Sports Professional",
115
- "value": 17
116
- },
117
- {
118
- "name": "Voice Actor",
119
- "value": 2
120
  },
121
  {
122
  "name": "Other",
123
- "value": 43
124
  }
125
  ]
126
  },
127
  {
128
- "name": "South Korea",
129
  "children": [
130
  {
131
  "name": "Actor",
132
- "value": 186
133
  },
134
  {
135
  "name": "Adult Performer",
136
- "value": 10
137
  },
138
  {
139
  "name": "Model",
140
- "value": 81
141
  },
142
  {
143
  "name": "Online Personality",
144
- "value": 46
145
  },
146
  {
147
  "name": "Public Figure",
148
- "value": 2
149
  },
150
  {
151
  "name": "Singer, Musician",
152
- "value": 1047
153
  },
154
  {
155
  "name": "Sports Professional",
156
- "value": 2
157
  },
158
  {
159
  "name": "Other",
160
- "value": 6
161
  }
162
  ]
163
  },
164
  {
165
- "name": "India",
166
  "children": [
167
  {
168
  "name": "Actor",
169
- "value": 666
170
  },
171
  {
172
  "name": "Adult Performer",
173
- "value": 8
174
  },
175
  {
176
  "name": "Model",
177
- "value": 22
178
  },
179
  {
180
  "name": "Online Personality",
181
- "value": 10
182
  },
183
  {
184
  "name": "Public Figure",
185
- "value": 7
186
  },
187
  {
188
  "name": "Singer, Musician",
189
- "value": 4
190
- },
191
- {
192
- "name": "Sports Professional",
193
- "value": 4
194
  },
195
  {
196
  "name": "Other",
197
- "value": 2
198
  }
199
  ]
200
  },
@@ -203,34 +195,30 @@
203
  "children": [
204
  {
205
  "name": "Actor",
206
- "value": 237
207
  },
208
  {
209
  "name": "Adult Performer",
210
- "value": 72
211
  },
212
  {
213
  "name": "Model",
214
- "value": 161
215
  },
216
  {
217
  "name": "Online Personality",
218
- "value": 174
219
  },
220
  {
221
  "name": "Public Figure",
222
- "value": 11
223
  },
224
  {
225
  "name": "Singer, Musician",
226
- "value": 55
227
  },
228
  {
229
  "name": "Sports Professional",
230
- "value": 2
231
- },
232
- {
233
- "name": "Other",
234
  "value": 1
235
  }
236
  ]
@@ -240,27 +228,27 @@
240
  "children": [
241
  {
242
  "name": "Actor",
243
- "value": 203
244
  },
245
  {
246
  "name": "Adult Performer",
247
- "value": 34
248
  },
249
  {
250
  "name": "Model",
251
- "value": 28
252
  },
253
  {
254
  "name": "Online Personality",
255
- "value": 16
256
  },
257
  {
258
  "name": "Public Figure",
259
- "value": 59
260
  },
261
  {
262
  "name": "Singer, Musician",
263
- "value": 36
264
  },
265
  {
266
  "name": "Sports Professional",
@@ -268,139 +256,139 @@
268
  },
269
  {
270
  "name": "Other",
271
- "value": 10
272
  }
273
  ]
274
  },
275
  {
276
- "name": "Canada",
277
  "children": [
278
  {
279
  "name": "Actor",
280
- "value": 245
281
  },
282
  {
283
  "name": "Adult Performer",
284
- "value": 8
285
  },
286
  {
287
  "name": "Model",
288
- "value": 12
289
  },
290
  {
291
  "name": "Online Personality",
292
- "value": 8
293
  },
294
  {
295
  "name": "Public Figure",
296
- "value": 17
297
  },
298
  {
299
  "name": "Singer, Musician",
300
- "value": 66
301
  },
302
  {
303
  "name": "Sports Professional",
304
- "value": 6
305
- },
306
- {
307
- "name": "Voice Actor",
308
- "value": 1
309
  },
310
  {
311
  "name": "Other",
312
- "value": 2
313
  }
314
  ]
315
  },
316
  {
317
- "name": "Russia",
318
  "children": [
319
  {
320
  "name": "Actor",
321
- "value": 31
322
  },
323
  {
324
  "name": "Adult Performer",
325
- "value": 101
326
  },
327
  {
328
  "name": "Model",
329
- "value": 68
330
  },
331
  {
332
  "name": "Online Personality",
333
- "value": 42
334
  },
335
  {
336
  "name": "Public Figure",
337
- "value": 44
338
  },
339
  {
340
  "name": "Singer, Musician",
341
- "value": 21
342
  },
343
  {
344
  "name": "Sports Professional",
345
- "value": 8
346
  },
347
  {
348
  "name": "Other",
349
- "value": 6
350
  }
351
  ]
352
  },
353
  {
354
- "name": "Brazil",
355
  "children": [
356
  {
357
  "name": "Actor",
358
- "value": 87
359
  },
360
  {
361
  "name": "Adult Performer",
362
- "value": 29
363
  },
364
  {
365
  "name": "Model",
366
- "value": 78
367
  },
368
  {
369
  "name": "Online Personality",
370
- "value": 27
371
  },
372
  {
373
  "name": "Public Figure",
374
- "value": 15
375
  },
376
  {
377
  "name": "Singer, Musician",
378
- "value": 33
379
  },
380
  {
381
  "name": "Sports Professional",
382
- "value": 6
 
 
 
 
383
  },
384
  {
385
  "name": "Other",
386
- "value": 14
387
  }
388
  ]
389
  },
390
  {
391
- "name": "Australia",
392
  "children": [
393
  {
394
  "name": "Actor",
395
- "value": 169
396
  },
397
  {
398
  "name": "Adult Performer",
399
- "value": 7
400
  },
401
  {
402
  "name": "Model",
403
- "value": 36
404
  },
405
  {
406
  "name": "Online Personality",
@@ -408,139 +396,139 @@
408
  },
409
  {
410
  "name": "Public Figure",
411
- "value": 3
412
  },
413
  {
414
  "name": "Singer, Musician",
415
- "value": 25
416
  },
417
  {
418
  "name": "Sports Professional",
419
- "value": 4
420
  },
421
  {
422
  "name": "Other",
423
- "value": 2
424
  }
425
  ]
426
  },
427
  {
428
- "name": "Germany",
429
  "children": [
430
  {
431
  "name": "Actor",
432
- "value": 47
433
  },
434
  {
435
  "name": "Adult Performer",
436
- "value": 14
437
  },
438
  {
439
  "name": "Model",
440
- "value": 41
441
  },
442
  {
443
  "name": "Online Personality",
444
- "value": 15
445
  },
446
  {
447
  "name": "Public Figure",
448
- "value": 44
449
  },
450
  {
451
  "name": "Singer, Musician",
452
- "value": 26
453
  },
454
  {
455
  "name": "Sports Professional",
456
- "value": 11
457
  },
458
  {
459
  "name": "Other",
460
- "value": 9
461
  }
462
  ]
463
  },
464
  {
465
- "name": "Italy",
466
  "children": [
467
  {
468
  "name": "Actor",
469
- "value": 66
470
  },
471
  {
472
  "name": "Adult Performer",
473
- "value": 16
474
  },
475
  {
476
  "name": "Model",
477
- "value": 25
478
  },
479
  {
480
  "name": "Online Personality",
481
- "value": 21
482
  },
483
  {
484
  "name": "Public Figure",
485
- "value": 19
486
  },
487
  {
488
  "name": "Singer, Musician",
489
- "value": 27
490
  },
491
  {
492
  "name": "Sports Professional",
493
- "value": 12
494
- },
495
- {
496
- "name": "Voice Actor",
497
- "value": 1
498
  },
499
  {
500
  "name": "Other",
501
- "value": 8
502
  }
503
  ]
504
  },
505
  {
506
- "name": "Ukraine",
507
  "children": [
508
  {
509
  "name": "Actor",
510
- "value": 11
511
  },
512
  {
513
  "name": "Adult Performer",
514
- "value": 70
515
  },
516
  {
517
  "name": "Model",
518
- "value": 19
519
  },
520
  {
521
  "name": "Online Personality",
522
- "value": 23
523
  },
524
  {
525
  "name": "Public Figure",
526
- "value": 12
527
  },
528
  {
529
  "name": "Singer, Musician",
530
- "value": 4
531
  },
532
  {
533
  "name": "Sports Professional",
534
- "value": 3
 
 
 
 
535
  }
536
  ]
537
  },
538
  {
539
- "name": "Spain",
540
  "children": [
541
  {
542
  "name": "Actor",
543
- "value": 60
544
  },
545
  {
546
  "name": "Adult Performer",
@@ -548,56 +536,56 @@
548
  },
549
  {
550
  "name": "Model",
551
- "value": 7
552
  },
553
  {
554
  "name": "Online Personality",
555
- "value": 17
556
  },
557
  {
558
  "name": "Public Figure",
559
- "value": 11
560
  },
561
  {
562
  "name": "Singer, Musician",
563
- "value": 12
564
  },
565
  {
566
  "name": "Sports Professional",
567
- "value": 6
568
  },
569
  {
570
  "name": "Other",
571
- "value": 15
572
  }
573
  ]
574
  },
575
  {
576
- "name": "Türkiye",
577
  "children": [
578
  {
579
  "name": "Actor",
580
- "value": 69
581
  },
582
  {
583
  "name": "Adult Performer",
584
- "value": 2
585
  },
586
  {
587
  "name": "Model",
588
- "value": 21
589
  },
590
  {
591
  "name": "Online Personality",
592
- "value": 11
593
  },
594
  {
595
  "name": "Public Figure",
596
- "value": 15
597
  },
598
  {
599
  "name": "Singer, Musician",
600
- "value": 8
601
  },
602
  {
603
  "name": "Sports Professional",
@@ -605,35 +593,43 @@
605
  },
606
  {
607
  "name": "Other",
608
- "value": 2
609
  }
610
  ]
611
  },
612
  {
613
- "name": "Thailand",
614
  "children": [
615
  {
616
  "name": "Actor",
617
- "value": 20
618
  },
619
  {
620
  "name": "Adult Performer",
621
- "value": 19
622
  },
623
  {
624
  "name": "Model",
625
- "value": 14
626
  },
627
  {
628
  "name": "Online Personality",
629
- "value": 33
 
 
 
 
630
  },
631
  {
632
  "name": "Singer, Musician",
633
- "value": 30
634
  },
635
  {
636
  "name": "Sports Professional",
 
 
 
 
637
  "value": 1
638
  }
639
  ]
@@ -643,35 +639,35 @@
643
  "children": [
644
  {
645
  "name": "Actor",
646
- "value": 25
647
  },
648
  {
649
  "name": "Adult Performer",
650
- "value": 7
651
  },
652
  {
653
  "name": "Model",
654
- "value": 19
655
  },
656
  {
657
  "name": "Online Personality",
658
- "value": 10
659
  },
660
  {
661
  "name": "Public Figure",
662
- "value": 32
663
  },
664
  {
665
  "name": "Singer, Musician",
666
- "value": 10
667
  },
668
  {
669
  "name": "Sports Professional",
670
- "value": 9
671
  },
672
  {
673
  "name": "Other",
674
- "value": 2
675
  }
676
  ]
677
  },
@@ -680,7 +676,15 @@
680
  "children": [
681
  {
682
  "name": "Actor",
683
- "value": 60
 
 
 
 
 
 
 
 
684
  },
685
  {
686
  "name": "Public Figure",
@@ -688,11 +692,11 @@
688
  },
689
  {
690
  "name": "Singer, Musician",
691
- "value": 10
692
  },
693
  {
694
  "name": "Sports Professional",
695
- "value": 7
696
  },
697
  {
698
  "name": "Other",
@@ -705,11 +709,11 @@
705
  "children": [
706
  {
707
  "name": "Actor",
708
- "value": 26
709
  },
710
  {
711
  "name": "Adult Performer",
712
- "value": 1
713
  },
714
  {
715
  "name": "Model",
@@ -717,19 +721,19 @@
717
  },
718
  {
719
  "name": "Online Personality",
720
- "value": 5
721
  },
722
  {
723
  "name": "Public Figure",
724
- "value": 20
725
  },
726
  {
727
  "name": "Singer, Musician",
728
- "value": 22
729
  },
730
  {
731
  "name": "Sports Professional",
732
- "value": 7
733
  },
734
  {
735
  "name": "Other",
@@ -744,132 +748,120 @@
744
  "name": "Actor",
745
  "value": 11
746
  },
747
- {
748
- "name": "Adult Performer",
749
- "value": 1
750
- },
751
  {
752
  "name": "Model",
753
- "value": 3
754
  },
755
  {
756
  "name": "Online Personality",
757
- "value": 4
758
  },
759
  {
760
  "name": "Public Figure",
761
- "value": 21
762
  },
763
  {
764
  "name": "Singer, Musician",
765
- "value": 28
766
  },
767
  {
768
  "name": "Sports Professional",
769
- "value": 11
770
  },
771
  {
772
  "name": "Other",
773
- "value": 3
774
  }
775
  ]
776
  },
777
  {
778
- "name": "Poland",
779
  "children": [
780
  {
781
  "name": "Actor",
782
- "value": 20
783
  },
784
  {
785
  "name": "Adult Performer",
786
- "value": 10
787
  },
788
  {
789
  "name": "Model",
790
- "value": 15
791
  },
792
  {
793
  "name": "Online Personality",
794
- "value": 7
795
  },
796
  {
797
  "name": "Public Figure",
798
- "value": 9
799
  },
800
  {
801
  "name": "Singer, Musician",
802
- "value": 7
803
- },
804
- {
805
- "name": "Sports Professional",
806
- "value": 7
807
  },
808
  {
809
  "name": "Other",
810
- "value": 2
811
  }
812
  ]
813
  },
814
  {
815
- "name": "Mexico",
816
  "children": [
817
  {
818
  "name": "Actor",
819
- "value": 54
820
  },
821
  {
822
  "name": "Adult Performer",
823
- "value": 3
824
  },
825
  {
826
  "name": "Model",
827
- "value": 7
828
  },
829
  {
830
  "name": "Online Personality",
831
- "value": 2
832
- },
833
- {
834
- "name": "Public Figure",
835
- "value": 1
836
- },
837
- {
838
- "name": "Singer, Musician",
839
  "value": 6
840
  },
841
  {
842
- "name": "Sports Professional",
843
- "value": 3
844
  }
845
  ]
846
  },
847
  {
848
- "name": "Indonesia",
849
  "children": [
850
  {
851
  "name": "Actor",
852
- "value": 11
853
  },
854
  {
855
  "name": "Adult Performer",
856
- "value": 5
857
  },
858
  {
859
  "name": "Model",
860
- "value": 15
861
  },
862
  {
863
  "name": "Online Personality",
864
- "value": 21
865
  },
866
  {
867
  "name": "Public Figure",
868
- "value": 4
869
  },
870
  {
871
  "name": "Singer, Musician",
872
- "value": 17
 
 
 
 
873
  },
874
  {
875
  "name": "Other",
@@ -878,30 +870,30 @@
878
  ]
879
  },
880
  {
881
- "name": "Taiwan",
882
  "children": [
883
  {
884
  "name": "Actor",
885
- "value": 13
886
  },
887
  {
888
  "name": "Adult Performer",
889
- "value": 9
890
  },
891
  {
892
  "name": "Model",
893
- "value": 11
894
  },
895
  {
896
  "name": "Online Personality",
897
- "value": 25
898
  },
899
  {
900
- "name": "Singer, Musician",
901
- "value": 14
902
  },
903
  {
904
- "name": "Other",
905
  "value": 2
906
  }
907
  ]
@@ -911,31 +903,31 @@
911
  "children": [
912
  {
913
  "name": "Actor",
914
- "value": 232
915
  },
916
  {
917
  "name": "Adult Performer",
918
- "value": 72
919
  },
920
  {
921
  "name": "Model",
922
- "value": 159
923
  },
924
  {
925
  "name": "Online Personality",
926
- "value": 55
927
  },
928
  {
929
  "name": "Public Figure",
930
- "value": 83
931
  },
932
  {
933
  "name": "Singer, Musician",
934
- "value": 99
935
  },
936
  {
937
  "name": "Sports Professional",
938
- "value": 48
939
  },
940
  {
941
  "name": "Other",
 
6
  "children": [
7
  {
8
  "name": "Actor",
9
+ "value": 1251
10
  },
11
  {
12
  "name": "Adult Performer",
13
+ "value": 298
14
  },
15
  {
16
  "name": "Model",
17
+ "value": 120
18
  },
19
  {
20
  "name": "Online Personality",
21
+ "value": 114
22
  },
23
  {
24
  "name": "Public Figure",
25
+ "value": 146
26
  },
27
  {
28
  "name": "Singer, Musician",
29
+ "value": 223
30
  },
31
  {
32
  "name": "Sports Professional",
33
+ "value": 78
34
  },
35
  {
36
  "name": "Voice Actor",
37
+ "value": 4
38
  },
39
  {
40
  "name": "Other",
41
+ "value": 64
42
  }
43
  ]
44
  },
 
47
  "children": [
48
  {
49
  "name": "Actor",
50
+ "value": 201
51
  },
52
  {
53
  "name": "Adult Performer",
54
+ "value": 483
55
  },
56
  {
57
  "name": "Model",
58
+ "value": 180
59
  },
60
  {
61
  "name": "Online Personality",
62
+ "value": 69
63
  },
64
  {
65
  "name": "Public Figure",
66
+ "value": 28
67
  },
68
  {
69
  "name": "Singer, Musician",
70
+ "value": 301
71
  },
72
  {
73
  "name": "Sports Professional",
74
+ "value": 10
75
  },
76
  {
77
  "name": "Voice Actor",
78
+ "value": 255
79
  },
80
  {
81
  "name": "Other",
82
+ "value": 9
83
  }
84
  ]
85
  },
 
88
  "children": [
89
  {
90
  "name": "Actor",
91
+ "value": 302
92
  },
93
  {
94
  "name": "Adult Performer",
95
+ "value": 33
96
  },
97
  {
98
  "name": "Model",
99
+ "value": 36
100
  },
101
  {
102
  "name": "Online Personality",
103
+ "value": 14
104
  },
105
  {
106
  "name": "Public Figure",
107
+ "value": 30
108
  },
109
  {
110
  "name": "Singer, Musician",
111
+ "value": 77
112
  },
113
  {
114
  "name": "Sports Professional",
115
+ "value": 11
 
 
 
 
116
  },
117
  {
118
  "name": "Other",
119
+ "value": 31
120
  }
121
  ]
122
  },
123
  {
124
+ "name": "India",
125
  "children": [
126
  {
127
  "name": "Actor",
128
+ "value": 352
129
  },
130
  {
131
  "name": "Adult Performer",
132
+ "value": 5
133
  },
134
  {
135
  "name": "Model",
136
+ "value": 18
137
  },
138
  {
139
  "name": "Online Personality",
140
+ "value": 10
141
  },
142
  {
143
  "name": "Public Figure",
144
+ "value": 7
145
  },
146
  {
147
  "name": "Singer, Musician",
148
+ "value": 6
149
  },
150
  {
151
  "name": "Sports Professional",
152
+ "value": 5
153
  },
154
  {
155
  "name": "Other",
156
+ "value": 2
157
  }
158
  ]
159
  },
160
  {
161
+ "name": "South Korea",
162
  "children": [
163
  {
164
  "name": "Actor",
165
+ "value": 105
166
  },
167
  {
168
  "name": "Adult Performer",
169
+ "value": 4
170
  },
171
  {
172
  "name": "Model",
173
+ "value": 43
174
  },
175
  {
176
  "name": "Online Personality",
177
+ "value": 12
178
  },
179
  {
180
  "name": "Public Figure",
181
+ "value": 2
182
  },
183
  {
184
  "name": "Singer, Musician",
185
+ "value": 227
 
 
 
 
186
  },
187
  {
188
  "name": "Other",
189
+ "value": 6
190
  }
191
  ]
192
  },
 
195
  "children": [
196
  {
197
  "name": "Actor",
198
+ "value": 129
199
  },
200
  {
201
  "name": "Adult Performer",
202
+ "value": 30
203
  },
204
  {
205
  "name": "Model",
206
+ "value": 80
207
  },
208
  {
209
  "name": "Online Personality",
210
+ "value": 72
211
  },
212
  {
213
  "name": "Public Figure",
214
+ "value": 7
215
  },
216
  {
217
  "name": "Singer, Musician",
218
+ "value": 31
219
  },
220
  {
221
  "name": "Sports Professional",
 
 
 
 
222
  "value": 1
223
  }
224
  ]
 
228
  "children": [
229
  {
230
  "name": "Actor",
231
+ "value": 118
232
  },
233
  {
234
  "name": "Adult Performer",
235
+ "value": 39
236
  },
237
  {
238
  "name": "Model",
239
+ "value": 17
240
  },
241
  {
242
  "name": "Online Personality",
243
+ "value": 18
244
  },
245
  {
246
  "name": "Public Figure",
247
+ "value": 44
248
  },
249
  {
250
  "name": "Singer, Musician",
251
+ "value": 28
252
  },
253
  {
254
  "name": "Sports Professional",
 
256
  },
257
  {
258
  "name": "Other",
259
+ "value": 14
260
  }
261
  ]
262
  },
263
  {
264
+ "name": "Russia",
265
  "children": [
266
  {
267
  "name": "Actor",
268
+ "value": 33
269
  },
270
  {
271
  "name": "Adult Performer",
272
+ "value": 75
273
  },
274
  {
275
  "name": "Model",
276
+ "value": 63
277
  },
278
  {
279
  "name": "Online Personality",
280
+ "value": 31
281
  },
282
  {
283
  "name": "Public Figure",
284
+ "value": 32
285
  },
286
  {
287
  "name": "Singer, Musician",
288
+ "value": 23
289
  },
290
  {
291
  "name": "Sports Professional",
292
+ "value": 7
 
 
 
 
293
  },
294
  {
295
  "name": "Other",
296
+ "value": 6
297
  }
298
  ]
299
  },
300
  {
301
+ "name": "Brazil",
302
  "children": [
303
  {
304
  "name": "Actor",
305
+ "value": 68
306
  },
307
  {
308
  "name": "Adult Performer",
309
+ "value": 32
310
  },
311
  {
312
  "name": "Model",
313
+ "value": 56
314
  },
315
  {
316
  "name": "Online Personality",
317
+ "value": 19
318
  },
319
  {
320
  "name": "Public Figure",
321
+ "value": 10
322
  },
323
  {
324
  "name": "Singer, Musician",
325
+ "value": 16
326
  },
327
  {
328
  "name": "Sports Professional",
329
+ "value": 6
330
  },
331
  {
332
  "name": "Other",
333
+ "value": 11
334
  }
335
  ]
336
  },
337
  {
338
+ "name": "Italy",
339
  "children": [
340
  {
341
  "name": "Actor",
342
+ "value": 40
343
  },
344
  {
345
  "name": "Adult Performer",
346
+ "value": 13
347
  },
348
  {
349
  "name": "Model",
350
+ "value": 29
351
  },
352
  {
353
  "name": "Online Personality",
354
+ "value": 18
355
  },
356
  {
357
  "name": "Public Figure",
358
+ "value": 25
359
  },
360
  {
361
  "name": "Singer, Musician",
362
+ "value": 24
363
  },
364
  {
365
  "name": "Sports Professional",
366
+ "value": 10
367
+ },
368
+ {
369
+ "name": "Voice Actor",
370
+ "value": 1
371
  },
372
  {
373
  "name": "Other",
374
+ "value": 6
375
  }
376
  ]
377
  },
378
  {
379
+ "name": "Germany",
380
  "children": [
381
  {
382
  "name": "Actor",
383
+ "value": 33
384
  },
385
  {
386
  "name": "Adult Performer",
387
+ "value": 18
388
  },
389
  {
390
  "name": "Model",
391
+ "value": 29
392
  },
393
  {
394
  "name": "Online Personality",
 
396
  },
397
  {
398
  "name": "Public Figure",
399
+ "value": 28
400
  },
401
  {
402
  "name": "Singer, Musician",
403
+ "value": 22
404
  },
405
  {
406
  "name": "Sports Professional",
407
+ "value": 9
408
  },
409
  {
410
  "name": "Other",
411
+ "value": 12
412
  }
413
  ]
414
  },
415
  {
416
+ "name": "Canada",
417
  "children": [
418
  {
419
  "name": "Actor",
420
+ "value": 78
421
  },
422
  {
423
  "name": "Adult Performer",
424
+ "value": 9
425
  },
426
  {
427
  "name": "Model",
428
+ "value": 10
429
  },
430
  {
431
  "name": "Online Personality",
432
+ "value": 11
433
  },
434
  {
435
  "name": "Public Figure",
436
+ "value": 14
437
  },
438
  {
439
  "name": "Singer, Musician",
440
+ "value": 24
441
  },
442
  {
443
  "name": "Sports Professional",
444
+ "value": 4
445
  },
446
  {
447
  "name": "Other",
448
+ "value": 1
449
  }
450
  ]
451
  },
452
  {
453
+ "name": "Türkiye",
454
  "children": [
455
  {
456
  "name": "Actor",
457
+ "value": 77
458
  },
459
  {
460
  "name": "Adult Performer",
461
+ "value": 2
462
  },
463
  {
464
  "name": "Model",
465
+ "value": 23
466
  },
467
  {
468
  "name": "Online Personality",
469
+ "value": 12
470
  },
471
  {
472
  "name": "Public Figure",
473
+ "value": 14
474
  },
475
  {
476
  "name": "Singer, Musician",
477
+ "value": 7
478
  },
479
  {
480
  "name": "Sports Professional",
481
+ "value": 4
 
 
 
 
482
  },
483
  {
484
  "name": "Other",
485
+ "value": 2
486
  }
487
  ]
488
  },
489
  {
490
+ "name": "Poland",
491
  "children": [
492
  {
493
  "name": "Actor",
494
+ "value": 18
495
  },
496
  {
497
  "name": "Adult Performer",
498
+ "value": 8
499
  },
500
  {
501
  "name": "Model",
502
+ "value": 14
503
  },
504
  {
505
  "name": "Online Personality",
506
+ "value": 21
507
  },
508
  {
509
  "name": "Public Figure",
510
+ "value": 8
511
  },
512
  {
513
  "name": "Singer, Musician",
514
+ "value": 44
515
  },
516
  {
517
  "name": "Sports Professional",
518
+ "value": 9
519
+ },
520
+ {
521
+ "name": "Other",
522
+ "value": 2
523
  }
524
  ]
525
  },
526
  {
527
+ "name": "Australia",
528
  "children": [
529
  {
530
  "name": "Actor",
531
+ "value": 52
532
  },
533
  {
534
  "name": "Adult Performer",
 
536
  },
537
  {
538
  "name": "Model",
539
+ "value": 17
540
  },
541
  {
542
  "name": "Online Personality",
543
+ "value": 7
544
  },
545
  {
546
  "name": "Public Figure",
547
+ "value": 1
548
  },
549
  {
550
  "name": "Singer, Musician",
551
+ "value": 9
552
  },
553
  {
554
  "name": "Sports Professional",
555
+ "value": 4
556
  },
557
  {
558
  "name": "Other",
559
+ "value": 1
560
  }
561
  ]
562
  },
563
  {
564
+ "name": "Spain",
565
  "children": [
566
  {
567
  "name": "Actor",
568
+ "value": 37
569
  },
570
  {
571
  "name": "Adult Performer",
572
+ "value": 10
573
  },
574
  {
575
  "name": "Model",
576
+ "value": 6
577
  },
578
  {
579
  "name": "Online Personality",
580
+ "value": 9
581
  },
582
  {
583
  "name": "Public Figure",
584
+ "value": 8
585
  },
586
  {
587
  "name": "Singer, Musician",
588
+ "value": 7
589
  },
590
  {
591
  "name": "Sports Professional",
 
593
  },
594
  {
595
  "name": "Other",
596
+ "value": 13
597
  }
598
  ]
599
  },
600
  {
601
+ "name": "Ukraine",
602
  "children": [
603
  {
604
  "name": "Actor",
605
+ "value": 3
606
  },
607
  {
608
  "name": "Adult Performer",
609
+ "value": 38
610
  },
611
  {
612
  "name": "Model",
613
+ "value": 17
614
  },
615
  {
616
  "name": "Online Personality",
617
+ "value": 17
618
+ },
619
+ {
620
+ "name": "Public Figure",
621
+ "value": 7
622
  },
623
  {
624
  "name": "Singer, Musician",
625
+ "value": 5
626
  },
627
  {
628
  "name": "Sports Professional",
629
+ "value": 2
630
+ },
631
+ {
632
+ "name": "Other",
633
  "value": 1
634
  }
635
  ]
 
639
  "children": [
640
  {
641
  "name": "Actor",
642
+ "value": 14
643
  },
644
  {
645
  "name": "Adult Performer",
646
+ "value": 8
647
  },
648
  {
649
  "name": "Model",
650
+ "value": 15
651
  },
652
  {
653
  "name": "Online Personality",
654
+ "value": 4
655
  },
656
  {
657
  "name": "Public Figure",
658
+ "value": 29
659
  },
660
  {
661
  "name": "Singer, Musician",
662
+ "value": 6
663
  },
664
  {
665
  "name": "Sports Professional",
666
+ "value": 8
667
  },
668
  {
669
  "name": "Other",
670
+ "value": 3
671
  }
672
  ]
673
  },
 
676
  "children": [
677
  {
678
  "name": "Actor",
679
+ "value": 32
680
+ },
681
+ {
682
+ "name": "Model",
683
+ "value": 1
684
+ },
685
+ {
686
+ "name": "Online Personality",
687
+ "value": 1
688
  },
689
  {
690
  "name": "Public Figure",
 
692
  },
693
  {
694
  "name": "Singer, Musician",
695
+ "value": 5
696
  },
697
  {
698
  "name": "Sports Professional",
699
+ "value": 1
700
  },
701
  {
702
  "name": "Other",
 
709
  "children": [
710
  {
711
  "name": "Actor",
712
+ "value": 11
713
  },
714
  {
715
  "name": "Adult Performer",
716
+ "value": 3
717
  },
718
  {
719
  "name": "Model",
 
721
  },
722
  {
723
  "name": "Online Personality",
724
+ "value": 4
725
  },
726
  {
727
  "name": "Public Figure",
728
+ "value": 10
729
  },
730
  {
731
  "name": "Singer, Musician",
732
+ "value": 12
733
  },
734
  {
735
  "name": "Sports Professional",
736
+ "value": 5
737
  },
738
  {
739
  "name": "Other",
 
748
  "name": "Actor",
749
  "value": 11
750
  },
 
 
 
 
751
  {
752
  "name": "Model",
753
+ "value": 4
754
  },
755
  {
756
  "name": "Online Personality",
757
+ "value": 2
758
  },
759
  {
760
  "name": "Public Figure",
761
+ "value": 14
762
  },
763
  {
764
  "name": "Singer, Musician",
765
+ "value": 16
766
  },
767
  {
768
  "name": "Sports Professional",
769
+ "value": 7
770
  },
771
  {
772
  "name": "Other",
773
+ "value": 2
774
  }
775
  ]
776
  },
777
  {
778
+ "name": "Indonesia",
779
  "children": [
780
  {
781
  "name": "Actor",
782
+ "value": 11
783
  },
784
  {
785
  "name": "Adult Performer",
786
+ "value": 2
787
  },
788
  {
789
  "name": "Model",
790
+ "value": 12
791
  },
792
  {
793
  "name": "Online Personality",
794
+ "value": 16
795
  },
796
  {
797
  "name": "Public Figure",
798
+ "value": 4
799
  },
800
  {
801
  "name": "Singer, Musician",
802
+ "value": 5
 
 
 
 
803
  },
804
  {
805
  "name": "Other",
806
+ "value": 1
807
  }
808
  ]
809
  },
810
  {
811
+ "name": "Thailand",
812
  "children": [
813
  {
814
  "name": "Actor",
815
+ "value": 15
816
  },
817
  {
818
  "name": "Adult Performer",
819
+ "value": 8
820
  },
821
  {
822
  "name": "Model",
823
+ "value": 8
824
  },
825
  {
826
  "name": "Online Personality",
 
 
 
 
 
 
 
 
827
  "value": 6
828
  },
829
  {
830
+ "name": "Singer, Musician",
831
+ "value": 8
832
  }
833
  ]
834
  },
835
  {
836
+ "name": "Czechia",
837
  "children": [
838
  {
839
  "name": "Actor",
840
+ "value": 4
841
  },
842
  {
843
  "name": "Adult Performer",
844
+ "value": 14
845
  },
846
  {
847
  "name": "Model",
848
+ "value": 8
849
  },
850
  {
851
  "name": "Online Personality",
852
+ "value": 2
853
  },
854
  {
855
  "name": "Public Figure",
856
+ "value": 8
857
  },
858
  {
859
  "name": "Singer, Musician",
860
+ "value": 3
861
+ },
862
+ {
863
+ "name": "Sports Professional",
864
+ "value": 2
865
  },
866
  {
867
  "name": "Other",
 
870
  ]
871
  },
872
  {
873
+ "name": "Colombia",
874
  "children": [
875
  {
876
  "name": "Actor",
877
+ "value": 1
878
  },
879
  {
880
  "name": "Adult Performer",
881
+ "value": 7
882
  },
883
  {
884
  "name": "Model",
885
+ "value": 15
886
  },
887
  {
888
  "name": "Online Personality",
889
+ "value": 2
890
  },
891
  {
892
+ "name": "Public Figure",
893
+ "value": 3
894
  },
895
  {
896
+ "name": "Singer, Musician",
897
  "value": 2
898
  }
899
  ]
 
903
  "children": [
904
  {
905
  "name": "Actor",
906
+ "value": 119
907
  },
908
  {
909
  "name": "Adult Performer",
910
+ "value": 51
911
  },
912
  {
913
  "name": "Model",
914
+ "value": 111
915
  },
916
  {
917
  "name": "Online Personality",
918
+ "value": 49
919
  },
920
  {
921
  "name": "Public Figure",
922
+ "value": 60
923
  },
924
  {
925
  "name": "Singer, Musician",
926
+ "value": 49
927
  },
928
  {
929
  "name": "Sports Professional",
930
+ "value": 31
931
  },
932
  {
933
  "name": "Other",
public/json/sunburst_gender_A.json CHANGED
@@ -6,39 +6,39 @@
6
  "children": [
7
  {
8
  "name": "Actor",
9
- "value": 6520
10
  },
11
  {
12
  "name": "Adult Performer",
13
- "value": 1556
14
  },
15
  {
16
  "name": "Model",
17
- "value": 1413
18
  },
19
  {
20
  "name": "Online Personality",
21
- "value": 770
22
  },
23
  {
24
  "name": "Public Figure",
25
- "value": 313
26
  },
27
  {
28
  "name": "Singer, Musician",
29
- "value": 2569
30
  },
31
  {
32
  "name": "Sports Professional",
33
- "value": 118
34
  },
35
  {
36
  "name": "Voice Actor",
37
- "value": 334
38
  },
39
  {
40
  "name": "Other",
41
- "value": 187
42
  }
43
  ]
44
  },
@@ -47,31 +47,31 @@
47
  "children": [
48
  {
49
  "name": "Actor",
50
- "value": 1152
51
  },
52
  {
53
  "name": "Adult Performer",
54
- "value": 31
55
  },
56
  {
57
  "name": "Model",
58
- "value": 33
59
  },
60
  {
61
  "name": "Online Personality",
62
- "value": 112
63
  },
64
  {
65
  "name": "Public Figure",
66
- "value": 420
67
  },
68
  {
69
  "name": "Singer, Musician",
70
- "value": 295
71
  },
72
  {
73
  "name": "Sports Professional",
74
- "value": 181
75
  },
76
  {
77
  "name": "Voice Actor",
@@ -79,16 +79,7 @@
79
  },
80
  {
81
  "name": "Other",
82
- "value": 50
83
- }
84
- ]
85
- },
86
- {
87
- "name": "Other",
88
- "children": [
89
- {
90
- "name": "Actor",
91
- "value": 1
92
  }
93
  ]
94
  }
 
6
  "children": [
7
  {
8
  "name": "Actor",
9
+ "value": 2396
10
  },
11
  {
12
  "name": "Adult Performer",
13
+ "value": 1178
14
  },
15
  {
16
  "name": "Model",
17
+ "value": 912
18
  },
19
  {
20
  "name": "Online Personality",
21
+ "value": 478
22
  },
23
  {
24
  "name": "Public Figure",
25
+ "value": 231
26
  },
27
  {
28
  "name": "Singer, Musician",
29
+ "value": 988
30
  },
31
  {
32
  "name": "Sports Professional",
33
+ "value": 95
34
  },
35
  {
36
  "name": "Voice Actor",
37
+ "value": 256
38
  },
39
  {
40
  "name": "Other",
41
+ "value": 155
42
  }
43
  ]
44
  },
 
47
  "children": [
48
  {
49
  "name": "Actor",
50
+ "value": 719
51
  },
52
  {
53
  "name": "Adult Performer",
54
+ "value": 20
55
  },
56
  {
57
  "name": "Model",
58
+ "value": 31
59
  },
60
  {
61
  "name": "Online Personality",
62
+ "value": 74
63
  },
64
  {
65
  "name": "Public Figure",
66
+ "value": 332
67
  },
68
  {
69
  "name": "Singer, Musician",
70
+ "value": 192
71
  },
72
  {
73
  "name": "Sports Professional",
74
+ "value": 138
75
  },
76
  {
77
  "name": "Voice Actor",
 
79
  },
80
  {
81
  "name": "Other",
82
+ "value": 43
 
 
 
 
 
 
 
 
 
83
  }
84
  ]
85
  }