Ray1ee01 commited on
Commit
3c00a10
·
verified ·
1 Parent(s): 4de7714

Upload folder using huggingface_hub

Browse files
modules/chart_engine/template/d3-js/type72_funnel_chart/funnel_plain_chart_01.js ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ REQUIREMENTS_BEGIN
3
+ {
4
+ "chart_type": "Funnel Chart",
5
+ "chart_name": "funnel_plain_chart_01",
6
+ "required_fields": ["x", "y"],
7
+ "required_fields_type": [["categorical"], ["numerical"]],
8
+ "required_fields_range": [[3, 10], [0, 100]],
9
+ "required_fields_icons": [],
10
+ "required_other_icons": [],
11
+ "required_fields_colors": ["x"],
12
+ "required_other_colors": [],
13
+ "supported_effects": [],
14
+ "min_height": 400,
15
+ "min_width": 400,
16
+ "background": "light",
17
+ "icon_mark": "none",
18
+ "icon_label": "none",
19
+ "has_x_axis": "no",
20
+ "has_y_axis": "no"
21
+ }
22
+ REQUIREMENTS_END
23
+ */
24
+
25
+ function makeChart(containerSelector, data) {
26
+ // 提取数据
27
+ const jsonData = data;
28
+ const chartData = jsonData.data.data;
29
+ const variables = jsonData.variables;
30
+ const typography = jsonData.typography;
31
+ const colors = jsonData.colors || {};
32
+ const colorResolver = chartUtils.color.resolver(jsonData);
33
+ const dataColumns = chartUtils.schema.columns(jsonData);
34
+ const images = jsonData.images || {};
35
+
36
+ // 清空容器
37
+ d3.select(containerSelector).html("");
38
+
39
+ // 获取字段名
40
+ const categoryField = chartUtils.schema.columnField(dataColumns, 0);
41
+ const valueField = chartUtils.schema.columnField(dataColumns, 1);
42
+
43
+ // 按值从大到小排序数据(大的在顶部)
44
+ const sortedData = [...chartData].sort((a, b) => +b[valueField] - +a[valueField]);
45
+
46
+ // 计算总和以获取百分比
47
+ const total = d3.sum(sortedData, d => +d[valueField]);
48
+
49
+ // 为每个数据点添加百分比
50
+ sortedData.forEach(d => {
51
+ d.percent = (+d[valueField] / total) * 100;
52
+ });
53
+
54
+ // 设置尺寸和边距
55
+ const width = variables.width;
56
+ const height = variables.height;
57
+ const margin = { top: 40, right: 120, bottom: 40, left: 60 };
58
+
59
+ // 创建SVG
60
+ const svg = d3.select(containerSelector)
61
+ .append("svg")
62
+ .attr("width", "100%")
63
+ .attr("height", height)
64
+ .attr("viewBox", `0 0 ${width} ${height}`)
65
+ .attr("style", "max-width: 100%; height: auto;")
66
+ .attr("xmlns", "http://www.w3.org/2000/svg")
67
+ .attr("xmlns:xlink", "http://www.w3.org/1999/xlink");
68
+
69
+ // 创建图表区域
70
+ const chartWidth = width - margin.left - margin.right;
71
+ const chartHeight = height - margin.top - margin.bottom;
72
+
73
+ const g = svg.append("g")
74
+ .attr("transform", `translate(${margin.left}, ${margin.top})`);
75
+
76
+ // 计算漏斗图的最大宽度和高度
77
+ const maxFunnelWidth = chartWidth * 0.8;
78
+ const funnelHeight = chartHeight * 0.8;
79
+
80
+ // 计算每个部分的高度(均等分配)
81
+ const sectionHeight = funnelHeight / sortedData.length;
82
+
83
+ // 创建宽度比例尺
84
+ const widthScale = d3.scaleLinear()
85
+ .domain([0, 100])
86
+ .range([0, maxFunnelWidth]);
87
+
88
+ // 计算每个部分的宽度
89
+ const sectionWidths = sortedData.map(d => widthScale(d.percent));
90
+
91
+ // 计算垂直居中的偏移量
92
+ const verticalOffset = (chartHeight - funnelHeight) / 2;
93
+
94
+ // 绘制漏斗图的每一层
95
+ sortedData.forEach((d, i) => {
96
+ // 获取颜色
97
+ const color = colorResolver.field(d[categoryField], i, { palette: "category10" }).value;
98
+
99
+ // 计算当前层的宽度
100
+ const topWidth = sectionWidths[i];
101
+
102
+ // 计算下一层的宽度(如果是最后一层,则使用当前宽度的80%)
103
+ const bottomWidth = i < sortedData.length - 1
104
+ ? sectionWidths[i + 1]
105
+ : topWidth * 0.8;
106
+
107
+ // 计算当前层的位置
108
+ const sectionY = i * sectionHeight + verticalOffset;
109
+
110
+ // 绘制梯形
111
+ const points = [
112
+ [chartWidth / 2 - topWidth / 2, sectionY],
113
+ [chartWidth / 2 + topWidth / 2, sectionY],
114
+ [chartWidth / 2 + bottomWidth / 2, sectionY + sectionHeight],
115
+ [chartWidth / 2 - bottomWidth / 2, sectionY + sectionHeight]
116
+ ];
117
+
118
+ g.append("polygon")
119
+ .attr("points", points.map(p => p.join(",")).join(" "))
120
+ .attr("fill", color);
121
+
122
+ // 添加标签
123
+ g.append("text")
124
+ .attr("x", chartWidth / 2 + topWidth / 2 + 10)
125
+ .attr("y", sectionY + sectionHeight / 2)
126
+ .attr("dominant-baseline", "middle")
127
+ .attr("font-size", "14px")
128
+ .attr("font-weight", "bold")
129
+ .text(`${d[categoryField]} ${chartUtils.format.percent(d.percent, { digits: 0 }).text}`);
130
+ });
131
+
132
+ return svg.node();
133
+ }
modules/chart_engine/template/d3-js/type72_funnel_chart/funnel_plain_chart_02.js ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ REQUIREMENTS_BEGIN
3
+ {
4
+ "chart_type": "Funnel Chart",
5
+ "chart_name": "funnel_plain_chart_02",
6
+ "required_fields": ["x", "y"],
7
+ "required_fields_type": [["categorical"], ["numerical"]],
8
+ "required_fields_range": [[3, 10], [0, 100]],
9
+ "required_fields_icons": [],
10
+ "required_other_icons": [],
11
+ "required_fields_colors": ["x"],
12
+ "required_other_colors": [],
13
+ "supported_effects": [],
14
+ "min_height": 400,
15
+ "min_width": 400,
16
+ "background": "light",
17
+ "icon_mark": "none",
18
+ "icon_label": "none",
19
+ "has_x_axis": "no",
20
+ "has_y_axis": "no"
21
+ }
22
+ REQUIREMENTS_END
23
+ */
24
+
25
+ function makeChart(containerSelector, data) {
26
+ // 提取数据
27
+ const jsonData = data;
28
+ const chartData = jsonData.data.data;
29
+ const variables = jsonData.variables;
30
+ const typography = jsonData.typography;
31
+ const colors = jsonData.colors || {};
32
+ const colorResolver = chartUtils.color.resolver(jsonData);
33
+ const dataColumns = chartUtils.schema.columns(jsonData);
34
+ const images = jsonData.images || {};
35
+
36
+ // 清空容器
37
+ d3.select(containerSelector).html("");
38
+
39
+ // 获取字段名
40
+ const categoryField = chartUtils.schema.columnField(dataColumns, 0);
41
+ const valueField = chartUtils.schema.columnField(dataColumns, 1);
42
+
43
+ // 按值从大到小排序数据(大的在顶部)
44
+ const sortedData = [...chartData].sort((a, b) => +b[valueField] - +a[valueField]);
45
+
46
+ // 计算总和以获取百分比
47
+ const total = d3.sum(sortedData, d => +d[valueField]);
48
+
49
+ // 为每个数据点添加百分比
50
+ sortedData.forEach(d => {
51
+ d.percent = (+d[valueField] / total) * 100;
52
+ });
53
+
54
+ // 设置尺寸和边距
55
+ const width = variables.width;
56
+ const height = variables.height;
57
+ const margin = { top: 40, right: 120, bottom: 40, left: 60 };
58
+
59
+ // 创建SVG
60
+ const svg = d3.select(containerSelector)
61
+ .append("svg")
62
+ .attr("width", "100%")
63
+ .attr("height", height)
64
+ .attr("viewBox", `0 0 ${width} ${height}`)
65
+ .attr("style", "max-width: 100%; height: auto;")
66
+ .attr("xmlns", "http://www.w3.org/2000/svg")
67
+ .attr("xmlns:xlink", "http://www.w3.org/1999/xlink");
68
+
69
+ // 创建图表区域
70
+ const chartWidth = width - margin.left - margin.right;
71
+ const chartHeight = height - margin.top - margin.bottom;
72
+
73
+ const g = svg.append("g")
74
+ .attr("transform", `translate(${margin.left}, ${margin.top})`);
75
+
76
+ // 计算漏斗图的最大宽度和高度
77
+ const maxFunnelWidth = chartWidth * 0.8;
78
+ const funnelHeight = chartHeight * 0.8;
79
+
80
+ // 计算每个部分的高度(均等分配)
81
+ const sectionHeight = funnelHeight / sortedData.length;
82
+
83
+ // 创建宽度比例尺
84
+ const widthScale = d3.scaleLinear()
85
+ .domain([0, 100])
86
+ .range([0, maxFunnelWidth]);
87
+
88
+ // 计算每个部分的宽度
89
+ const sectionWidths = sortedData.map(d => widthScale(d.percent));
90
+
91
+ // 计算垂直居中的偏移量
92
+ const verticalOffset = (chartHeight - funnelHeight) / 2;
93
+
94
+ const y_padding = 5;
95
+
96
+ // 绘制漏斗图的每一层
97
+ sortedData.forEach((d, i) => {
98
+ // 获取颜色
99
+ const color = colorResolver.field(d[categoryField], i, { palette: "category10" }).value;
100
+
101
+ // 计算当前层的宽度
102
+ const topWidth = sectionWidths[i];
103
+
104
+ // 计算下一层的宽度(如果是最后一层,则使用当前宽度的80%)
105
+ const bottomWidth = i < sortedData.length - 1
106
+ ? sectionWidths[i + 1]
107
+ : topWidth * 0.8;
108
+
109
+ // 计算当前层的位置
110
+ const sectionY = i * sectionHeight + verticalOffset;
111
+
112
+ // 绘制梯形
113
+ const points = [
114
+ [chartWidth / 2 - topWidth / 2, sectionY + y_padding * i],
115
+ [chartWidth / 2 + topWidth / 2, sectionY + y_padding * i],
116
+ [chartWidth / 2 + bottomWidth / 2, sectionY + sectionHeight + y_padding * i],
117
+ [chartWidth / 2 - bottomWidth / 2, sectionY + sectionHeight + y_padding * i]
118
+ ];
119
+
120
+ g.append("polygon")
121
+ .attr("points", points.map(p => p.join(",")).join(" "))
122
+ .attr("fill", color);
123
+
124
+ // 添加标签
125
+ g.append("text")
126
+ .attr("x", chartWidth / 2 + topWidth / 2 + 10)
127
+ .attr("y", sectionY + sectionHeight / 2 + y_padding * i)
128
+ .attr("dominant-baseline", "middle")
129
+ .attr("font-size", "14px")
130
+ .attr("font-weight", "bold")
131
+ .text(`${d[categoryField]} ${chartUtils.format.percent(d.percent, { digits: 0 }).text}`);
132
+ });
133
+
134
+ return svg.node();
135
+ }