HtexChart.cs 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825
  1. using DocumentFormat.OpenXml;
  2. using DocumentFormat.OpenXml.Drawing;
  3. using DocumentFormat.OpenXml.Drawing.Charts;
  4. using DocumentFormat.OpenXml.Packaging;
  5. using DocumentFormat.OpenXml.Presentation;
  6. using HTEXLib.Helpers.ShapeHelpers;
  7. using HTEXLib.Models.Inner;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Drawing;
  11. using System.Linq;
  12. using System.Text;
  13. using System.Xml.Linq;
  14. namespace HTEXLib.Models.HTEX
  15. {
  16. public class HtexChart : HtexElement
  17. {
  18. public HtexChart(string id, double rot, double width, double height,
  19. double top, double left, bool invisible,
  20. bool animatable, int index, DocumentFormat.OpenXml.Drawing.Charts.ChartReference Chart, PPTSlide slide, string partForm, string timingId)
  21. {
  22. base.slide = slide;
  23. this.rot = rot;
  24. this.Chart = Chart;
  25. base.id = id;
  26. base.top = top;
  27. base.left = left;
  28. base.width = width;
  29. base.height = height;
  30. base.invisible = invisible;
  31. base.animatable = animatable;
  32. base.index = index;
  33. base.type = "Chart";
  34. base.partForm = partForm;
  35. base.sid = timingId;
  36. }
  37. public ChartPart chartPart { get; set; }
  38. public string VerticalAlign { get; set; }
  39. public DocumentFormat.OpenXml.Drawing.Charts.ChartReference Chart { get; set; }
  40. public override List<Item> DrawElement()
  41. {
  42. var ChartNode = slide.SlidePart.Parts.Where(x => x.RelationshipId == Chart.Id).FirstOrDefault();
  43. var url = ChartNode.OpenXmlPart.Uri.ToString().Replace("../", "/ppt/");
  44. var ChartParts = slide.SlidePart.GetPartsOfType<DocumentFormat.OpenXml.Packaging.ChartPart>();
  45. if (ChartParts != null) {
  46. var chart = ChartParts.Where(x => x.Uri.ToString() == url).FirstOrDefault() ;
  47. chartPart = chart;
  48. if (chart != null) {
  49. ChartColorStylePart ChartColorStylePart = null;
  50. ChartStylePart ChartStylePart = null;
  51. foreach (var idp in chart.Parts) {
  52. if (idp.OpenXmlPart is ChartColorStylePart ChartColorStyleParts) {
  53. ChartColorStylePart = ChartColorStyleParts;
  54. }
  55. if (idp.OpenXmlPart is ChartStylePart ChartStyleParts)
  56. {
  57. ChartStylePart = ChartStyleParts;
  58. }
  59. }
  60. if (ChartStylePart != null) {
  61. var ChartStyleChildren = ChartStylePart.ChartStyle.ChildElements;
  62. foreach (var child in ChartStyleChildren)
  63. {
  64. if (child is DocumentFormat.OpenXml.Office2013.Drawing.ChartStyle.StyleEntry StyleEntry)
  65. {
  66. DoStyleEntry(StyleEntry);
  67. }
  68. ///OfficeArtExtensionList cs: extLst
  69. // MarkerLayoutProperties cs: dataPointMarkerLayout
  70. }
  71. }
  72. Chart charts= DrawChart(chart.ChartSpace);
  73. return new List<Item> { charts };
  74. }
  75. }
  76. return null;
  77. }
  78. public Chart DrawChart(DocumentFormat.OpenXml.Drawing.Charts.ChartSpace chartSpace) {
  79. var Chart = chartSpace.GetFirstChild<DocumentFormat.OpenXml.Drawing.Charts.Chart>();
  80. var ShapeProperties = chartSpace.GetFirstChild<DocumentFormat.OpenXml.Drawing.Charts.ShapeProperties>();
  81. HTEXLib.Models.HTEX.ShapeStyle shapeStyleChart= PPTXHelper.DoShapeProperties(ShapeProperties,slide,type,partForm);
  82. var TextProperties = chartSpace.GetFirstChild<TextProperties>();
  83. var style = chartSpace.GetFirstChild<DocumentFormat.OpenXml.Drawing.Charts.Style>();
  84. var ColorMapOverride = chartSpace.GetFirstChild<DocumentFormat.OpenXml.Drawing.Charts.ColorMapOverride>();
  85. var style2010 = chartSpace.GetFirstChild<DocumentFormat.OpenXml.Office2010.Drawing.Charts.Style>();
  86. var UserShapesReference = chartSpace.GetFirstChild<UserShapesReference>();
  87. var charts = DoPlotArea(Chart.PlotArea);
  88. ShapeStyle shapeStyle = null;
  89. if (Chart.Title != null)
  90. {
  91. var ChartShapeProperties = Chart.Title.ChartShapeProperties;
  92. shapeStyle = PPTXHelper.DoShapeProperties(ChartShapeProperties, slide, type, partForm, chartPart);
  93. }
  94. LinkedList<PPTParagraph> PPTParagraphs= DoChartTitle(Chart.Title);
  95. List<Paragraph> paragraphs = DrawText(PPTParagraphs);
  96. Shape shape= new Shape { type = "Sp", shapeType = "rect", paragraph = paragraphs };
  97. shape.style.fill = shapeStyle != null ? shapeStyle.fill : null;
  98. shape.style.border = shapeStyle != null ? shapeStyle.border : null;
  99. var chart= new Chart {sid=sid, id = this.id, charts =charts,title=shape};
  100. Position position = new Position { cx = width, cy = height, x = left, y = top, rot = rot };
  101. chart.style.position = position;
  102. chart.style.fill = shapeStyleChart != null ? shapeStyleChart.fill : null;
  103. chart.style.border = shapeStyleChart != null ? shapeStyleChart.border : null;
  104. return chart;
  105. }
  106. public LinkedList<PPTParagraph> DoChartTitle(DocumentFormat.OpenXml.Drawing.Charts.Title title)
  107. {
  108. if (title==null ||title.ChartText == null)
  109. {
  110. return null;
  111. }
  112. LinkedList<PPTParagraph> Texts = new LinkedList<PPTParagraph>();
  113. var BodyProperties = title.ChartText.RichText.BodyProperties;
  114. var ListStyle = title.ChartText.RichText.ListStyle;
  115. var Layout = title.Layout;
  116. if (BodyProperties == null)
  117. {
  118. BodyProperties = title.TextProperties.BodyProperties;
  119. }
  120. if (ListStyle != null&& title.TextProperties!=null)
  121. {
  122. ListStyle = title.TextProperties.ListStyle;
  123. }
  124. if (ListStyle != null)
  125. {
  126. //TODO文本层级内容
  127. }
  128. if (BodyProperties.Anchor != null)
  129. {
  130. string VerticalAlign = BodyProperties.Anchor.Value.ToString();
  131. }
  132. int fontScale = 100000;
  133. if (BodyProperties.GetFirstChild<NormalAutoFit>() != null &&
  134. BodyProperties.GetFirstChild<NormalAutoFit>().FontScale != null)
  135. {
  136. fontScale = BodyProperties.GetFirstChild<NormalAutoFit>().FontScale.Value;
  137. }
  138. var ExtensionList = title.ExtensionList;
  139. var Paragraphs = title.ChartText.RichText.Elements<DocumentFormat.OpenXml.Drawing.Paragraph>();
  140. foreach (var paragraph in Paragraphs)
  141. {
  142. PlaceholderShape placeholder = null;
  143. var par = new PPTParagraph(slide, placeholder,partForm)
  144. {
  145. Paragraph = index++
  146. };
  147. if (paragraph.ParagraphProperties != null)
  148. {
  149. int level = paragraph.ParagraphProperties.Level == null ?
  150. -1 : paragraph.ParagraphProperties.Level.Value;
  151. par.Level = level;
  152. }
  153. par.SetParagraphProperties(paragraph, slide.SlidePart,
  154. slide.shapeListStyleMaster, slide.shapeListStyleLayout);
  155. bool hasText = false;
  156. foreach (var obj in paragraph.ChildElements)
  157. {
  158. hasText = GetParagraphChildElements(title.ChartText.RichText, par, hasText, obj, fontScale);
  159. }
  160. //This is because when we set paragraph properties we add the bullet to the text runs.
  161. //If we don't have text it still outputs the bullet character.
  162. if (par.bullet != null && hasText)
  163. {
  164. par.RunPropList.Insert(0, par.bullet);
  165. }
  166. Texts.AddLast(par);
  167. }
  168. return Texts;
  169. }
  170. public List<Paragraph> DrawText(LinkedList<PPTParagraph> Texts)
  171. {
  172. if (Texts == null) {
  173. return null;
  174. }
  175. List<Paragraph> Paragraphs = new List<Paragraph>();
  176. foreach (var par in Texts)
  177. {
  178. double paragraphTop = par.getSpaceBeforePoints();
  179. Paragraph paragraph = new HTEXLib.Paragraph { animatable = par.Animatable, invisible = par.Invisible };
  180. paragraph.style.hori = par.Align;
  181. paragraph.style.vert = VerticalAlign;
  182. if (par.bullet != null)
  183. {
  184. var bullet = par.bullet;
  185. paragraph.buChar = new BuChar
  186. {
  187. type=bullet.BulletType,
  188. left = bullet.Left,
  189. buchar = bullet.Text,
  190. color = bullet.FontColor,
  191. typeface = bullet.FontFamily,
  192. size = bullet.FontSize,
  193. };
  194. }
  195. int newTop = par.getSpaceBeforePoints();
  196. int left = 0;
  197. List<HtexText> textElements = new List<HtexText>();
  198. List<Text> texts = new List<Text>();
  199. if (par.RunPropList == null || par.RunPropList.Count == 0 && par.defaultRunProperties != null) //Only paragraph!
  200. {
  201. float points = float.Parse(par.defaultRunProperties.FontSize.ToString()) * 72.0F / 96.0F;
  202. System.Drawing.Font font = new System.Drawing.Font(par.defaultRunProperties.FontFamily.ToString(), points);
  203. newTop = font.Height;
  204. }
  205. List<HtexText> processedElements = new List<HtexText>();
  206. IEnumerable<PPTRunProperties> pPTRunProperties = breakTextsToShape(par);
  207. foreach (var text in pPTRunProperties)
  208. {
  209. float points = float.Parse(text.FontSize.ToString()) * 72.0F / 96.0F;
  210. System.Drawing.Font font = new System.Drawing.Font(text.FontFamily.ToString(), points);
  211. if (text.Bold) font = new System.Drawing.Font(text.FontFamily.ToString(), points, System.Drawing.FontStyle.Bold);
  212. else if (text.Italic)
  213. font = new System.Drawing.Font(text.FontFamily.ToString(), points, System.Drawing.FontStyle.Italic);
  214. else if (text.Underline != null && text.Underline.Equals("Single"))
  215. font = new System.Drawing.Font(text.FontFamily.ToString(), points, System.Drawing.FontStyle.Underline);
  216. newTop = font.Height > newTop ? font.Height : newTop;
  217. newTop = par.getLineSpacingInPointsFromFont(newTop);
  218. if (text.isBreak)
  219. {
  220. top += newTop;
  221. left = 0;
  222. fixLeftSpacingForAlignment(processedElements, par, font);
  223. processedElements.Clear();
  224. continue;
  225. }
  226. String currentString = text.Text.TrimEnd() + getStringFromTextElements(processedElements);
  227. HtexText t1 = new HtexText(left: left,
  228. top: top,
  229. fontFamily: text.FontFamily,
  230. fontColor: text.FontColor,
  231. fontSize: text.FontSize,
  232. isBullet: text.isBullet,
  233. bold: text.Bold,
  234. italic: text.Italic,
  235. underline: text.Underline,
  236. id: id,
  237. slideIndex: slide.slideIndex)
  238. {
  239. Rotate = this.rot
  240. };
  241. t1.width = MeasureString(text.Text, font);
  242. if (text.isBullet && text.Text != null && text.Text.Contains("rId"))
  243. {
  244. t1.PictureBullet = true;
  245. t1.width = text.bulletSize;
  246. t1.bulletSize = text.bulletSize;
  247. newTop = text.bulletSize;
  248. }
  249. t1.Text = text.Text;
  250. textElements.Add(t1);
  251. texts.Add(new Text
  252. {
  253. content = t1.Text,
  254. link=text.link,
  255. linkType=text.linkType,
  256. style = new FontStyle
  257. {
  258. align = par.FontAlign,
  259. spacing = par.defTabSize,
  260. color = text.FontColor,
  261. family = text.FontFamily,
  262. top = top,
  263. left = left,
  264. size = text.FontSize,
  265. isBullet = text.isBullet,
  266. underline = t1.underline,
  267. italic = text.Italic,
  268. bold = text.Bold,
  269. rot = this.rot,
  270. width = t1.width,
  271. pictureBullet = t1.PictureBullet,
  272. bulletSize = t1.bulletSize
  273. }
  274. });
  275. processedElements.Add(t1);
  276. }
  277. fixLeftSpacingForAlignment(processedElements, par);
  278. HtexText lastTxt = null;
  279. List<HtexText> mergedTextElements = new List<HtexText>();
  280. foreach (HtexText textElement in textElements)
  281. {
  282. if (lastTxt == null || !lastTxt.sameProps(textElement))
  283. mergedTextElements.Add(textElement);
  284. else
  285. mergedTextElements[mergedTextElements.Count - 1].Text += textElement.Text;
  286. lastTxt = textElement;
  287. }
  288. //foreach (HtexText textElement in mergedTextElements) {
  289. // shapeBuilder.Append(textElement.DrawElement());
  290. //}
  291. top += newTop;
  292. top += par.getSpaceAfterPoints(newTop);
  293. top += par.getSpaceBeforePoints(newTop);
  294. paragraph.texts = texts;
  295. Paragraphs.Add(paragraph);
  296. }
  297. return Paragraphs;
  298. }
  299. private String getStringFromTextElements(List<HtexText> elements)
  300. {
  301. if (elements == null || elements.Count == 0)
  302. return "";
  303. StringBuilder result = new StringBuilder();
  304. foreach (HtexText el in elements)
  305. {
  306. result.Append(el.Text);
  307. }
  308. return result.ToString();
  309. }//We have two similar methods - this one is better because it measures the whole string with the font.
  310. private void fixLeftSpacingForAlignment(List<HtexText> textElements, PPTParagraph par, System.Drawing.Font font)
  311. {
  312. int combinedWidth = 0;
  313. StringBuilder combinedText = new StringBuilder();
  314. foreach (HtexText textElement in textElements)
  315. {
  316. if (textElement.PictureBullet)
  317. combinedWidth += textElement.bulletSize;
  318. else
  319. combinedText.Append(textElement.Text);
  320. }
  321. int bulletOffset = 0;
  322. if (par.bullet != null && textElements.Count > 0 && !textElements[0].isBullet)
  323. {
  324. bulletOffset = par.bullet.bulletSize;
  325. combinedWidth += par.bullet.bulletSize;
  326. }
  327. combinedWidth += MeasureString(combinedText.ToString(), font);
  328. double firstLeft = 0;
  329. if ("Center".Equals(par.Align))
  330. firstLeft = ((this.width - par.Indent - bulletOffset - par.marginLeft - par.marginRight) - combinedWidth) / 2;
  331. else if ("Right".Equals(par.Align))
  332. firstLeft = (this.width - par.Indent - bulletOffset - par.marginLeft - par.marginRight) - combinedWidth;
  333. combinedText = new StringBuilder();
  334. combinedWidth = 0; //Now used only for picture bullets!
  335. foreach (HtexText textElement in textElements)
  336. {
  337. textElement.setLeft(firstLeft + par.Indent + bulletOffset + par.marginLeft + combinedWidth + MeasureString(combinedText.ToString(), font));
  338. if (textElement.PictureBullet)
  339. combinedWidth += textElement.bulletSize;
  340. else
  341. combinedText.Append(textElement.Text);
  342. }
  343. }//We have two similar methods. This is worse because it uses the Width property of each element instead of measuring the whole string.
  344. //There is mistake in the calculations coming from that and the difference is bigger when there are more elements.
  345. private void fixLeftSpacingForAlignment(List<HtexText> textElements, PPTParagraph par)
  346. {
  347. int combinedWidth = 0;
  348. foreach (HtexText textElement in textElements)
  349. combinedWidth += textElement.width;
  350. int bulletOffset = 0;
  351. if (par.bullet != null && textElements.Count > 0 && !textElements[0].isBullet)
  352. {
  353. combinedWidth += par.bullet.bulletSize;
  354. bulletOffset = par.bullet.bulletSize;
  355. }
  356. double currentLeft = 0;
  357. if ("Center".Equals(par.Align))
  358. currentLeft = ((this.width - par.Indent - bulletOffset - par.marginLeft - par.marginRight) - combinedWidth) / 2;
  359. else if ("Right".Equals(par.Align))
  360. currentLeft = (this.width - par.Indent - bulletOffset - par.marginLeft - par.marginRight) - combinedWidth;
  361. foreach (HtexText textElement in textElements)
  362. {
  363. textElement.setLeft(currentLeft + par.Indent + bulletOffset + par.marginLeft);
  364. currentLeft += textElement.width;
  365. }
  366. }
  367. private IEnumerable<PPTRunProperties> breakTextsToShape(PPTParagraph par)
  368. {
  369. List<PPTRunProperties> list = par.RunPropList;
  370. List<PPTRunProperties> result = new List<PPTRunProperties>();
  371. String previousToken = null;
  372. int bulletSize = 0;
  373. foreach (var text in list)
  374. {
  375. float points = float.Parse(text.FontSize.ToString()) * 72.0F / 96.0F;
  376. System.Drawing.Font font = new System.Drawing.Font(text.FontFamily.ToString(), points);
  377. if (text.Bold) font = new System.Drawing.Font(text.FontFamily.ToString(), points, System.Drawing.FontStyle.Bold);
  378. else if (text.Italic) font = new System.Drawing.Font(text.FontFamily.ToString(), points, System.Drawing.FontStyle.Italic);
  379. else if (text.Underline != null && text.Underline.Equals("Single"))
  380. font = new System.Drawing.Font(text.FontFamily.ToString(), points, System.Drawing.FontStyle.Underline);
  381. int size = 0;
  382. if (text.isBullet && text.Text != null && text.Text.Contains("rId"))
  383. bulletSize = text.bulletSize;
  384. else
  385. size = MeasureString((previousToken == null ? "" : previousToken + " ") + text.Text, font);
  386. if (text.isBreak || size + bulletSize < this.width - par.Indent - par.marginLeft - par.marginRight)//- Shape.LeftInset - Shape.RightInset)
  387. {
  388. if (text.Text != null && text.Text.Trim() != "" && !(text.isBullet && text.Text.Contains("rId")))
  389. {
  390. previousToken = (previousToken == null ? "" : previousToken) + text.Text;
  391. }
  392. if (text.isBreak)
  393. previousToken = null;
  394. result.Add(text);
  395. continue;
  396. }
  397. // previousToken = null;
  398. string[] tokens = text.Text.Split(' ');
  399. int index = 0;
  400. foreach (string token in tokens)
  401. {
  402. index++;
  403. int combinedSize = MeasureString((previousToken == null ? "" : previousToken + " ") + token, font);
  404. if (combinedSize + bulletSize > this.width - par.Indent - par.marginLeft - par.marginRight)//- Shape.LeftInset - Shape.RightInset)
  405. {
  406. PPTRunProperties temp = new PPTRunProperties(text);
  407. temp.Text = "";
  408. temp.isBreak = true;
  409. result.Add(temp);
  410. temp = new PPTRunProperties(text);
  411. temp.Text = index < tokens.Length ? token + " " : token;
  412. result.Add(temp);
  413. previousToken = token;
  414. }
  415. else
  416. {
  417. PPTRunProperties temp = new PPTRunProperties(text);
  418. temp.Text = index < tokens.Length ? token + " " : token;
  419. result.Add(temp);
  420. previousToken = (previousToken == null ? "" : previousToken + " ") + token;
  421. }
  422. }
  423. }
  424. return result;
  425. }
  426. public static int MeasureString(string s, System.Drawing.Font font)
  427. {
  428. s = s.Replace("\t", "aaaa");//TODO the replace is dirty hack for measuring tabulations
  429. StringFormat stringFormat = new StringFormat(StringFormat.GenericTypographic);
  430. CharacterRange[] rng = { new CharacterRange(0, s.Length) };
  431. stringFormat.SetMeasurableCharacterRanges(rng);
  432. Graphics g = Graphics.FromImage(new Bitmap(100, 100));
  433. //Use measure character ranges with a big box because we used this for measurement only
  434. //Later we might better use this for drawing the text.
  435. Region[] regions = g.MeasureCharacterRanges(s, font, new System.Drawing.Rectangle(0, 0, 10000, 3000), stringFormat);
  436. foreach (Region region in regions)
  437. {
  438. RectangleF rect = region.GetBounds(g);
  439. return (int)System.Math.Round(rect.Width);
  440. }
  441. return 0;
  442. //
  443. // SizeF result;
  444. // using (var image = new Bitmap(1, 1))
  445. // {
  446. // using (var g = Graphics.FromImage(image))
  447. // {
  448. // result = g.MeasureString(s, font);
  449. // }
  450. // }
  451. //
  452. // return result.ToSize();
  453. }
  454. private bool GetParagraphChildElements(RichText shape, PPTParagraph par, bool hasText, OpenXmlElement obj, int fontScale)
  455. {
  456. LinkedList<string> effectShapes = new LinkedList<string>();
  457. if (obj is Run)
  458. {
  459. Run run = (Run)obj;
  460. hasText = true;
  461. PPTRunProperties runProp = new PPTRunProperties(par.defaultRunProperties);
  462. runProp.Text = run.Text.Text;
  463. runProp.SetRunProperties(run.RunProperties, shape, ref effectShapes);
  464. runProp.FontSize = System.Math.Round(fontScale * runProp.FontSize / Globals.PercentageConstant);
  465. par.RunPropList.Add(runProp);
  466. }
  467. else if (obj is Field)
  468. {
  469. Field run = (Field)obj;
  470. hasText = true;
  471. PPTRunProperties runProp = new PPTRunProperties(par.defaultRunProperties);
  472. runProp.Text = run.Text.Text;
  473. runProp.SetRunProperties(run.RunProperties, shape, ref effectShapes);
  474. runProp.FontSize = System.Math.Round(fontScale * runProp.FontSize / Globals.PercentageConstant);
  475. par.RunPropList.Add(runProp);
  476. }
  477. else if (obj is Break)
  478. {
  479. Break aBreak = (Break)obj;
  480. PPTRunProperties runProp = new PPTRunProperties(par.defaultRunProperties);
  481. runProp.SetRunProperties(aBreak.RunProperties, shape, ref effectShapes);
  482. runProp.FontSize = System.Math.Round(fontScale * runProp.FontSize / Globals.PercentageConstant);
  483. runProp.isBreak = true;
  484. par.RunPropList.Add(runProp);
  485. }
  486. return hasText;
  487. }
  488. public List<CommonChart> DoPlotArea(PlotArea plotArea) {
  489. List<CommonChart> charts = new List<CommonChart>();
  490. foreach (var child in plotArea.ChildElements)
  491. {
  492. string key = child.LocalName;
  493. IEnumerable<XElement> serNodes = null;
  494. switch (key)
  495. {
  496. //break块中不可以随意更换,此条件用于归类不同从Chart
  497. case "pieChart":
  498. case "ofPieChart":
  499. case "pie3DChart":
  500. case "doughnutChart":
  501. PieChart pieChart = new PieChart { chartType = "pie" };
  502. if (key.Equals("pie3DChart"))
  503. {
  504. pieChart.is3D = true;
  505. }
  506. pieChart.pieType = key;
  507. if (key.Equals("ofPieChart"))
  508. {
  509. var ofPieType = child.GetTextByPath("c:ofPieType");
  510. if (ofPieType != null)
  511. {
  512. //ofPieChart-pie ofPieChart-bar 子母饼图
  513. pieChart.pieType += "-" + ofPieType.Attribute("val").Value;
  514. }
  515. }
  516. serNodes = child.GetTextByPathList("c:ser");
  517. pieChart.datas = ExtractChartData(serNodes);
  518. charts.Add(pieChart);
  519. break;
  520. case "lineChart":
  521. case "line3DChart":
  522. LineChart lineChart = new LineChart { chartType = "line" };
  523. if (key.Equals("line3DChart"))
  524. {
  525. lineChart.is3D = true;
  526. }
  527. lineChart.lineType = key;
  528. var LineGrouping = child.GetTextByPath("c:grouping");
  529. if (LineGrouping != null)
  530. {
  531. //standard stacked percentStacked
  532. lineChart.lineType += "-" + LineGrouping.Attribute("val").Value;
  533. }
  534. serNodes = child.GetTextByPathList("c:ser");
  535. lineChart.datas = ExtractChartData(serNodes);
  536. charts.Add(lineChart);
  537. break;
  538. case "barChart":
  539. case "bar3DChart":
  540. var barDir = child.GetTextByPath("c:barDir");
  541. if (barDir != null)
  542. {
  543. if (barDir.Attribute("val").Value.Equals("bar"))
  544. {
  545. BarChart barChart = new BarChart { chartType = "bar" };
  546. charts.Add(barChart);
  547. if (key.Equals("bar3DChart"))
  548. {
  549. barChart.is3D = true;
  550. }
  551. barChart.barType = key;
  552. var BarGrouping = child.GetTextByPath("c:grouping");
  553. if (BarGrouping != null)
  554. {
  555. //standard stacked percentStacked
  556. barChart.barType += "-" + BarGrouping.Attribute("val").Value;
  557. }
  558. serNodes = child.GetTextByPathList("c:ser");
  559. barChart.datas = ExtractChartData(serNodes);
  560. charts.Add(barChart);
  561. }
  562. else if (barDir.Attribute("val").Value.Equals("col"))
  563. {
  564. ColChart colChart = new ColChart { chartType = "col" };
  565. if (key.Equals("bar3DChart"))
  566. {
  567. colChart.is3D = true;
  568. }
  569. colChart.colType = key.Replace("bar", "col");
  570. var ColGrouping = child.GetTextByPath("c:grouping");
  571. if (ColGrouping != null)
  572. {
  573. //standard stacked percentStacked
  574. colChart.colType += "-" + ColGrouping.Attribute("val").Value;
  575. }
  576. serNodes = child.GetTextByPathList("c:ser");
  577. colChart.datas = ExtractChartData(serNodes);
  578. charts.Add(colChart);
  579. }
  580. }
  581. break;
  582. case "areaChart":
  583. case "area3DChart":
  584. AreaChart areaChart = new AreaChart { chartType = "area" };
  585. if (key.Equals("area3DChart"))
  586. {
  587. areaChart.is3D = true;
  588. }
  589. areaChart.areaType = key;
  590. var AreaGrouping = child.GetTextByPath("c:grouping");
  591. if (AreaGrouping != null)
  592. {
  593. //standard stacked percentStacked
  594. areaChart.areaType += "-" + AreaGrouping.Attribute("val").Value;
  595. }
  596. serNodes = child.GetTextByPathList("c:ser");
  597. areaChart.datas = ExtractChartData(serNodes);
  598. charts.Add(areaChart);
  599. break;
  600. case "scatterChart":
  601. case "bubbleChart":
  602. ScatterChart scatterChart = new ScatterChart { chartType = "scatter" };
  603. scatterChart.scatterType = key;
  604. if (key.Equals("scatterChart"))
  605. {
  606. var ScatterStyle = child.GetTextByPath("c:scatterStyle");
  607. if (ScatterStyle != null)
  608. {
  609. scatterChart.scatterType += "-" + ScatterStyle.Attribute("val").Value.Replace("Marker", "");
  610. }
  611. }
  612. serNodes = child.GetTextByPathList("c:ser");
  613. scatterChart.datas = ExtractChartData(serNodes);
  614. charts.Add(scatterChart);
  615. break;
  616. case "radarChart":
  617. RadarChart radarChart = new RadarChart { chartType = "radar" };
  618. radarChart.radarType = key;
  619. var RadarStyle = child.GetTextByPath("c:radarStyle");
  620. if (RadarStyle != null)
  621. {
  622. radarChart.radarType += "-" + RadarStyle.Attribute("val").Value;
  623. }
  624. serNodes = child.GetTextByPathList("c:ser");
  625. radarChart.datas = ExtractChartData(serNodes);
  626. charts.Add(radarChart);
  627. break;
  628. case "plotAreaRegion":
  629. PlotAreaChart plotAreaChart = new PlotAreaChart { chartType = "plotArea" };
  630. plotAreaChart.plotAreaType = key;
  631. var PlotSeries = child.GetTextByPath("cx:series");
  632. if (PlotSeries != null)
  633. {
  634. plotAreaChart.plotAreaType += "-" + PlotSeries.Attribute("val").Value;
  635. }
  636. serNodes = child.GetTextByPathList("c:ser");
  637. plotAreaChart.datas = ExtractChartData(serNodes);
  638. charts.Add(plotAreaChart);
  639. break;
  640. case "stockChart":
  641. StockChart stockChart = new StockChart { chartType = "stock" };
  642. stockChart.stockType = key;
  643. serNodes = child.GetTextByPathList("c:ser");
  644. stockChart.datas = ExtractChartData(serNodes);
  645. charts.Add(stockChart);
  646. break;
  647. case "surfaceChart":
  648. case "surface3DChart":
  649. SurfaceChart surfaceChart = new SurfaceChart { chartType = "surface" };
  650. if (key.Equals("surface3DChart"))
  651. {
  652. surfaceChart.is3D = true;
  653. }
  654. surfaceChart.surfaceType = key;
  655. var Wireframe = child.GetTextByPath("c:wireframe");
  656. if (Wireframe != null)
  657. {
  658. surfaceChart.surfaceType += "-" + Wireframe.Attribute("val").Value;
  659. }
  660. serNodes = child.GetTextByPathList("c:ser");
  661. surfaceChart.datas = ExtractChartData(serNodes);
  662. charts.Add(surfaceChart);
  663. break;
  664. }
  665. }
  666. return charts;
  667. }
  668. public List<Dictionary<string, object>> ExtractChartData(IEnumerable<XElement> nodes)
  669. {
  670. if (nodes != null)
  671. {
  672. List<Dictionary<string, object>> listDict = new List<Dictionary<string, object>>();
  673. foreach (XElement node in nodes)
  674. {
  675. if (node.GetTextByPath("c:xVal") != null)
  676. {
  677. Dictionary<string, object> dict = new Dictionary<string, object>();
  678. var xCvNodes = node.GetTextByPathList("c:xVal/c:numRef/c:numCache/c:pt/c:v");
  679. if (xCvNodes != null)
  680. {
  681. List<string> list = new List<string>();
  682. foreach (XElement cvNode in xCvNodes)
  683. {
  684. list.Add(cvNode.Value);
  685. }
  686. dict.Add("xAxis", list);
  687. }
  688. var yCvNodes = node.GetTextByPathList("c:yVal/c:numRef/c:numCache/c:pt/c:v");
  689. if (yCvNodes != null)
  690. {
  691. List<string> list = new List<string>();
  692. foreach (XElement cvNode in yCvNodes)
  693. {
  694. list.Add(cvNode.Value);
  695. }
  696. dict.Add("yAxis", list);
  697. }
  698. dict.Add("colName", "-");
  699. listDict.Add(dict);
  700. }
  701. else
  702. {
  703. Dictionary<string, object> dict = new Dictionary<string, object>();
  704. var spPr = node.GetTextByPath("c:spPr");
  705. if (spPr != null)
  706. {
  707. var ChartShapeProperties = new ChartShapeProperties(spPr.ToString());
  708. ShapeStyle shapeStyle = PPTXHelper.DoShapeProperties(ChartShapeProperties, slide, type, partForm,chartPart);
  709. dict.Add("colStyle", shapeStyle);
  710. }
  711. else {
  712. dict.Add("colStyle", null);
  713. }
  714. var colNameNode = node.GetTextByPath("c:tx/c:strRef/c:strCache/c:pt/c:v");
  715. if (colNameNode != null)
  716. {
  717. dict.Add("colName", colNameNode.Value);
  718. }
  719. //name
  720. var catNodes = node.GetTextByPathList("c:cat/c:strRef/c:strCache/c:pt/c:v");
  721. if (catNodes == null)
  722. {
  723. catNodes = node.GetTextByPathList("c:cat/c:numRef/c:numCache/c:pt/c:v");
  724. }
  725. if (catNodes != null)
  726. {
  727. List<string> list = new List<string>();
  728. foreach (XElement cvNode in catNodes)
  729. {
  730. list.Add(cvNode.Value);
  731. }
  732. dict.Add("xAxis", list);
  733. }
  734. //value
  735. var valNodes = node.GetTextByPathList("c:val/c:numRef/c:numCache/c:pt/c:v");
  736. if (valNodes != null)
  737. {
  738. List<string> list = new List<string>();
  739. foreach (XElement cvNode in valNodes)
  740. {
  741. list.Add(cvNode.Value);
  742. }
  743. dict.Add("yAxis", list);
  744. }
  745. listDict.Add(dict);
  746. }
  747. }
  748. return listDict;
  749. }
  750. return null;
  751. }
  752. public void DoStyleEntry(DocumentFormat.OpenXml.Office2013.Drawing.ChartStyle.StyleEntry StyleEntry)
  753. {
  754. //TODO
  755. /*
  756. * LineReference
  757. LineWidthScale
  758. FillReference
  759. EffectReference
  760. FontReference
  761. ShapeProperties
  762. TextCharacterPropertiesType
  763. TextBodyProperties
  764. OfficeArtExtensionList
  765. * */
  766. var LineReference = StyleEntry.LineReference;
  767. var LineWidthScale= StyleEntry.LineWidthScale;
  768. var FillReference= StyleEntry.FillReference;
  769. var EffectReference = StyleEntry.EffectReference;
  770. var FontReference= StyleEntry.FontReference;
  771. var ShapeProperties = StyleEntry.ShapeProperties;
  772. var TextCharacterPropertiesType = StyleEntry.TextCharacterPropertiesType;
  773. var TextBodyProperties = StyleEntry.TextBodyProperties;
  774. var OfficeArtExtensionList = StyleEntry.OfficeArtExtensionList;
  775. }
  776. }
  777. public class ChartStyle {
  778. //
  779. }
  780. }