返回 aippt
index.html
根目录 / index.html
1 <!DOCTYPE html>
2 <html lang="zh">
3 <head>
4 <meta charset="UTF-8">
5 <title>AI PPT</title>
6 <style>
7 ::-webkit-scrollbar {
8 width: 5px;
9 height: 5px;
10 background-color: #fff;
11 }
12 ::-webkit-scrollbar-thumb {
13 background-color: #c1c1c1;
14 }
15 .docmee {
16 z-index: 9999;
17 background-image: linear-gradient(to left, rgb(107, 90, 196), rgb(96, 84, 189));
18 background-clip: text;
19 color: transparent;
20 font-weight: bold;
21 display: inline-block;
22 font-size: 1.125rem;
23 line-height: 1.75rem;
24 user-select: none;
25 cursor: pointer;
26 position: fixed;
27 top: 10px;
28 left: 15px;
29 }
30 #div1 {
31 text-align: center;
32 margin-top: 60px;
33 }
34 #div1, #div2, #div3, #nextTo2, #nextTo3, #desc, #right_canvas {
35 display: none;
36 }
37 #outline {
38 text-align: left;
39 margin: 0 calc(20vw);
40 }
41 #templates {
42 width: 80%;
43 max-width: 1050px;
44 margin: auto;
45 display: flex;
46 flex-wrap: wrap;
47 flex-direction: row;
48 align-items: center;
49 text-align: center;
50 }
51 .template {
52 margin: 8px;
53 width: 240px;
54 height: 136px;
55 cursor: pointer;
56 overflow: hidden;
57 border-radius: 12px;
58 background-color: #ecedf4;
59 border: 2px solid transparent;
60 }
61 .template img {
62 width: 100%;
63 height: 100%;
64 opacity: 1;
65 object-fit: cover;
66 transition: all .6s ease;
67 }
68 .template img:hover {
69 transform: scale(1.2);
70 transition-duration: .3s;
71 }
72 h1 {
73 font-size: 1.6em;
74 margin-block-start: 0.5em;
75 margin-block-end: 0.5em;
76 }
77 h2 {
78 font-size: 1.3em;
79 margin-block-start: 0.7em;
80 margin-block-end: 0.7em;
81 }
82 h3 {
83 font-size: 1.1em;
84 margin-block-start: 0.9em;
85 margin-block-end: 0.9em;
86 }
87 h4 {
88 margin-block-start: 1.1em;
89 margin-block-end: 1.1em;
90 }
91 ul {
92 list-style: none;
93 }
94 #pptDownload {
95 display: none;
96 float: right;
97 }
98 .left_div {
99 align-items: center;
100 display: flex;
101 flex-direction: column;
102 flex-shrink: 0;
103 height: 96vh;
104 justify-content: center;
105 position: absolute;
106 width: 158px;
107 }
108 .left_div_child {
109 background: #fff;
110 border: 1px solid #fff;
111 border-radius: 6px;
112 box-shadow: 0 4px 10px 0 #0003;
113 margin-left: 12px;
114 margin-top: 28px;
115 max-height: calc(100vh - 130px);
116 width: 200px;
117 }
118 .left_div_child_child {
119 max-height: calc(100vh - 130px);
120 overflow-x: hidden;
121 overflow-y: auto;
122 padding: 0 8px 0 2px;
123 }
124 .left_div_item {
125 display: flex;
126 cursor: pointer;
127 margin: 10px 0;
128 }
129 .left_div_item_index {
130 color: #8d90a5;
131 flex-shrink: 0;
132 padding-right: 6px;
133 padding-top: 30px;
134 text-align: right;
135 width: 23px;
136 }
137 .left_div_item_img {
138 height: 80px;
139 border: 1px solid #ccc;
140 }
141 .right_div {
142 position: absolute;
143 margin-left: 280px;
144 top: 50%;
145 transform: translateY(-50%);
146 }
147 #right_canvas {
148 margin: 0px auto;
149 display: block;
150 border: 1px solid #666;
151 }
152 .item_select {
153 border: 2px solid #491ff8;
154 }
155 .draw_el_class {
156 position: fixed;
157 }
158 .draw_el_class:hover {
159 cursor: text;
160 border: 1.5px solid red;
161 }
162 .lang-switch {
163 position: fixed;
164 top: 10px;
165 right: 15px;
166 z-index: 9999;
167 cursor: pointer;
168 font-size: 14px;
169 color: #666;
170 user-select: none;
171 }
172 .lang-switch:hover {
173 color: #491ff8;
174 }
175 </style>
176 </head>
177 <body>
178 <a href="https://docmee.cn" target="_blank" class="docmee" data-i18n="brand_title" title="进入文多多AiPPT官网">文多多 AiPPT</a>
179 <div class="lang-switch" onclick="toggleLanguage()">
180 <span id="lang-text">EN</span>
181 </div>
182 <!-- 大纲生成 -->
183 <div id="div1">
184 <div style="margin-bottom: 50px;">
185 <h1 data-i18n="page1_title">🤖 AI智能生成PPT演示文稿</h1>
186 <div style="font-size: 14px;color: #999;" data-i18n="page1_steps">生成大纲 ---&gt; 挑选模板 ---&gt; 实时生成PPT</div>
187 </div>
188 <label data-i18n="subject_label">主题:</label>
189 <input type="text" id="subject" data-i18n-placeholder="subject_placeholder" placeholder="请输入PPT主题" maxlength="30" />
190 <button onclick="generateOutline()" data-i18n="generate_outline_btn">生成大纲</button>
191 <button id="nextTo2" class="next_but" onclick="nextTo2()" data-i18n="next_to_template_btn">下一步:选择模板</button>
192 <div id="outline"></div>
193 </div>
194 <!-- 选择模板 -->
195 <div id="div2">
196 <div style="text-align: center;margin: 10px;">
197 <div data-i18n="select_template_title">---- 选择模板 ----</div>
198 <button id="nextTo3" class="next_but" style="margin-top: 10px;" onclick="nextTo3()" data-i18n="next_to_generate_btn">下一步:生成PPT</button>
199 </div>
200 <div id="templates" data-i18n="templates_loading">模板加载中...</div>
201 </div>
202 <!-- PPT页面 -->
203 <div id="div3">
204 <div id="desc" style="text-align: center;margin-top: 20px">
205 <span id="desc_msg" data-i18n="generating_msg">正在生成中,请稍后...</span>
206 <span id="desc_time" style="margin-left: 5px"></span>
207 </div>
208 <div class="left_div">
209 <div class="left_div_child">
210 <div id="left_image_list" class="left_div_child_child">
211 <!--
212 <div class="left_div_item" onclick="drawPptx(0)">
213 <div class="left_div_item_index">1</div>
214 <img src="1.png" class="left_div_item_img" />
215 </div>
216 -->
217 </div>
218 </div>
219 </div>
220 <div class="right_div">
221 <select id="insert_element" style="display: none;margin-left: 10px" onchange="insertElement(this.value.split(',')[0], this.value.split(',')[1])">
222 <option value="" data-i18n="insert_element_title">-- 插入元素 --</option>
223 <option value="text,title1" data-i18n="insert_title1">插入大标题</option>
224 <option value="text,title2" data-i18n="insert_title2">插入副标题</option>
225 <option value="text,content" data-i18n="insert_content">插入正文文本</option>
226 <option value="image" data-i18n="insert_image">插入图片</option>
227 <option value="geometry" data-i18n="insert_geometry">插入随机形状</option>
228 <option value="table" data-i18n="insert_table">插入表格</option>
229 <option value="chart,bar" data-i18n="insert_bar_chart">插入柱状图</option>
230 <option value="chart,pie" data-i18n="insert_pie_chart">插入饼图</option>
231 <option value="chart,doughnut" data-i18n="insert_doughnut_chart">插入环形图</option>
232 <option value="chart,line" data-i18n="insert_line_chart">插入折线图</option>
233 </select>
234 <div id="pptDownload">
235 <select id="download_select" style="margin-right: 5px">
236 <option value="" data-i18n="download_options_title">-- 下载选项 --</option>
237 <option value="0" data-i18n="download_no_animation">不添加动画</option>
238 <option value="1" data-i18n="download_with_animation">智能添加动画</option>
239 </select>
240 <a id="downloadPptx" href="javascript:downloadPptx()" data-i18n="download_pptx_btn">渲染pptx并下载</a>
241 </div>
242 <div id="right_container" style="padding-top: 8px;">
243 <!--<canvas id="right_canvas" width="1920" height="1080" style="width: 960px;height: 540px;"></canvas>-->
244 <svg id="right_canvas"></svg>
245 </div>
246 </div>
247 </div>
248
249 <script src="static/i18n.js"></script>
250 <script src="static/sse.js"></script>
251 <script src="static/chart.js"></script>
252 <script src="static/geometry.js"></script>
253 <script src="static/element.js"></script>
254 <script src="static/ppt2svg.js"></script>
255 <script src="static/ppt2canvas.js"></script>
256 <script src="static/base64js.js"></script>
257 <script src="static/pako.js"></script>
258 <script src="static/marked.js"></script>
259 <script>
260
261 // 文多多AiPPT
262 // 官网 https://docmee.cn
263 // 开放平台 https://docmee.cn/open-platform
264
265 const apiKey = '4u2Fo50Alk1ym2Os'
266 var pptxId = null
267 var outline = ''
268 var templateId = ''
269 var pptxObj = null
270 var selectIdx = 0
271 var mTimer = null
272 var gening = false
273
274 var markdownRenderer = new marked.Renderer()
275 marked.setOptions({
276 renderer: markdownRenderer,
277 async: false, // 是否异步渲染
278 gfm: true, // 运行github标准的markdown
279 tables: true, // 表格
280 breaks: false, // 回车换行
281 pedantic: false, // 兼容隐晦部分
282 silent: true // 错误时不抛异常
283 })
284
285 // canvas
286 // var painter = new Ppt2Canvas('right_canvas')
287 // var canvas = painter.getCanvas()
288
289 // svg
290 var painter = new Ppt2Svg('right_canvas')
291 var canvas = painter.svgNode()
292 painter.setMode('edit')
293
294 function generateOutline() {
295 let subject = document.getElementById('subject').value
296 if (!subject) {
297 alert(t('alert_empty_subject'))
298 return
299 }
300 if (subject.length <= 1) {
301 alert(t('alert_subject_too_short'))
302 return
303 }
304 if (subject.length > 30) {
305 alert(t('alert_subject_too_long'))
306 return
307 }
308 if (gening) {
309 return
310 }
311 outline = ''
312 gening = true
313 const url = 'https://docmee.cn/api/public/ppt/generateOutline?apiKey=' + apiKey
314 var source = new SSE(url, {
315 method: 'POST',
316 // withCredentials: true,
317 headers: {
318 'Content-Type': 'application/json',
319 'Cache-Control': 'no-cache'
320 },
321 payload: JSON.stringify({ subject }),
322 })
323 source.onmessage = function (data) {
324 let json = JSON.parse(data.data)
325 if (json.status == -1) {
326 gening = false
327 alert(t('alert_outline_error') + json.error)
328 return
329 }
330 outline += json.text
331 document.getElementById('outline').innerHTML = window.marked.marked(outline.replaceAll('```markdown', '').replaceAll('```', ''))
332 window.scrollTo({ behavior: 'smooth', top: document.body.scrollHeight })
333 }
334 source.onend = function (data) {
335 gening = false
336 if (data.data.startsWith('{') && data.data.endsWith('}')) {
337 const json = JSON.parse(data.data)
338 if (json.code != 0) {
339 alert(t('alert_outline_error') + json.message)
340 return
341 }
342 }
343 document.getElementById('nextTo2').style.display = 'inline-block'
344 window.scrollTo(0, 0)
345 }
346 source.onerror = function (err) {
347 gening = false
348 console.error('生成大纲异常', err)
349 alert(t('alert_outline_error'))
350 }
351 source.stream()
352 }
353 function nextTo2() {
354 document.getElementById('nextTo2').style.display = 'none'
355 document.getElementById('div1').style.display = 'none'
356 document.getElementById('div2').style.display = 'block'
357 window.scrollTo(0, 0)
358 loadTemplates()
359 }
360 function loadTemplates() {
361 let url = 'https://docmee.cn/api/public/ppt/randomTemplates?apiKey=' + apiKey
362 let xhr = new XMLHttpRequest()
363 xhr.open('POST', url, true)
364 xhr.setRequestHeader('Content-Type', 'application/json')
365 xhr.send(JSON.stringify({ page: 1, size: 28, filters: { type: 1 } }))
366 xhr.onreadystatechange = function () {
367 if (xhr.readyState === 4) {
368 if (xhr.status === 200) {
369 let resp = JSON.parse(xhr.responseText)
370 let list = resp.data
371 let templates = ''
372 for (let i = 0; i < list.length; i++) {
373 let id = list[i].id
374 let coverUrl = list[i].coverUrl
375 let html = `<div id="${id}" class="template" onclick="selectTemplate('${id}')">`
376 html += `<img id="img_${id}" src="${coverUrl}" />`
377 html += '</div>'
378 templates += html
379 }
380 templates += `<div style="width: 100%;padding: 10px;text-align: center;"><button onclick="loadTemplates()">${t('load_more_templates')}</button></div>`
381 document.getElementById('templates').innerHTML = templates
382 selectTemplate(list[0].id)
383 }
384 }
385 }
386 xhr.onerror = function (e) {
387 console.error(e)
388 }
389 }
390 async function selectTemplate(id) {
391 if (templateId) {
392 let ele = document.getElementById(templateId)
393 if (ele) {
394 ele.classList.remove('item_select')
395 }
396 }
397 templateId = id
398 document.getElementById('nextTo3').style.display = 'inline-block'
399 document.getElementById(id).classList.add('item_select')
400 let color = await calcSubjectColor(document.getElementById(`img_${id}`).src)
401 document.body.style.background = color
402 }
403 function nextTo3() {
404 document.body.style.background = null
405 document.getElementById('nextTo3').style.display = 'none'
406 document.getElementById('div2').style.display = 'none'
407 document.getElementById('div3').style.display = 'block'
408 generatePptx()
409 }
410 function generatePptx() {
411 var count = 0
412 var timer = setInterval(() => {
413 count = count + 1
414 document.getElementById('desc').style.display = 'block'
415 document.getElementById('desc_time').innerHTML = count + t('seconds')
416 }, 1000)
417 const url = 'https://docmee.cn/api/public/ppt/generateContent?apiKey=' + apiKey
418 var source = new SSE(url, {
419 method: 'POST',
420 // withCredentials: true,
421 headers: {
422 'Content-Type': 'application/json',
423 'Cache-Control': 'no-cache'
424 },
425 payload: JSON.stringify({ outlineMarkdown: outline, asyncGenPptx: true, templateId }),
426 })
427 source.onmessage = function (data) {
428 let json = JSON.parse(data.data)
429 if (json.status == -1) {
430 alert(t('alert_ppt_error') + json.error)
431 return
432 }
433 if (json.pptId) {
434 document.getElementById('desc_msg').innerText = `${t('generating_progress')} ${json.current}/${json.total},${t('generating_msg')}`
435 asyncGenPptxInfo(json.pptId)
436 }
437 }
438 source.onend = function (data) {
439 if (data.data.startsWith('{') && data.data.endsWith('}')) {
440 const json = JSON.parse(data.data)
441 if (json.code != 0) {
442 alert(t('alert_ppt_error') + json.message)
443 return
444 }
445 }
446 clearInterval(timer)
447 document.getElementById('desc').style.display = 'none'
448 document.getElementById('pptDownload').style.display = 'inline-block'
449 document.getElementById('insert_element').style.display = 'inline-block'
450 drawPptxList()
451 }
452 source.onerror = function (err) {
453 clearInterval(timer)
454 console.error('生成内容异常', err)
455 alert(t('alert_ppt_error'))
456 }
457 source.stream()
458 }
459 function asyncGenPptxInfo(id) {
460 pptxId = id
461 let url = `https://docmee.cn/api/public/ppt/asyncPptInfo?apiKey=${apiKey}&pptId=${pptxId}`
462 let xhr = new XMLHttpRequest()
463 xhr.open('GET', url, true)
464 xhr.send()
465 xhr.onreadystatechange = function () {
466 if (xhr.readyState === 4) {
467 if (xhr.status === 200) {
468 let resp = JSON.parse(xhr.responseText)
469 let gzipBase64 = resp.data.pptxProperty
470 let gzip = base64js.toByteArray(gzipBase64)
471 let json = pako.ungzip(gzip, { to: 'string' })
472 pptxObj = JSON.parse(json)
473 drawPptxList(resp.data.current - 1, true)
474 }
475 }
476 }
477 xhr.onerror = function (e) {
478 console.error(e)
479 document.getElementById('desc').style.display = 'none'
480 }
481 }
482 async function drawPptxList(idx, asyncGen) {
483 if (idx == null || document.getElementById('img_' + idx) == null) {
484 let html = ''
485 for (let i = 0; i < pptxObj.pages.length; i++) {
486 if (asyncGen && i > idx) {
487 break
488 }
489 html += '<div class="left_div_item" onclick="drawPptx(' + i + ')">'
490 html += '<div class="left_div_item_index">' + (i + 1) + '</div>'
491 html += '<canvas id="img_' + i + '" width="288" height="162" style="width: 144px;height: 81px;" class="left_div_item_img" />'
492 html += '</div>'
493 }
494 if (asyncGen && idx < pptxObj.pages.length - 1) {
495 html += '<div class="left_div_item">'
496 html += '<div class="left_div_item_index">' + (idx + 2) + '</div>'
497 html += `<div style="width: 144px;height: 81px;text-align: center;line-height: 81px;color: #666;cursor: default;" class="left_div_item_img">${t('generating_msg')}</div>`
498 html += '</div>'
499 }
500 let itemList = document.getElementById('left_image_list')
501 itemList.innerHTML = html
502 if (asyncGen) {
503 itemList.scrollBy(0, itemList.scrollHeight)
504 }
505 for (let i = 0; i < pptxObj.pages.length; i++) {
506 let imgCanvas = document.getElementById('img_' + i)
507 if (!imgCanvas) {
508 continue
509 }
510 try {
511 let _ppt2Canvas = new Ppt2Canvas(imgCanvas)
512 await _ppt2Canvas.drawPptx(pptxObj, i)
513 } catch(e) {
514 console.log('渲染第' + (i + 1) + '页封面异常', e)
515 }
516 }
517 } else if (idx != null) {
518 try {
519 let imgCanvas = document.getElementById('img_' + idx)
520 let _ppt2Canvas = new Ppt2Canvas(imgCanvas)
521 await _ppt2Canvas.drawPptx(pptxObj, idx)
522 } catch(e) {
523 console.log('渲染第' + (idx + 1) + '页封面异常', e)
524 }
525 }
526
527 drawPptx(idx || 0)
528 }
529 function drawPptx(idx) {
530 if (idx == 0) {
531 document.getElementById('img_0').scrollIntoView(true)
532 }
533 let lastSelect = document.getElementById('img_' + selectIdx)
534 lastSelect && lastSelect.classList.remove('item_select')
535 document.getElementById('right_canvas').style.display = 'block'
536 selectIdx = idx
537 let current = document.getElementById('img_' + idx)
538 current.classList.add('item_select')
539 painter.drawPptx(pptxObj, idx)
540 }
541 function downloadPptx() {
542 let download = document.getElementById('downloadPptx')
543 // 渲染pptx并下载
544 const downloadBtnText = t('download_pptx_btn')
545 if (download.innerText !== downloadBtnText) {
546 return
547 }
548 download.innerText = t('rendering')
549 let animationType = document.getElementById('download_select').value
550 if (animationType != '1' && animationType != '2') {
551 animationType = null
552 }
553 let xhr = new XMLHttpRequest()
554 xhr.responseType = 'blob'
555 xhr.open('POST', 'https://docmee.cn/api/public/ppt/json2ppt?animationType=' + (animationType || '') + '&apiKey=' + apiKey)
556 xhr.setRequestHeader('Content-Type', 'application/json')
557 xhr.onload = function() {
558 if (this.status == 200) {
559 download.innerText = t('download_pptx_btn')
560 let blob = this.response
561 if (blob.type == 'application/json') {
562 const reader = new FileReader()
563 reader.onload = function(e) {
564 let json = JSON.parse(e.target.result)
565 alert(t('alert_download_error') + json.message)
566 }
567 reader.readAsText(blob)
568 return
569 }
570 let a = document.createElement('a')
571 a.href = window.URL.createObjectURL(blob)
572 let name = 'download'
573 let subject = document.getElementById('subject')
574 if (subject && subject.value) {
575 name = subject.value
576 }
577 a.download = name + '.pptx'
578 a.click()
579 }
580 }
581 xhr.onerror = function (e) {
582 console.error(e)
583 download.innerText = t('download_pptx_btn')
584 }
585 xhr.send(JSON.stringify(pptxObj))
586 }
587 async function calcSubjectColor(src) {
588 let img = new Image()
589 await new Promise(resolve => {
590 let eqOrigin = src.startsWith('data:') || src.startsWith(document.location.origin) || (src.startsWith('//') && (document.location.protocol + src).startsWith(document.location.origin))
591 if (!eqOrigin) {
592 img.crossOrigin = 'anonymous'
593 }
594 img.src = src
595 img.onload = function() {
596 resolve(img)
597 }
598 img.onerror = function (e) {
599 resolve()
600 }
601 })
602 let canvas = document.createElement('canvas')
603 let ctx = canvas.getContext('2d')
604 canvas.width = img.width
605 canvas.height = img.height
606 ctx.drawImage(img, 0, 0)
607 let imageData = ctx.getImageData(0, 0, canvas.width, canvas.height)
608 let data = imageData.data
609 let map = {}
610 for (let i = 0; i < data.length; i += 4) {
611 let r = data[i]
612 let g = data[i + 1]
613 let b = data[i + 2]
614 let rgb = r + g + b
615 if (rgb <= 50 || rgb >= 660) {
616 // 忽略黑白
617 continue
618 }
619 let color = `${r},${g},${b}`
620 map[color] = (map[color] || 0) + 1
621 }
622 let valueMap = {}
623 for (let k in map) {
624 let v = map[k]
625 let ks = valueMap[v]
626 if (ks) {
627 ks.push(k)
628 } else {
629 valueMap[v] = [k]
630 }
631 }
632 let colors = []
633 let values = Object.values(map).sort()
634 for (let i = values.length - 1; i >= 0; i--) {
635 let ks = valueMap[values[i]]
636 for (let j = 0; j < ks.length; j++) {
637 colors.push(ks[j])
638 if (colors.length >= 3) {
639 break
640 }
641 }
642 if (colors.length >= 3) {
643 break
644 }
645 }
646 // return `rgb(${colors[0]})`
647 return `linear-gradient(to bottom right, rgb(${colors[0]}), rgb(${colors[1]}), rgb(${colors[2]}))`
648 }
649 function insertElement(type, subType) {
650 let element = null
651 if (type == 'text') {
652 // 文本
653 element = createTextBox(subType)
654 } else if (type == 'image') {
655 // 图片
656 let input = document.createElement('input')
657 input.type = 'file'
658 input.accept = '.jpg,.png'
659 input.onchange = function(e1) {
660 const file = e1.target.files[0]
661 if (!file) return
662 const reader = new FileReader()
663 reader.onload = function(e2) {
664 const base64 = e2.target.result
665 const img = new Image()
666 img.src = base64
667 img.onload = function() {
668 const width = img.width > 300 ? 300 : img.width
669 const height = img.height * (width / img.width)
670 element = createImage(base64, width, height)
671 pptxObj.pages[selectIdx].children.push(element)
672 painter.drawPptx(pptxObj, selectIdx)
673 }
674 }
675 reader.readAsDataURL(file)
676 }
677 input.click()
678 } else if (type == 'geometry') {
679 // 形状
680 let geometryName = subType
681 if (!geometryName) {
682 // 随机形状
683 let keys = Object.keys(geometryMap)
684 geometryName = keys[Math.floor(Math.random() * keys.length)]
685 console.log('geometry', geometryName)
686 }
687 element = createGeometry(geometryName)
688 } else if (type == 'table') {
689 // 表格
690 let rowColumnDataList = [
691 [t('table_cell').replace('{row}', '1').replace('{col}', '1'), t('table_cell').replace('{row}', '1').replace('{col}', '2'), t('table_cell').replace('{row}', '1').replace('{col}', '3')],
692 [t('table_cell').replace('{row}', '2').replace('{col}', '1'), t('table_cell').replace('{row}', '2').replace('{col}', '2'), t('table_cell').replace('{row}', '2').replace('{col}', '3')],
693 [t('table_cell').replace('{row}', '3').replace('{col}', '1'), t('table_cell').replace('{row}', '3').replace('{col}', '2'), t('table_cell').replace('{row}', '3').replace('{col}', '3')]
694 ]
695 element = createTable(rowColumnDataList)
696 } else if (type == 'chart') {
697 // 图表
698 let rowColumnDataList = []
699 if (subType == 'pie' || subType == 'doughnut') {
700 rowColumnDataList = [[' ', t('chart_sales')], [t('chart_q1'), '8.2'], [t('chart_q2'), '3.2'], [t('chart_q3'), '1.4'], [t('chart_q4'), '1.2']]
701 } else {
702 rowColumnDataList = [
703 [' ', t('chart_series').replace('{n}', '1'), t('chart_series').replace('{n}', '2'), t('chart_series').replace('{n}', '3')],
704 [t('chart_category').replace('{n}', '1'), '4.3', '2.4', '2'],
705 [t('chart_category').replace('{n}', '2'), '2.5', '4.4', '2'],
706 [t('chart_category').replace('{n}', '3'), '3.5', '1.8', '3'],
707 [t('chart_category').replace('{n}', '4'), '4.5', '2.8', '5']
708 ]
709 }
710 element = createChart(t('chart_title'), subType, rowColumnDataList)
711 }
712 if (element) {
713 pptxObj.pages[selectIdx].children.push(element)
714 painter.drawPptx(pptxObj, selectIdx)
715 }
716 document.getElementById('insert_element').value = ''
717 }
718 function resetSize() {
719 let width = Math.max(Math.min(document.body.clientWidth - 400, 1600), 480)
720 painter.resetSize(width, width * 0.5625)
721 }
722
723 window.addEventListener('resize', function() {
724 mTimer && clearTimeout(mTimer)
725 mTimer = setTimeout(() => {
726 resetSize()
727 }, 50)
728 })
729
730 // 初始化
731 document.getElementById('div1').style.display = 'block'
732 applyLanguage()
733 resetSize()
734 </script>
735 </body>
736 </html>
736 lines HTML