@ww_nero/skills 3.0.2 → 3.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/svg_to_pptx.py +120 -9
- package/index.js +2 -3
- package/package.json +1 -1
package/assets/svg_to_pptx.py
CHANGED
|
@@ -1,15 +1,7 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
1
|
# -*- coding: utf-8 -*-
|
|
3
|
-
"""
|
|
4
|
-
将HTML文件中的SVG转换为PPTX
|
|
5
|
-
|
|
6
|
-
注意事项:
|
|
7
|
-
- 对于 icon 元素(如带有 id="icon-*" 的 <g> 元素),
|
|
8
|
-
会先将其独立保存为小的 PNG 图片,然后再插入到 PPTX 中。
|
|
9
|
-
这样可以保证矢量图标在 PowerPoint 中正确显示。
|
|
10
|
-
"""
|
|
11
2
|
import os
|
|
12
3
|
import re
|
|
4
|
+
import math
|
|
13
5
|
import tempfile
|
|
14
6
|
from pptx import Presentation
|
|
15
7
|
from pptx.util import Pt, Emu
|
|
@@ -522,6 +514,106 @@ def add_circular_image(slide, image_path, cx, cy, r):
|
|
|
522
514
|
shape = slide.shapes.add_picture(buffer, px(cx - r), px(cy - r), px(diameter), px(diameter))
|
|
523
515
|
return shape
|
|
524
516
|
|
|
517
|
+
def add_pie_chart(slide, cx, cy, r, data, colors, labels=None, start_angle=-90, stroke_color=None, stroke_width=0, opacity=1.0, has_shadow=False):
|
|
518
|
+
total = sum(data)
|
|
519
|
+
if total == 0:
|
|
520
|
+
return []
|
|
521
|
+
|
|
522
|
+
shapes = []
|
|
523
|
+
current_angle = start_angle
|
|
524
|
+
|
|
525
|
+
for i, value in enumerate(data):
|
|
526
|
+
if value <= 0:
|
|
527
|
+
continue
|
|
528
|
+
|
|
529
|
+
percentage = value / total
|
|
530
|
+
sweep_angle = percentage * 360
|
|
531
|
+
|
|
532
|
+
color = colors[i % len(colors)]
|
|
533
|
+
shape = _add_pie_slice(slide, cx, cy, r, current_angle, sweep_angle,
|
|
534
|
+
color, stroke_color, stroke_width, opacity, has_shadow)
|
|
535
|
+
if shape:
|
|
536
|
+
shapes.append(shape)
|
|
537
|
+
|
|
538
|
+
current_angle += sweep_angle
|
|
539
|
+
|
|
540
|
+
return shapes
|
|
541
|
+
|
|
542
|
+
def _add_pie_slice(slide, cx, cy, r, start_angle, sweep_angle, fill_color, stroke_color=None, stroke_width=0, opacity=1.0, has_shadow=False):
|
|
543
|
+
if sweep_angle >= 360:
|
|
544
|
+
sweep_angle = 359.99
|
|
545
|
+
|
|
546
|
+
start_rad = math.radians(start_angle)
|
|
547
|
+
end_rad = math.radians(start_angle + sweep_angle)
|
|
548
|
+
|
|
549
|
+
points = [(cx, cy)]
|
|
550
|
+
|
|
551
|
+
num_segments = max(int(sweep_angle / 5), 2)
|
|
552
|
+
for i in range(num_segments + 1):
|
|
553
|
+
angle = start_rad + (end_rad - start_rad) * i / num_segments
|
|
554
|
+
x = cx + r * math.cos(angle)
|
|
555
|
+
y = cy + r * math.sin(angle)
|
|
556
|
+
points.append((x, y))
|
|
557
|
+
|
|
558
|
+
points.append((cx, cy))
|
|
559
|
+
|
|
560
|
+
shape = add_freeform_path(slide, points, fill_color=fill_color,
|
|
561
|
+
stroke_color=stroke_color, stroke_width=stroke_width,
|
|
562
|
+
opacity=opacity, closed=True, has_shadow=has_shadow)
|
|
563
|
+
return shape
|
|
564
|
+
|
|
565
|
+
def add_donut_chart(slide, cx, cy, outer_r, inner_r, data, colors, labels=None, start_angle=-90, stroke_color=None, stroke_width=0, opacity=1.0, has_shadow=False):
|
|
566
|
+
total = sum(data)
|
|
567
|
+
if total == 0:
|
|
568
|
+
return []
|
|
569
|
+
|
|
570
|
+
shapes = []
|
|
571
|
+
current_angle = start_angle
|
|
572
|
+
|
|
573
|
+
for i, value in enumerate(data):
|
|
574
|
+
if value <= 0:
|
|
575
|
+
continue
|
|
576
|
+
|
|
577
|
+
percentage = value / total
|
|
578
|
+
sweep_angle = percentage * 360
|
|
579
|
+
|
|
580
|
+
color = colors[i % len(colors)]
|
|
581
|
+
shape = _add_donut_slice(slide, cx, cy, outer_r, inner_r, current_angle, sweep_angle,
|
|
582
|
+
color, stroke_color, stroke_width, opacity, has_shadow)
|
|
583
|
+
if shape:
|
|
584
|
+
shapes.append(shape)
|
|
585
|
+
|
|
586
|
+
current_angle += sweep_angle
|
|
587
|
+
|
|
588
|
+
return shapes
|
|
589
|
+
|
|
590
|
+
def _add_donut_slice(slide, cx, cy, outer_r, inner_r, start_angle, sweep_angle, fill_color, stroke_color=None, stroke_width=0, opacity=1.0, has_shadow=False):
|
|
591
|
+
if sweep_angle >= 360:
|
|
592
|
+
sweep_angle = 359.99
|
|
593
|
+
|
|
594
|
+
start_rad = math.radians(start_angle)
|
|
595
|
+
end_rad = math.radians(start_angle + sweep_angle)
|
|
596
|
+
|
|
597
|
+
points = []
|
|
598
|
+
|
|
599
|
+
num_segments = max(int(sweep_angle / 5), 2)
|
|
600
|
+
for i in range(num_segments + 1):
|
|
601
|
+
angle = start_rad + (end_rad - start_rad) * i / num_segments
|
|
602
|
+
x = cx + outer_r * math.cos(angle)
|
|
603
|
+
y = cy + outer_r * math.sin(angle)
|
|
604
|
+
points.append((x, y))
|
|
605
|
+
|
|
606
|
+
for i in range(num_segments, -1, -1):
|
|
607
|
+
angle = start_rad + (end_rad - start_rad) * i / num_segments
|
|
608
|
+
x = cx + inner_r * math.cos(angle)
|
|
609
|
+
y = cy + inner_r * math.sin(angle)
|
|
610
|
+
points.append((x, y))
|
|
611
|
+
|
|
612
|
+
shape = add_freeform_path(slide, points, fill_color=fill_color,
|
|
613
|
+
stroke_color=stroke_color, stroke_width=stroke_width,
|
|
614
|
+
opacity=opacity, closed=True, has_shadow=has_shadow)
|
|
615
|
+
return shape
|
|
616
|
+
|
|
525
617
|
def create_slide(prs):
|
|
526
618
|
"""深度学习的崛起(1990-2017)"""
|
|
527
619
|
slide = prs.slides.add_slide(prs.slide_layouts[6])
|
|
@@ -680,6 +772,25 @@ def create_slide(prs):
|
|
|
680
772
|
# SVG: <text x="320" y="650" font-size="32" fill="#ffffff">🧠</text>
|
|
681
773
|
add_text_box(slide, "🧠", 320, 650, 50, 40, 32, "#ffffff", anchor='start', valign='top')
|
|
682
774
|
|
|
775
|
+
# 饼状图演示:展示各技术占比
|
|
776
|
+
# SVG: <g transform="translate(500, 550)">
|
|
777
|
+
# <!-- 饼状图: CNN 40%, RNN 25%, GAN 20%, Transformer 15% -->
|
|
778
|
+
# </g>
|
|
779
|
+
pie_data = [40, 25, 20, 15]
|
|
780
|
+
pie_colors = ["#ff6384", "#36a2eb", "#ffce56", "#4bc0c0"]
|
|
781
|
+
add_pie_chart(slide, 500, 580, 50, pie_data, pie_colors, stroke_color="#1a237e", stroke_width=1)
|
|
782
|
+
add_text_box(slide, "技术分布", 500, 520, 100, 20, 12, "#b3e5fc", anchor='middle', valign='top')
|
|
783
|
+
|
|
784
|
+
# 环形图演示:展示GPU使用率
|
|
785
|
+
# SVG: <g transform="translate(600, 550)">
|
|
786
|
+
# <!-- 环形图: 训练 60%, 推理 30%, 空闲 10% -->
|
|
787
|
+
# </g>
|
|
788
|
+
donut_data = [60, 30, 10]
|
|
789
|
+
donut_colors = ["#00e5ff", "#2979ff", "#ffffff"]
|
|
790
|
+
add_donut_chart(slide, 600, 580, 50, 30, donut_data, donut_colors, stroke_color="#1a237e", stroke_width=1, opacity=0.9)
|
|
791
|
+
add_text_box(slide, "GPU", 600, 580, 40, 20, 14, "#ffffff", bold=True, anchor='middle', valign='middle')
|
|
792
|
+
add_text_box(slide, "使用率", 600, 520, 100, 20, 12, "#b3e5fc", anchor='middle', valign='top')
|
|
793
|
+
|
|
683
794
|
def main():
|
|
684
795
|
prs = Presentation()
|
|
685
796
|
prs.slide_width = px(1280)
|
package/index.js
CHANGED
|
@@ -201,8 +201,7 @@ const GUIDES = {
|
|
|
201
201
|
- **不要使用\`BeautifulSoup\`这种通用的解析元素的方式,而是逐个元素从svg代码转化为python创建元素的代码**
|
|
202
202
|
- 转换过程中,需要把图片占位元素替换成前面准备的图片素材
|
|
203
203
|
|
|
204
|
-
|
|
205
|
-
- 完成后**需要保留**规划文档、html页面文件和python转化脚本,方便进一步根据反馈进行修改`
|
|
204
|
+
**注意**:完成后**需要保留**规划文档、html页面文件和python转化脚本,方便进一步根据反馈进行修改`
|
|
206
205
|
}
|
|
207
206
|
};
|
|
208
207
|
|
|
@@ -284,7 +283,7 @@ const listTools = () => ({
|
|
|
284
283
|
]
|
|
285
284
|
});
|
|
286
285
|
|
|
287
|
-
const server = new Server({ name: 'skills', version: '3.0.
|
|
286
|
+
const server = new Server({ name: 'skills', version: '3.0.4' }, { capabilities: { tools: {} } });
|
|
288
287
|
|
|
289
288
|
server.setRequestHandler(ListToolsRequestSchema, async () => listTools());
|
|
290
289
|
|