Saba Noorassa commited on
Commit
1e8f76d
·
1 Parent(s): dc0b857

sunburst chart

Browse files
Files changed (5) hide show
  1. .gitignore +1 -0
  2. data/sunburst_data.min.json +0 -0
  3. index.html +27 -17
  4. style.css +24 -14
  5. sunburst.js +128 -0
.gitignore ADDED
@@ -0,0 +1 @@
 
 
1
+ .DS_STORE
data/sunburst_data.min.json ADDED
The diff for this file is too large to render. See raw diff
 
index.html CHANGED
@@ -1,19 +1,29 @@
1
- <!doctype html>
2
  <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
 
 
 
 
 
 
 
 
 
 
19
  </html>
 
1
+ <!DOCTYPE html>
2
  <html>
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width" />
6
+ <title>Xet Storage Sunburst</title>
7
+ <link rel="stylesheet" href="style.css" />
8
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/d3.min.js"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/d3-scale.min.js"></script>
10
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/d3-hierarchy.min.js"></script>
11
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/d3-shape.min.js"></script>
12
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/d3-format.min.js"></script>
13
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/d3-scale-chromatic.min.js"></script>
14
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/d3-interpolate.min.js"></script>
15
+ <script defer src="sunburst.js"></script>
16
+ </head>
17
+ <body>
18
+ <div id="content">
19
+ <h1>&#9728;&#65039; Xet Storage Sunburst &#9728;&#65039;</h1>
20
+ <p>
21
+ This sunburst diagram represents all public data stored using Xet. The
22
+ diagram presents this information hierarchically first by repo type
23
+ (model, dataset, or space) then owner (user or org), repo name, and
24
+ finally individual files within the repo backed by Xet.
25
+ </p>
26
+ <svg id="sunburst"></svg>
27
+ </div>
28
+ </body>
29
  </html>
style.css CHANGED
@@ -1,28 +1,38 @@
1
  body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
4
  }
5
 
6
  h1 {
7
- font-size: 16px;
8
- margin-top: 0;
9
  }
10
 
11
  p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
16
  }
17
 
18
  .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
24
  }
25
 
26
  .card p:last-child {
27
- margin-bottom: 0;
 
 
 
 
 
 
 
 
 
 
28
  }
 
1
  body {
2
+ padding: 2rem;
3
+ font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
4
  }
5
 
6
  h1 {
7
+ font-size: 36px;
8
+ margin-top: 0;
9
  }
10
 
11
  p {
12
+ color: rgb(107, 114, 128);
13
+ font-size: 15px;
14
+ margin-bottom: 10px;
15
+ margin-top: 5px;
16
  }
17
 
18
  .card {
19
+ max-width: 620px;
20
+ margin: 0 auto;
21
+ padding: 16px;
22
+ border: 1px solid lightgray;
23
+ border-radius: 16px;
24
  }
25
 
26
  .card p:last-child {
27
+ margin-bottom: 0;
28
+ }
29
+
30
+ #content {
31
+ max-width: 1024px;
32
+ margin: 0 auto;
33
+ }
34
+
35
+ #sunburst {
36
+ margin-top: 2rem;
37
+ max-width: 928px;
38
  }
sunburst.js ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (async () => {
2
+ // Fetch graph data.
3
+ const response = await fetch("/data/sunburst_data.min.json");
4
+ if (!response.ok) throw new Error(response.statusText);
5
+ const data = await response.json();
6
+
7
+ // Specify the chart’s dimensions.
8
+ const width = 928;
9
+ const height = width;
10
+ const radius = width / 6;
11
+
12
+ // Create the color scale.
13
+ const color = d3.scaleOrdinal(d3.quantize(d3.interpolateRainbow, data.children.length + 1));
14
+
15
+ // Compute the layout.
16
+ const hierarchy = d3.hierarchy(data)
17
+ .sum(d => d.value)
18
+ .sort((a, b) => b.value - a.value);
19
+ const root = d3.partition()
20
+ .size([2 * Math.PI, hierarchy.height + 1])
21
+ (hierarchy);
22
+ root.each(d => d.current = d);
23
+
24
+ // Create the arc generator.
25
+ const arc = d3.arc()
26
+ .startAngle(d => d.x0)
27
+ .endAngle(d => d.x1)
28
+ .padAngle(d => Math.min((d.x1 - d.x0) / 2, 0.005))
29
+ .padRadius(radius * 1.5)
30
+ .innerRadius(d => d.y0 * radius)
31
+ .outerRadius(d => Math.max(d.y0 * radius, d.y1 * radius - 1))
32
+
33
+ // Select the SVG container.
34
+ const svg = d3.select("#sunburst")
35
+ .attr("viewBox", [-width / 2, -height / 2, width, width])
36
+ .style("font", "10px sans-serif");
37
+
38
+ // Append the arcs.
39
+ const path = svg.append("g")
40
+ .selectAll("path")
41
+ .data(root.descendants().slice(1))
42
+ .join("path")
43
+ .attr("fill", d => { while (d.depth > 1) d = d.parent; return color(d.data.name); })
44
+ .attr("fill-opacity", d => arcVisible(d.current) ? (d.children ? 0.6 : 0.4) : 0)
45
+ .attr("pointer-events", d => arcVisible(d.current) ? "auto" : "none")
46
+
47
+ .attr("d", d => arc(d.current));
48
+
49
+ // Make them clickable if they have children.
50
+ path.filter(d => d.children)
51
+ .style("cursor", "pointer")
52
+ .on("click", clicked);
53
+
54
+ const format = d3.format(",d");
55
+ path.append("title")
56
+ .text(d => `${d.ancestors().map(d => d.data.name).reverse().join("/")}\n${format(d.value)}`);
57
+
58
+ const label = svg.append("g")
59
+ .attr("pointer-events", "none")
60
+ .attr("text-anchor", "middle")
61
+ .style("user-select", "none")
62
+ .selectAll("text")
63
+ .data(root.descendants().slice(1))
64
+ .join("text")
65
+ .attr("dy", "0.35em")
66
+ .attr("fill-opacity", d => +labelVisible(d.current))
67
+ .attr("transform", d => labelTransform(d.current))
68
+ .text(d => d.data.name);
69
+
70
+ const parent = svg.append("circle")
71
+ .datum(root)
72
+ .attr("r", radius)
73
+ .attr("fill", "none")
74
+ .attr("pointer-events", "all")
75
+ .on("click", clicked);
76
+
77
+ // Handle zoom on click.
78
+ function clicked(event, p) {
79
+ parent.datum(p.parent || root);
80
+
81
+ root.each(d => d.target = {
82
+ x0: Math.max(0, Math.min(1, (d.x0 - p.x0) / (p.x1 - p.x0))) * 2 * Math.PI,
83
+ x1: Math.max(0, Math.min(1, (d.x1 - p.x0) / (p.x1 - p.x0))) * 2 * Math.PI,
84
+ y0: Math.max(0, d.y0 - p.depth),
85
+ y1: Math.max(0, d.y1 - p.depth)
86
+ });
87
+
88
+ const t = svg.transition().duration(event.altKey ? 7500 : 750);
89
+
90
+ // Transition the data on all arcs, even the ones that aren’t visible,
91
+ // so that if this transition is interrupted, entering arcs will start
92
+ // the next transition from the desired position.
93
+ path.transition(t)
94
+ .tween("data", d => {
95
+ const i = d3.interpolate(d.current, d.target);
96
+ return t => d.current = i(t);
97
+ })
98
+ .filter(function(d) {
99
+ return +this.getAttribute("fill-opacity") || arcVisible(d.target);
100
+ })
101
+ .attr("fill-opacity", d => arcVisible(d.target) ? (d.children ? 0.6 : 0.4) : 0)
102
+ .attr("pointer-events", d => arcVisible(d.target) ? "auto" : "none")
103
+
104
+ .attrTween("d", d => () => arc(d.current));
105
+
106
+ label.filter(function(d) {
107
+ return +this.getAttribute("fill-opacity") || labelVisible(d.target);
108
+ }).transition(t)
109
+ .attr("fill-opacity", d => +labelVisible(d.target))
110
+ .attrTween("transform", d => () => labelTransform(d.current));
111
+ }
112
+
113
+ function arcVisible(d) {
114
+ return d.y1 <= 3 && d.y0 >= 1 && d.x1 > d.x0;
115
+ }
116
+
117
+ function labelVisible(d) {
118
+ return d.y1 <= 3 && d.y0 >= 1 && (d.y1 - d.y0) * (d.x1 - d.x0) > 0.03;
119
+ }
120
+
121
+ function labelTransform(d) {
122
+ const x = (d.x0 + d.x1) / 2 * 180 / Math.PI;
123
+ const y = (d.y0 + d.y1) / 2 * radius;
124
+ return `rotate(${x - 90}) translate(${y},0) rotate(${x < 180 ? 0 : 180})`;
125
+ }
126
+
127
+ // return svg.node();
128
+ })();