ChartElement.cs 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT license.
  3. // See the LICENSE file in the project root for more information.
  4. //
  5. // Purpose: The chart element is base class for the big number
  6. // of classes. It stores common methods and data.
  7. //
  8. using System;
  9. using System.Diagnostics.CodeAnalysis;
  10. using System.Drawing.Drawing2D;
  11. namespace FastReport.DataVisualization.Charting
  12. {
  13. #region Enumerations
  14. /// <summary>
  15. /// An enumeration that specifies a label alignment.
  16. /// </summary>
  17. [
  18. Flags
  19. ]
  20. public enum LabelAlignmentStyles
  21. {
  22. /// <summary>
  23. /// Label is aligned to the top of the data point.
  24. /// </summary>
  25. Top = 1,
  26. /// <summary>
  27. /// Label is aligned to the bottom of the data point.
  28. /// </summary>
  29. Bottom = 2,
  30. /// <summary>
  31. /// Label is aligned to the right of the data point.
  32. /// </summary>
  33. Right = 4,
  34. /// <summary>
  35. /// Label is aligned to the left of the data point.
  36. /// </summary>
  37. Left = 8,
  38. /// <summary>
  39. /// Label is aligned to the top-left corner of the data point.
  40. /// </summary>
  41. TopLeft = 16,
  42. /// <summary>
  43. /// Label is aligned to the top-right corner of the data point.
  44. /// </summary>
  45. TopRight = 32,
  46. /// <summary>
  47. /// Label is aligned to the bottom-left of the data point.
  48. /// </summary>
  49. BottomLeft = 64,
  50. /// <summary>
  51. /// Label is aligned to the bottom-right of the data point.
  52. /// </summary>
  53. BottomRight = 128,
  54. /// <summary>
  55. /// Label is aligned to the center of the data point.
  56. /// </summary>
  57. Center = 256,
  58. }
  59. /// <summary>
  60. /// An enumeration of chart types.
  61. /// </summary>
  62. public enum SeriesChartType
  63. {
  64. /// <summary>
  65. /// Point chart type.
  66. /// </summary>
  67. Point,
  68. /// <summary>
  69. /// FastPoint chart type.
  70. /// </summary>
  71. FastPoint,
  72. /// <summary>
  73. /// Bubble chart type.
  74. /// </summary>
  75. Bubble,
  76. /// <summary>
  77. /// Line chart type.
  78. /// </summary>
  79. Line,
  80. /// <summary>
  81. /// Spline chart type.
  82. /// </summary>
  83. Spline,
  84. /// <summary>
  85. /// StepLine chart type.
  86. /// </summary>
  87. StepLine,
  88. /// <summary>
  89. /// FastLine chart type.
  90. /// </summary>
  91. FastLine,
  92. /// <summary>
  93. /// Bar chart type.
  94. /// </summary>
  95. Bar,
  96. /// <summary>
  97. /// Stacked bar chart type.
  98. /// </summary>
  99. StackedBar,
  100. /// <summary>
  101. /// Hundred percent stacked bar chart type.
  102. /// </summary>
  103. StackedBar100,
  104. /// <summary>
  105. /// Column chart type.
  106. /// </summary>
  107. Column,
  108. /// <summary>
  109. /// Stacked column chart type.
  110. /// </summary>
  111. StackedColumn,
  112. /// <summary>
  113. /// Hundred percent stacked column chart type.
  114. /// </summary>
  115. StackedColumn100,
  116. /// <summary>
  117. /// Area chart type.
  118. /// </summary>
  119. Area,
  120. /// <summary>
  121. /// Spline area chart type.
  122. /// </summary>
  123. SplineArea,
  124. /// <summary>
  125. /// Stacked area chart type.
  126. /// </summary>
  127. StackedArea,
  128. /// <summary>
  129. /// Hundred percent stacked area chart type.
  130. /// </summary>
  131. StackedArea100,
  132. /// <summary>
  133. /// Pie chart type.
  134. /// </summary>
  135. Pie,
  136. /// <summary>
  137. /// Doughnut chart type.
  138. /// </summary>
  139. Doughnut,
  140. /// <summary>
  141. /// Stock chart type.
  142. /// </summary>
  143. Stock,
  144. /// <summary>
  145. /// CandleStick chart type.
  146. /// </summary>
  147. Candlestick,
  148. /// <summary>
  149. /// Range chart type.
  150. /// </summary>
  151. Range,
  152. /// <summary>
  153. /// Spline range chart type.
  154. /// </summary>
  155. SplineRange,
  156. /// <summary>
  157. /// RangeBar chart type.
  158. /// </summary>
  159. RangeBar,
  160. /// <summary>
  161. /// Range column chart type.
  162. /// </summary>
  163. RangeColumn,
  164. /// <summary>
  165. /// Radar chart type.
  166. /// </summary>
  167. Radar,
  168. /// <summary>
  169. /// Polar chart type.
  170. /// </summary>
  171. Polar,
  172. /// <summary>
  173. /// Error bar chart type.
  174. /// </summary>
  175. ErrorBar,
  176. /// <summary>
  177. /// Box plot chart type.
  178. /// </summary>
  179. BoxPlot,
  180. /// <summary>
  181. /// Renko chart type.
  182. /// </summary>
  183. [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Renko")]
  184. Renko,
  185. /// <summary>
  186. /// ThreeLineBreak chart type.
  187. /// </summary>
  188. ThreeLineBreak,
  189. /// <summary>
  190. /// Kagi chart type.
  191. /// </summary>
  192. [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Kagi")]
  193. Kagi,
  194. /// <summary>
  195. /// PointAndFigure chart type.
  196. /// </summary>
  197. PointAndFigure,
  198. /// <summary>
  199. /// Funnel chart type.
  200. /// </summary>
  201. Funnel,
  202. /// <summary>
  203. /// Pyramid chart type.
  204. /// </summary>
  205. Pyramid,
  206. }
  207. /// <summary>
  208. /// Axis Arrow orientation
  209. /// </summary>
  210. internal enum ArrowOrientation
  211. {
  212. /// <summary>
  213. /// Arrow direction is Right - Left
  214. /// </summary>
  215. Left,
  216. /// <summary>
  217. /// Arrow direction is Left - Right
  218. /// </summary>
  219. Right,
  220. /// <summary>
  221. /// Arrow direction is Bottom - Top
  222. /// </summary>
  223. Top,
  224. /// <summary>
  225. /// Arrow direction is Top - Bottom
  226. /// </summary>
  227. Bottom
  228. }
  229. /// <summary>
  230. /// An enumeration of image alignment.
  231. /// </summary>
  232. public enum ChartImageAlignmentStyle
  233. {
  234. /// <summary>
  235. /// The mage is aligned to the top left corner of the chart element.
  236. /// </summary>
  237. TopLeft,
  238. /// <summary>
  239. /// The image is aligned to the top boundary of the chart element.
  240. /// </summary>
  241. Top,
  242. /// <summary>
  243. /// The image is aligned to the top right corner of the chart element.
  244. /// </summary>
  245. TopRight,
  246. /// <summary>
  247. /// The image is aligned to the right boundary of the chart element.
  248. /// </summary>
  249. Right,
  250. /// <summary>
  251. /// The image is aligned to the bottom right corner of the chart element.
  252. /// </summary>
  253. BottomRight,
  254. /// <summary>
  255. /// The image is aligned to the bottom boundary of the chart element.
  256. /// </summary>
  257. Bottom,
  258. /// <summary>
  259. /// The image is aligned to the bottom left corner of the chart element.
  260. /// </summary>
  261. BottomLeft,
  262. /// <summary>
  263. /// The image is aligned to the left boundary of the chart element.
  264. /// </summary>
  265. Left,
  266. /// <summary>
  267. /// The image is aligned in the center of the chart element.
  268. /// </summary>
  269. Center
  270. };
  271. /// <summary>
  272. /// An enumeration that specifies a background image drawing mode.
  273. /// </summary>
  274. public enum ChartImageWrapMode
  275. {
  276. /// <summary>
  277. /// Background image is scaled to fit the entire chart element.
  278. /// </summary>
  279. Scaled = WrapMode.Clamp,
  280. /// <summary>
  281. /// Background image is tiled to fit the entire chart element.
  282. /// </summary>
  283. Tile = WrapMode.Tile,
  284. /// <summary>
  285. /// Every other tiled image is reversed around the X-axis.
  286. /// </summary>
  287. TileFlipX = WrapMode.TileFlipX,
  288. /// <summary>
  289. /// Every other tiled image is reversed around the X-axis and Y-axis.
  290. /// </summary>
  291. TileFlipXY = WrapMode.TileFlipXY,
  292. /// <summary>
  293. /// Every other tiled image is reversed around the Y-axis.
  294. /// </summary>
  295. TileFlipY = WrapMode.TileFlipY,
  296. /// <summary>
  297. /// Background image is not scaled.
  298. /// </summary>
  299. [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Unscaled")]
  300. Unscaled = 100
  301. };
  302. /// <summary>
  303. /// An enumeration that specifies the state of an axis.
  304. /// </summary>
  305. public enum AxisEnabled
  306. {
  307. /// <summary>
  308. /// The axis is only enabled if it used to plot a Series.
  309. /// </summary>
  310. Auto,
  311. /// <summary>
  312. /// The axis is always enabled.
  313. /// </summary>
  314. True,
  315. /// <summary>
  316. /// The axis is never enabled.
  317. /// </summary>
  318. False
  319. };
  320. /// <summary>
  321. /// An enumeration of units of measurement of an interval.
  322. /// </summary>
  323. public enum DateTimeIntervalType
  324. {
  325. /// <summary>
  326. /// Automatically determined by the Chart control.
  327. /// </summary>
  328. Auto,
  329. /// <summary>
  330. /// The interval is numerical.
  331. /// </summary>
  332. Number,
  333. /// <summary>
  334. /// The interval is years.
  335. /// </summary>
  336. Years,
  337. /// <summary>
  338. /// The interval is months.
  339. /// </summary>
  340. Months,
  341. /// <summary>
  342. /// The interval is weeks.
  343. /// </summary>
  344. Weeks,
  345. /// <summary>
  346. /// The interval is days.
  347. /// </summary>
  348. Days,
  349. /// <summary>
  350. /// The interval is hours.
  351. /// </summary>
  352. Hours,
  353. /// <summary>
  354. /// The interval is minutes.
  355. /// </summary>
  356. Minutes,
  357. /// <summary>
  358. /// The interval is seconds.
  359. /// </summary>
  360. Seconds,
  361. /// <summary>
  362. /// The interval is milliseconds.
  363. /// </summary>
  364. Milliseconds,
  365. /// <summary>
  366. /// The interval type is not defined.
  367. /// </summary>
  368. NotSet,
  369. }
  370. /// <summary>
  371. /// An enumeration that specifies value types for various chart properties
  372. /// </summary>
  373. public enum ChartValueType
  374. {
  375. /// <summary>
  376. /// Property type is set automatically by the Chart control.
  377. /// </summary>
  378. Auto,
  379. /// <summary>
  380. /// Double value.
  381. /// </summary>
  382. Double,
  383. /// <summary>
  384. /// Single value.
  385. /// </summary>
  386. Single,
  387. /// <summary>
  388. /// Int32 value.
  389. /// </summary>
  390. Int32,
  391. /// <summary>
  392. /// Int64 value.
  393. /// </summary>
  394. Int64,
  395. /// <summary>
  396. /// UInt32 value.
  397. /// </summary>
  398. [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly",
  399. Justification = "These names are patterned after the standard CLR types for consistency")]
  400. UInt32,
  401. /// <summary>
  402. /// UInt64 value.
  403. /// </summary>
  404. [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly",
  405. Justification = "These names are patterned after the standard CLR types for consistency")]
  406. UInt64,
  407. /// <summary>
  408. /// String value.
  409. /// </summary>
  410. String,
  411. /// <summary>
  412. /// DateTime value.
  413. /// </summary>
  414. DateTime,
  415. /// <summary>
  416. /// Date portion of the DateTime value.
  417. /// </summary>
  418. Date,
  419. /// <summary>
  420. /// Time portion of the DateTime value.
  421. /// </summary>
  422. Time,
  423. /// <summary>
  424. /// DateTime with offset
  425. /// </summary>
  426. DateTimeOffset
  427. };
  428. /// <summary>
  429. /// An enumeration that specifies a hatching style.
  430. /// </summary>
  431. public enum ChartHatchStyle
  432. {
  433. /// <summary>
  434. /// No hatching style.
  435. /// </summary>
  436. None,
  437. /// <summary>
  438. /// Backward diagonal style.
  439. /// </summary>
  440. BackwardDiagonal,
  441. /// <summary>
  442. /// Cross style.
  443. /// </summary>
  444. Cross,
  445. /// <summary>
  446. /// Dark downward diagonal style.
  447. /// </summary>
  448. DarkDownwardDiagonal,
  449. /// <summary>
  450. /// Dark horizontal style.
  451. /// </summary>
  452. DarkHorizontal,
  453. /// <summary>
  454. /// Dark upward diagonal style.
  455. /// </summary>
  456. DarkUpwardDiagonal,
  457. /// <summary>
  458. /// Dark vertical style.
  459. /// </summary>
  460. DarkVertical,
  461. /// <summary>
  462. /// Dashed downward diagonal style.
  463. /// </summary>
  464. DashedDownwardDiagonal,
  465. /// <summary>
  466. /// Dashed horizontal style.
  467. /// </summary>
  468. DashedHorizontal,
  469. /// <summary>
  470. /// Dashed upward diagonal style.
  471. /// </summary>
  472. DashedUpwardDiagonal,
  473. /// <summary>
  474. /// Dashed vertical style.
  475. /// </summary>
  476. DashedVertical,
  477. /// <summary>
  478. /// Diagonal brick style.
  479. /// </summary>
  480. DiagonalBrick,
  481. /// <summary>
  482. /// Diagonal cross style.
  483. /// </summary>
  484. DiagonalCross,
  485. /// <summary>
  486. /// Divot style.
  487. /// </summary>
  488. Divot,
  489. /// <summary>
  490. /// Dotted diamond style.
  491. /// </summary>
  492. DottedDiamond,
  493. /// <summary>
  494. /// Dotted grid style.
  495. /// </summary>
  496. DottedGrid,
  497. /// <summary>
  498. /// Forward diagonal style.
  499. /// </summary>
  500. ForwardDiagonal,
  501. /// <summary>
  502. /// Horizontal style.
  503. /// </summary>
  504. Horizontal,
  505. /// <summary>
  506. /// Horizontal brick style.
  507. /// </summary>
  508. HorizontalBrick,
  509. /// <summary>
  510. /// Large checker board style.
  511. /// </summary>
  512. [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "CheckerBoard")]
  513. LargeCheckerBoard,
  514. /// <summary>
  515. /// Large confetti style.
  516. /// </summary>
  517. LargeConfetti,
  518. /// <summary>
  519. /// Large grid style.
  520. /// </summary>
  521. LargeGrid,
  522. /// <summary>
  523. /// Light downward diagonal style.
  524. /// </summary>
  525. LightDownwardDiagonal,
  526. /// <summary>
  527. /// Light horizontal style.
  528. /// </summary>
  529. LightHorizontal,
  530. /// <summary>
  531. /// Light upward diagonal style.
  532. /// </summary>
  533. LightUpwardDiagonal,
  534. /// <summary>
  535. /// Light vertical style.
  536. /// </summary>
  537. LightVertical,
  538. /// <summary>
  539. /// Narrow horizontal style.
  540. /// </summary>
  541. NarrowHorizontal,
  542. /// <summary>
  543. /// Narrow vertical style.
  544. /// </summary>
  545. NarrowVertical,
  546. /// <summary>
  547. /// Outlined diamond style.
  548. /// </summary>
  549. OutlinedDiamond,
  550. /// <summary>
  551. /// Percent05 style.
  552. /// </summary>
  553. Percent05,
  554. /// <summary>
  555. /// Percent10 style.
  556. /// </summary>
  557. Percent10,
  558. /// <summary>
  559. /// Percent20 style.
  560. /// </summary>
  561. Percent20,
  562. /// <summary>
  563. /// Percent25 style.
  564. /// </summary>
  565. Percent25,
  566. /// <summary>
  567. /// Percent30 style.
  568. /// </summary>
  569. Percent30,
  570. /// <summary>
  571. /// Percent40 style.
  572. /// </summary>
  573. Percent40,
  574. /// <summary>
  575. /// Percent50 style.
  576. /// </summary>
  577. Percent50,
  578. /// <summary>
  579. /// Percent60 style.
  580. /// </summary>
  581. Percent60,
  582. /// <summary>
  583. /// Percent70 style.
  584. /// </summary>
  585. Percent70,
  586. /// <summary>
  587. /// Percent75 style.
  588. /// </summary>
  589. Percent75,
  590. /// <summary>
  591. /// Percent80 style.
  592. /// </summary>
  593. Percent80,
  594. /// <summary>
  595. /// Percent90 style.
  596. /// </summary>
  597. Percent90,
  598. /// <summary>
  599. /// Plaid style.
  600. /// </summary>
  601. Plaid,
  602. /// <summary>
  603. /// Shingle style.
  604. /// </summary>
  605. Shingle,
  606. /// <summary>
  607. /// Small checker board style.
  608. /// </summary>
  609. [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "CheckerBoard")]
  610. SmallCheckerBoard,
  611. /// <summary>
  612. /// Small confetti style.
  613. /// </summary>
  614. SmallConfetti,
  615. /// <summary>
  616. /// Small grid style.
  617. /// </summary>
  618. SmallGrid,
  619. /// <summary>
  620. /// Solid diamond style.
  621. /// </summary>
  622. SolidDiamond,
  623. /// <summary>
  624. /// Sphere style.
  625. /// </summary>
  626. Sphere,
  627. /// <summary>
  628. /// Trellis style.
  629. /// </summary>
  630. Trellis,
  631. /// <summary>
  632. /// Vertical style.
  633. /// </summary>
  634. Vertical,
  635. /// <summary>
  636. /// Wave style.
  637. /// </summary>
  638. Wave,
  639. /// <summary>
  640. /// Weave style.
  641. /// </summary>
  642. Weave,
  643. /// <summary>
  644. /// Wide downward diagonal style.
  645. /// </summary>
  646. WideDownwardDiagonal,
  647. /// <summary>
  648. /// Wide upward diagonal style.
  649. /// </summary>
  650. WideUpwardDiagonal,
  651. /// <summary>
  652. /// ZigZag style.
  653. /// </summary>
  654. [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "ZigZag")]
  655. [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Zig")]
  656. [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Zag")]
  657. ZigZag
  658. };
  659. /// <summary>
  660. /// An enumeration that specifies the level of anti-aliasing quality.
  661. /// </summary>
  662. public enum TextAntiAliasingQuality
  663. {
  664. /// <summary>
  665. /// Normal anti-aliasing quality.
  666. /// </summary>
  667. Normal,
  668. /// <summary>
  669. /// High anti-aliasing quality.
  670. /// </summary>
  671. High,
  672. /// <summary>
  673. /// System default anti-aliasing quality.
  674. /// </summary>
  675. SystemDefault
  676. }
  677. /// <summary>
  678. /// An enumeration of anti-aliasing flags.
  679. /// </summary>
  680. [Flags]
  681. public enum AntiAliasingStyles
  682. {
  683. /// <summary>
  684. /// No anti-aliasing.
  685. /// </summary>
  686. None = 0,
  687. /// <summary>
  688. /// Use anti-aliasing when drawing text.
  689. /// </summary>
  690. Text = 1,
  691. /// <summary>
  692. /// Use anti-aliasing when drawing grahics primitives (e.g. lines, rectangle)
  693. /// </summary>
  694. Graphics = 2,
  695. /// <summary>
  696. /// Use anti-alias for everything.
  697. /// </summary>
  698. All = Text | Graphics
  699. };
  700. /// <summary>
  701. /// An enumeration of marker styles.
  702. /// </summary>
  703. public enum MarkerStyle
  704. {
  705. /// <summary>
  706. /// No marker is displayed for the series/data point.
  707. /// </summary>
  708. None = 0,
  709. /// <summary>
  710. /// A square marker is displayed.
  711. /// </summary>
  712. Square = 1,
  713. /// <summary>
  714. /// A circle marker is displayed.
  715. /// </summary>
  716. Circle = 2,
  717. /// <summary>
  718. /// A diamond-shaped marker is displayed.
  719. /// </summary>
  720. Diamond = 3,
  721. /// <summary>
  722. /// A triangular marker is displayed.
  723. /// </summary>
  724. Triangle = 4,
  725. /// <summary>
  726. /// A cross-shaped marker is displayed.
  727. /// </summary>
  728. Cross = 5,
  729. /// <summary>
  730. /// A 4-point star-shaped marker is displayed.
  731. /// </summary>
  732. Star4 = 6,
  733. /// <summary>
  734. /// A 5-point star-shaped marker is displayed.
  735. /// </summary>
  736. Star5 = 7,
  737. /// <summary>
  738. /// A 6-point star-shaped marker is displayed.
  739. /// </summary>
  740. Star6 = 8,
  741. /// <summary>
  742. /// A 10-point star-shaped marker is displayed.
  743. /// </summary>
  744. Star10 = 9
  745. };
  746. /// <summary>
  747. /// An enumeration of gradient styles.
  748. /// </summary>
  749. public enum GradientStyle
  750. {
  751. /// <summary>
  752. /// No gradient is used.
  753. /// </summary>
  754. None,
  755. /// <summary>
  756. /// Gradient is applied from left to right.
  757. /// </summary>
  758. LeftRight,
  759. /// <summary>
  760. /// Gradient is applied from top to bottom.
  761. /// </summary>
  762. TopBottom,
  763. /// <summary>
  764. /// Gradient is applied from the center outwards.
  765. /// </summary>
  766. Center,
  767. /// <summary>
  768. /// Gradient is applied diagonally from left to right.
  769. /// </summary>
  770. DiagonalLeft,
  771. /// <summary>
  772. /// Gradient is applied diagonally from right to left.
  773. /// </summary>
  774. DiagonalRight,
  775. /// <summary>
  776. /// Gradient is applied horizontally from the center outwards.
  777. /// </summary>
  778. HorizontalCenter,
  779. /// <summary>
  780. /// Gradient is applied vertically from the center outwards.
  781. /// </summary>
  782. VerticalCenter
  783. };
  784. #endregion
  785. #region ChartElement
  786. /// <summary>
  787. /// Common chart helper methods used across different chart elements.
  788. /// </summary>
  789. internal class ChartHelper
  790. {
  791. #region Fields
  792. /// <summary>
  793. /// Maximum number of grid lines per Axis
  794. /// </summary>
  795. internal const int MaxNumOfGridlines = 10000;
  796. #endregion // Fields
  797. #region Constructor
  798. /// <summary>
  799. /// Private constructor to avoid instantiating the class
  800. /// </summary>
  801. private ChartHelper() { }
  802. #endregion // Constructor
  803. #region Methods
  804. /// <summary>
  805. /// Adjust the beginnin of the first interval depending on the type and size.
  806. /// </summary>
  807. /// <param name="start">Original start point.</param>
  808. /// <param name="intervalSize">Interval size.</param>
  809. /// <param name="type">AxisName of the interval (Month, Year, ...).</param>
  810. /// <returns>Adjusted interval start position as double.</returns>
  811. internal static double AlignIntervalStart(double start, double intervalSize, DateTimeIntervalType type)
  812. {
  813. return AlignIntervalStart(start, intervalSize, type, null);
  814. }
  815. /// <summary>
  816. /// Adjust the beginnin of the first interval depending on the type and size.
  817. /// </summary>
  818. /// <param name="start">Original start point.</param>
  819. /// <param name="intervalSize">Interval size.</param>
  820. /// <param name="type">AxisName of the interval (Month, Year, ...).</param>
  821. /// <param name="series">First series connected to the axis.</param>
  822. /// <returns>Adjusted interval start position as double.</returns>
  823. internal static double AlignIntervalStart(double start, double intervalSize, DateTimeIntervalType type, Series series)
  824. {
  825. return AlignIntervalStart( start, intervalSize, type, series, true );
  826. }
  827. /// <summary>
  828. /// Adjust the beginnin of the first interval depending on the type and size.
  829. /// </summary>
  830. /// <param name="start">Original start point.</param>
  831. /// <param name="intervalSize">Interval size.</param>
  832. /// <param name="type">AxisName of the interval (Month, Year, ...).</param>
  833. /// <param name="series">First series connected to the axis.</param>
  834. /// <param name="majorInterval">Interval is used for major gridlines or tickmarks.</param>
  835. /// <returns>Adjusted interval start position as double.</returns>
  836. internal static double AlignIntervalStart(double start, double intervalSize, DateTimeIntervalType type, Series series, bool majorInterval)
  837. {
  838. // Special case for indexed series
  839. if(series != null && series.IsXValueIndexed)
  840. {
  841. if(type == DateTimeIntervalType.Auto ||
  842. type == DateTimeIntervalType.Number)
  843. {
  844. if( majorInterval )
  845. {
  846. return 1;
  847. }
  848. else
  849. {
  850. return 0;
  851. }
  852. }
  853. return -(series.Points.Count + 1);
  854. }
  855. // Non indexed series
  856. else
  857. {
  858. // Do not adjust start position for these interval type
  859. if(type == DateTimeIntervalType.Auto ||
  860. type == DateTimeIntervalType.Number)
  861. {
  862. return start;
  863. }
  864. // Get the beginning of the interval depending on type
  865. DateTime newStartDate = DateTime.FromOADate(start);
  866. // Adjust the months interval depending on size
  867. if(intervalSize > 0.0 && intervalSize != 1.0)
  868. {
  869. if(type == DateTimeIntervalType.Months && intervalSize <= 12.0 && intervalSize > 1)
  870. {
  871. // Make sure that the beginning is aligned correctly for cases
  872. // like quarters and half years
  873. DateTime resultDate = newStartDate;
  874. DateTime sizeAdjustedDate = new DateTime(newStartDate.Year, 1, 1, 0, 0, 0);
  875. while(sizeAdjustedDate < newStartDate)
  876. {
  877. resultDate = sizeAdjustedDate;
  878. sizeAdjustedDate = sizeAdjustedDate.AddMonths((int)intervalSize);
  879. }
  880. newStartDate = resultDate;
  881. return newStartDate.ToOADate();
  882. }
  883. }
  884. // Check interval type
  885. switch(type)
  886. {
  887. case(DateTimeIntervalType.Years):
  888. int year = (int)((int)(newStartDate.Year / intervalSize) * intervalSize);
  889. if(year <= 0)
  890. {
  891. year = 1;
  892. }
  893. newStartDate = new DateTime(year,
  894. 1, 1, 0, 0, 0);
  895. break;
  896. case(DateTimeIntervalType.Months):
  897. int month = (int)((int)(newStartDate.Month / intervalSize) * intervalSize);
  898. if(month <= 0)
  899. {
  900. month = 1;
  901. }
  902. newStartDate = new DateTime(newStartDate.Year,
  903. month, 1, 0, 0, 0);
  904. break;
  905. case(DateTimeIntervalType.Days):
  906. int day = (int)((int)(newStartDate.Day / intervalSize) * intervalSize);
  907. if(day <= 0)
  908. {
  909. day = 1;
  910. }
  911. newStartDate = new DateTime(newStartDate.Year,
  912. newStartDate.Month, day, 0, 0, 0);
  913. break;
  914. case(DateTimeIntervalType.Hours):
  915. int hour = (int)((int)(newStartDate.Hour / intervalSize) * intervalSize);
  916. newStartDate = new DateTime(newStartDate.Year,
  917. newStartDate.Month, newStartDate.Day, hour, 0, 0);
  918. break;
  919. case(DateTimeIntervalType.Minutes):
  920. int minute = (int)((int)(newStartDate.Minute / intervalSize) * intervalSize);
  921. newStartDate = new DateTime(newStartDate.Year,
  922. newStartDate.Month,
  923. newStartDate.Day,
  924. newStartDate.Hour,
  925. minute,
  926. 0);
  927. break;
  928. case(DateTimeIntervalType.Seconds):
  929. int second = (int)((int)(newStartDate.Second / intervalSize) * intervalSize);
  930. newStartDate = new DateTime(newStartDate.Year,
  931. newStartDate.Month,
  932. newStartDate.Day,
  933. newStartDate.Hour,
  934. newStartDate.Minute,
  935. second,
  936. 0);
  937. break;
  938. case(DateTimeIntervalType.Milliseconds):
  939. int milliseconds = (int)((int)(newStartDate.Millisecond / intervalSize) * intervalSize);
  940. newStartDate = new DateTime(newStartDate.Year,
  941. newStartDate.Month,
  942. newStartDate.Day,
  943. newStartDate.Hour,
  944. newStartDate.Minute,
  945. newStartDate.Second,
  946. milliseconds);
  947. break;
  948. case(DateTimeIntervalType.Weeks):
  949. // NOTE: Code below was changed to fix issue #5962
  950. // Elements that have interval set to weeks should be aligned to the
  951. // nearest Monday no matter how many weeks is the interval.
  952. //newStartDate = newStartDate.AddDays(-((int)newStartDate.DayOfWeek * intervalSize));
  953. newStartDate = newStartDate.AddDays(-((int)newStartDate.DayOfWeek));
  954. newStartDate = new DateTime(newStartDate.Year,
  955. newStartDate.Month, newStartDate.Day, 0, 0, 0);
  956. break;
  957. }
  958. return newStartDate.ToOADate();
  959. }
  960. }
  961. /// <summary>
  962. /// Gets interval size as double number.
  963. /// </summary>
  964. /// <param name="current">Current value.</param>
  965. /// <param name="interval">Interval size.</param>
  966. /// <param name="type">AxisName of the interval (Month, Year, ...).</param>
  967. /// <returns>Interval size as double.</returns>
  968. internal static double GetIntervalSize(double current, double interval, DateTimeIntervalType type)
  969. {
  970. return GetIntervalSize(
  971. current,
  972. interval,
  973. type,
  974. null,
  975. 0,
  976. DateTimeIntervalType.Number,
  977. true,
  978. true);
  979. }
  980. /// <summary>
  981. /// Gets interval size as double number.
  982. /// </summary>
  983. /// <param name="current">Current value.</param>
  984. /// <param name="interval">Interval size.</param>
  985. /// <param name="type">AxisName of the interval (Month, Year, ...).</param>
  986. /// <param name="series">First series connected to the axis.</param>
  987. /// <param name="intervalOffset">Offset size.</param>
  988. /// <param name="intervalOffsetType">Offset type(Month, Year, ...).</param>
  989. /// <param name="forceIntIndex">Force Integer indexed</param>
  990. /// <returns>Interval size as double.</returns>
  991. internal static double GetIntervalSize(
  992. double current,
  993. double interval,
  994. DateTimeIntervalType type,
  995. Series series,
  996. double intervalOffset,
  997. DateTimeIntervalType intervalOffsetType,
  998. bool forceIntIndex)
  999. {
  1000. return GetIntervalSize(
  1001. current,
  1002. interval,
  1003. type,
  1004. series,
  1005. intervalOffset,
  1006. intervalOffsetType,
  1007. forceIntIndex,
  1008. true);
  1009. }
  1010. /// <summary>
  1011. /// Gets interval size as double number.
  1012. /// </summary>
  1013. /// <param name="current">Current value.</param>
  1014. /// <param name="interval">Interval size.</param>
  1015. /// <param name="type">AxisName of the interval (Month, Year, ...).</param>
  1016. /// <param name="series">First series connected to the axis.</param>
  1017. /// <param name="intervalOffset">Offset size.</param>
  1018. /// <param name="intervalOffsetType">Offset type(Month, Year, ...).</param>
  1019. /// <param name="forceIntIndex">Force Integer indexed</param>
  1020. /// <param name="forceAbsInterval">Force Integer indexed</param>
  1021. /// <returns>Interval size as double.</returns>
  1022. internal static double GetIntervalSize(
  1023. double current,
  1024. double interval,
  1025. DateTimeIntervalType type,
  1026. Series series,
  1027. double intervalOffset,
  1028. DateTimeIntervalType intervalOffsetType,
  1029. bool forceIntIndex,
  1030. bool forceAbsInterval)
  1031. {
  1032. // AxisName is not date.
  1033. if( type == DateTimeIntervalType.Number || type == DateTimeIntervalType.Auto )
  1034. {
  1035. return interval;
  1036. }
  1037. // Special case for indexed series
  1038. if(series != null && series.IsXValueIndexed)
  1039. {
  1040. // Check point index
  1041. int pointIndex = (int)Math.Ceiling(current - 1);
  1042. if(pointIndex < 0)
  1043. {
  1044. pointIndex = 0;
  1045. }
  1046. if(pointIndex >= series.Points.Count || series.Points.Count <= 1)
  1047. {
  1048. return interval;
  1049. }
  1050. // Get starting and ending values of the closest interval
  1051. double adjuster = 0;
  1052. double xValue = series.Points[pointIndex].XValue;
  1053. xValue = AlignIntervalStart(xValue, 1, type, null);
  1054. double xEndValue = xValue + GetIntervalSize(xValue, interval, type);
  1055. xEndValue += GetIntervalSize(xEndValue, intervalOffset, intervalOffsetType);
  1056. xValue += GetIntervalSize(xValue, intervalOffset, intervalOffsetType);
  1057. if(intervalOffset < 0)
  1058. {
  1059. xValue = xValue + GetIntervalSize(xValue, interval, type);
  1060. xEndValue = xEndValue + GetIntervalSize(xEndValue, interval, type);
  1061. }
  1062. // The first point in the series
  1063. if(pointIndex == 0 && current < 0)
  1064. {
  1065. // Round the first point value depending on the interval type
  1066. DateTime dateValue = DateTime.FromOADate(series.Points[pointIndex].XValue);
  1067. DateTime roundedDateValue = dateValue;
  1068. switch(type)
  1069. {
  1070. case(DateTimeIntervalType.Years): // Ignore hours,...
  1071. roundedDateValue = new DateTime(dateValue.Year,
  1072. dateValue.Month, dateValue.Day, 0, 0, 0);
  1073. break;
  1074. case(DateTimeIntervalType.Months): // Ignore hours,...
  1075. roundedDateValue = new DateTime(dateValue.Year,
  1076. dateValue.Month, dateValue.Day, 0, 0, 0);
  1077. break;
  1078. case(DateTimeIntervalType.Days): // Ignore hours,...
  1079. roundedDateValue = new DateTime(dateValue.Year,
  1080. dateValue.Month, dateValue.Day, 0, 0, 0);
  1081. break;
  1082. case(DateTimeIntervalType.Hours): //
  1083. roundedDateValue = new DateTime(dateValue.Year,
  1084. dateValue.Month, dateValue.Day, dateValue.Hour,
  1085. dateValue.Minute, 0);
  1086. break;
  1087. case(DateTimeIntervalType.Minutes):
  1088. roundedDateValue = new DateTime(dateValue.Year,
  1089. dateValue.Month,
  1090. dateValue.Day,
  1091. dateValue.Hour,
  1092. dateValue.Minute,
  1093. dateValue.Second);
  1094. break;
  1095. case(DateTimeIntervalType.Seconds):
  1096. roundedDateValue = new DateTime(dateValue.Year,
  1097. dateValue.Month,
  1098. dateValue.Day,
  1099. dateValue.Hour,
  1100. dateValue.Minute,
  1101. dateValue.Second,
  1102. 0);
  1103. break;
  1104. case(DateTimeIntervalType.Weeks):
  1105. roundedDateValue = new DateTime(dateValue.Year,
  1106. dateValue.Month, dateValue.Day, 0, 0, 0);
  1107. break;
  1108. }
  1109. // The first point value is exactly on the interval boundaries
  1110. if(roundedDateValue.ToOADate() == xValue || roundedDateValue.ToOADate() == xEndValue)
  1111. {
  1112. return - current + 1;
  1113. }
  1114. }
  1115. // Adjuster of 0.5 means that position should be between points
  1116. ++pointIndex;
  1117. while(pointIndex < series.Points.Count)
  1118. {
  1119. if(series.Points[pointIndex].XValue >= xEndValue)
  1120. {
  1121. if(series.Points[pointIndex].XValue > xEndValue && !forceIntIndex)
  1122. {
  1123. adjuster = -0.5;
  1124. }
  1125. break;
  1126. }
  1127. ++pointIndex;
  1128. }
  1129. // If last point outside of the max series index
  1130. if(pointIndex == series.Points.Count)
  1131. {
  1132. pointIndex += series.Points.Count/5 + 1;
  1133. }
  1134. double size = (pointIndex + 1) - current + adjuster;
  1135. return (size != 0) ? size : interval;
  1136. }
  1137. // Non indexed series
  1138. else
  1139. {
  1140. DateTime date = DateTime.FromOADate(current);
  1141. TimeSpan span = new TimeSpan(0);
  1142. if(type == DateTimeIntervalType.Days)
  1143. {
  1144. span = TimeSpan.FromDays(interval);
  1145. }
  1146. else if(type == DateTimeIntervalType.Hours)
  1147. {
  1148. span = TimeSpan.FromHours(interval);
  1149. }
  1150. else if(type == DateTimeIntervalType.Milliseconds)
  1151. {
  1152. span = TimeSpan.FromMilliseconds(interval);
  1153. }
  1154. else if(type == DateTimeIntervalType.Seconds)
  1155. {
  1156. span = TimeSpan.FromSeconds(interval);
  1157. }
  1158. else if(type == DateTimeIntervalType.Minutes)
  1159. {
  1160. span = TimeSpan.FromMinutes(interval);
  1161. }
  1162. else if(type == DateTimeIntervalType.Weeks)
  1163. {
  1164. span = TimeSpan.FromDays(7.0 * interval);
  1165. }
  1166. else if(type == DateTimeIntervalType.Months)
  1167. {
  1168. // Special case handling when current date points
  1169. // to the last day of the month
  1170. bool lastMonthDay = false;
  1171. if(date.Day == DateTime.DaysInMonth(date.Year, date.Month))
  1172. {
  1173. lastMonthDay = true;
  1174. }
  1175. // Add specified amount of months
  1176. date = date.AddMonths((int)Math.Floor(interval));
  1177. span = TimeSpan.FromDays(30.0 * ( interval - Math.Floor(interval) ));
  1178. // Check if last month of the day was used
  1179. if(lastMonthDay && span.Ticks == 0)
  1180. {
  1181. // Make sure the last day of the month is selected
  1182. int daysInMobth = DateTime.DaysInMonth(date.Year, date.Month);
  1183. date = date.AddDays(daysInMobth - date.Day);
  1184. }
  1185. }
  1186. else if(type == DateTimeIntervalType.Years)
  1187. {
  1188. date = date.AddYears((int)Math.Floor(interval));
  1189. span = TimeSpan.FromDays(365.0 * ( interval - Math.Floor(interval) ));
  1190. }
  1191. // Check if an absolute interval size must be returned
  1192. double result = date.Add(span).ToOADate() - current;
  1193. if(forceAbsInterval)
  1194. {
  1195. result = Math.Abs(result);
  1196. }
  1197. return result;
  1198. }
  1199. }
  1200. /// <summary>
  1201. /// Check if series is indexed. IsXValueIndexed flag is set or all X values are zeros.
  1202. /// </summary>
  1203. /// <param name="series">Data series to test.</param>
  1204. /// <returns>True if series is indexed.</returns>
  1205. static internal bool IndexedSeries( Series series)
  1206. {
  1207. // X value indexed flag set
  1208. if (series.IsXValueIndexed)
  1209. {
  1210. return true;
  1211. }
  1212. if (Utilities.CustomPropertyRegistry.IsXAxisQuantitativeChartTypes.Contains(series.ChartType) &&
  1213. series.IsCustomPropertySet(Utilities.CustomPropertyName.IsXAxisQuantitative))
  1214. {
  1215. string attribValue = series[Utilities.CustomPropertyName.IsXAxisQuantitative];
  1216. if (String.Compare(attribValue, "True", StringComparison.OrdinalIgnoreCase) == 0)
  1217. {
  1218. return false;
  1219. }
  1220. }
  1221. // Check if series has all X values set to zero
  1222. return SeriesXValuesZeros(series);
  1223. }
  1224. /// <summary>
  1225. /// Check if all data points in the series have X value set to 0.
  1226. /// </summary>
  1227. /// <param name="series">Data series to check.</param>
  1228. static private bool SeriesXValuesZeros( Series series )
  1229. {
  1230. // Check if X value zeros check was already done
  1231. if(series.xValuesZerosChecked)
  1232. {
  1233. return series.xValuesZeros;
  1234. }
  1235. // Data point loop
  1236. series.xValuesZerosChecked = true;
  1237. series.xValuesZeros = true;
  1238. foreach( DataPoint point in series.Points )
  1239. {
  1240. if( point.XValue != 0.0 )
  1241. {
  1242. // If any data point has value different than 0 return false
  1243. series.xValuesZeros = false;
  1244. break;
  1245. }
  1246. }
  1247. return series.xValuesZeros;
  1248. }
  1249. /// <summary>
  1250. /// Check if any series is indexed. IsXValueIndexed flag is set or all X values are zeros.
  1251. /// </summary>
  1252. /// <param name="common">Reference to common chart classes.</param>
  1253. /// <param name="series">Data series names.</param>
  1254. /// <returns>True if any series is indexed.</returns>
  1255. static internal bool IndexedSeries(CommonElements common, params string[] series)
  1256. {
  1257. // Data series loop
  1258. bool zeroXValues = true;
  1259. foreach (string ser in series)
  1260. {
  1261. Series localSeries = common.DataManager.Series[ser];
  1262. // Check series indexed flag
  1263. if (localSeries.IsXValueIndexed)
  1264. {
  1265. // If flag set in at least one series - all series are indexed
  1266. return true;
  1267. }
  1268. // Check if series has all X values set to zero
  1269. if (zeroXValues && !IndexedSeries(localSeries))
  1270. {
  1271. zeroXValues = false;
  1272. }
  1273. }
  1274. return zeroXValues;
  1275. }
  1276. /// <summary>
  1277. /// Check if all data points in many series have X value set to 0.
  1278. /// </summary>
  1279. /// <param name="common">Reference to common chart classes.</param>
  1280. /// <param name="series">Data series.</param>
  1281. /// <returns>True if all data points have value 0.</returns>
  1282. static internal bool SeriesXValuesZeros(CommonElements common, params string[] series)
  1283. {
  1284. // Data series loop
  1285. foreach( string ser in series )
  1286. {
  1287. // Check one series X values
  1288. if(!SeriesXValuesZeros(common.DataManager.Series[ ser ]))
  1289. {
  1290. return false;
  1291. }
  1292. }
  1293. return true;
  1294. }
  1295. #endregion
  1296. }
  1297. #endregion //ChartElement
  1298. }