@ww_nero/skills 3.0.2 → 3.0.3
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 +1 -1
- 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
|
@@ -284,7 +284,7 @@ const listTools = () => ({
|
|
|
284
284
|
]
|
|
285
285
|
});
|
|
286
286
|
|
|
287
|
-
const server = new Server({ name: 'skills', version: '3.0.
|
|
287
|
+
const server = new Server({ name: 'skills', version: '3.0.3' }, { capabilities: { tools: {} } });
|
|
288
288
|
|
|
289
289
|
server.setRequestHandler(ListToolsRequestSchema, async () => listTools());
|
|
290
290
|
|