zui 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (325) hide show
  1. checksums.yaml +7 -0
  2. data/Components/Builtins/Accordion.qml +208 -0
  3. data/Components/Builtins/Action.qml +43 -0
  4. data/Components/Builtins/ActionButton.qml +19 -0
  5. data/Components/Builtins/ActionGroup.qml +81 -0
  6. data/Components/Builtins/AlertDialog.qml +398 -0
  7. data/Components/Builtins/AnchorAnimation.qml +3 -0
  8. data/Components/Builtins/AnchorChanges.qml +11 -0
  9. data/Components/Builtins/AnimatedImage.qml +39 -0
  10. data/Components/Builtins/Animation.qml +3 -0
  11. data/Components/Builtins/AnimationController.qml +11 -0
  12. data/Components/Builtins/ApplicationWindow.qml +103 -0
  13. data/Components/Builtins/AreaChart.qml +70 -0
  14. data/Components/Builtins/AspectRatio.qml +30 -0
  15. data/Components/Builtins/Audio.qml +85 -0
  16. data/Components/Builtins/AudioInput.qml +10 -0
  17. data/Components/Builtins/AudioOutput.qml +10 -0
  18. data/Components/Builtins/Avatar.qml +46 -0
  19. data/Components/Builtins/Badge.qml +38 -0
  20. data/Components/Builtins/Banner.qml +133 -0
  21. data/Components/Builtins/BarChart.qml +67 -0
  22. data/Components/Builtins/BarIconButton.qml +30 -0
  23. data/Components/Builtins/BarIndicator.qml +26 -0
  24. data/Components/Builtins/Behavior.qml +13 -0
  25. data/Components/Builtins/Blur.qml +14 -0
  26. data/Components/Builtins/BorderImage.qml +38 -0
  27. data/Components/Builtins/BorderOverlay.qml +25 -0
  28. data/Components/Builtins/BottomSheet.qml +211 -0
  29. data/Components/Builtins/Breadcrumb.qml +169 -0
  30. data/Components/Builtins/BubbleChart.qml +3 -0
  31. data/Components/Builtins/BusyIndicator.qml +24 -0
  32. data/Components/Builtins/Button.qml +55 -0
  33. data/Components/Builtins/ButtonGroup.qml +18 -0
  34. data/Components/Builtins/Calendar.qml +55 -0
  35. data/Components/Builtins/Camera.qml +18 -0
  36. data/Components/Builtins/CandlestickChart.qml +3 -0
  37. data/Components/Builtins/Canvas.qml +159 -0
  38. data/Components/Builtins/CaptureSession.qml +19 -0
  39. data/Components/Builtins/Card.qml +23 -0
  40. data/Components/Builtins/Carousel.qml +72 -0
  41. data/Components/Builtins/Center.qml +20 -0
  42. data/Components/Builtins/CheckDelegate.qml +132 -0
  43. data/Components/Builtins/Checkbox.qml +62 -0
  44. data/Components/Builtins/Chip.qml +65 -0
  45. data/Components/Builtins/Circle.qml +35 -0
  46. data/Components/Builtins/Clipboard.qml +29 -0
  47. data/Components/Builtins/ColorAnimation.qml +3 -0
  48. data/Components/Builtins/ColorPicker.qml +70 -0
  49. data/Components/Builtins/Colorize.qml +14 -0
  50. data/Components/Builtins/Column.qml +17 -0
  51. data/Components/Builtins/ColumnLayout.qml +13 -0
  52. data/Components/Builtins/ConfirmDialog.qml +20 -0
  53. data/Components/Builtins/ConstrainedBox.qml +28 -0
  54. data/Components/Builtins/Container.qml +30 -0
  55. data/Components/Builtins/ContextMenu.qml +140 -0
  56. data/Components/Builtins/CursorSurface.qml +18 -0
  57. data/Components/Builtins/DataTable.qml +69 -0
  58. data/Components/Builtins/DatePicker.qml +180 -0
  59. data/Components/Builtins/DayOfWeekRow.qml +11 -0
  60. data/Components/Builtins/DelayButton.qml +47 -0
  61. data/Components/Builtins/DelegateModel.qml +10 -0
  62. data/Components/Builtins/DelegateModelGroup.qml +10 -0
  63. data/Components/Builtins/Dial.qml +42 -0
  64. data/Components/Builtins/Dialog.qml +128 -0
  65. data/Components/Builtins/DialogButtonBox.qml +137 -0
  66. data/Components/Builtins/Divider.qml +26 -0
  67. data/Components/Builtins/DonutChart.qml +3 -0
  68. data/Components/Builtins/DoubleSpinBox.qml +58 -0
  69. data/Components/Builtins/DragArea.qml +43 -0
  70. data/Components/Builtins/Drawer.qml +107 -0
  71. data/Components/Builtins/DropArea.qml +19 -0
  72. data/Components/Builtins/DropShadow.qml +16 -0
  73. data/Components/Builtins/Dropdown.qml +19 -0
  74. data/Components/Builtins/ExpansionPanel.qml +157 -0
  75. data/Components/Builtins/FilePicker.qml +140 -0
  76. data/Components/Builtins/FittedBox.qml +40 -0
  77. data/Components/Builtins/Flickable.qml +40 -0
  78. data/Components/Builtins/Flipable.qml +45 -0
  79. data/Components/Builtins/Flow.qml +16 -0
  80. data/Components/Builtins/FocusScope.qml +29 -0
  81. data/Components/Builtins/FolderListModel.qml +9 -0
  82. data/Components/Builtins/FolderPicker.qml +93 -0
  83. data/Components/Builtins/FontLoader.qml +21 -0
  84. data/Components/Builtins/FontPicker.qml +91 -0
  85. data/Components/Builtins/Frame.qml +71 -0
  86. data/Components/Builtins/FrameAnimation.qml +13 -0
  87. data/Components/Builtins/Gauge.qml +3 -0
  88. data/Components/Builtins/Glow.qml +15 -0
  89. data/Components/Builtins/Gradient.qml +93 -0
  90. data/Components/Builtins/Grid.qml +16 -0
  91. data/Components/Builtins/GridLayout.qml +16 -0
  92. data/Components/Builtins/GridView.qml +226 -0
  93. data/Components/Builtins/GroupBox.qml +95 -0
  94. data/Components/Builtins/Heatmap.qml +3 -0
  95. data/Components/Builtins/Histogram.qml +3 -0
  96. data/Components/Builtins/HorizontalHeader.qml +23 -0
  97. data/Components/Builtins/HorizontalHeaderDelegate.qml +39 -0
  98. data/Components/Builtins/HoverArea.qml +19 -0
  99. data/Components/Builtins/Icon.qml +16 -0
  100. data/Components/Builtins/Image.qml +110 -0
  101. data/Components/Builtins/ImageCapture.qml +14 -0
  102. data/Components/Builtins/ItemDelegate.qml +152 -0
  103. data/Components/Builtins/KeyCatcher.qml +25 -0
  104. data/Components/Builtins/Label.qml +43 -0
  105. data/Components/Builtins/LayoutItemProxy.qml +51 -0
  106. data/Components/Builtins/Legend.qml +86 -0
  107. data/Components/Builtins/Line.qml +28 -0
  108. data/Components/Builtins/LineChart.qml +87 -0
  109. data/Components/Builtins/ListModel.qml +8 -0
  110. data/Components/Builtins/ListView.qml +65 -0
  111. data/Components/Builtins/Loader.qml +33 -0
  112. data/Components/Builtins/Markdown.qml +23 -0
  113. data/Components/Builtins/MediaDevices.qml +10 -0
  114. data/Components/Builtins/MediaPlayer.qml +27 -0
  115. data/Components/Builtins/MediaRecorder.qml +16 -0
  116. data/Components/Builtins/Menu.qml +119 -0
  117. data/Components/Builtins/MenuBar.qml +128 -0
  118. data/Components/Builtins/MenuItem.qml +77 -0
  119. data/Components/Builtins/MenuSeparator.qml +30 -0
  120. data/Components/Builtins/MessageDialog.qml +104 -0
  121. data/Components/Builtins/ModalSheet.qml +222 -0
  122. data/Components/Builtins/ModelView3d.qml +50 -0
  123. data/Components/Builtins/MonthGrid.qml +23 -0
  124. data/Components/Builtins/MultiEffect.qml +48 -0
  125. data/Components/Builtins/MultiSelect.qml +23 -0
  126. data/Components/Builtins/NavigationRail.qml +154 -0
  127. data/Components/Builtins/NumberAnimation.qml +3 -0
  128. data/Components/Builtins/NumberField.qml +18 -0
  129. data/Components/Builtins/OpacityAnimator.qml +3 -0
  130. data/Components/Builtins/OpacityMask.qml +21 -0
  131. data/Components/Builtins/OpticalGlyph.qml +16 -0
  132. data/Components/Builtins/Page.qml +111 -0
  133. data/Components/Builtins/PageIndicator.qml +63 -0
  134. data/Components/Builtins/Pagination.qml +158 -0
  135. data/Components/Builtins/Pane.qml +72 -0
  136. data/Components/Builtins/PanelHero.qml +15 -0
  137. data/Components/Builtins/ParallelAnimation.qml +3 -0
  138. data/Components/Builtins/ParentAnimation.qml +3 -0
  139. data/Components/Builtins/ParentChange.qml +10 -0
  140. data/Components/Builtins/ParticleSystem.qml +81 -0
  141. data/Components/Builtins/PasswordField.qml +58 -0
  142. data/Components/Builtins/Path.qml +35 -0
  143. data/Components/Builtins/PathAnimation.qml +3 -0
  144. data/Components/Builtins/PauseAnimation.qml +3 -0
  145. data/Components/Builtins/PieChart.qml +3 -0
  146. data/Components/Builtins/PinchArea.qml +23 -0
  147. data/Components/Builtins/Popup.qml +130 -0
  148. data/Components/Builtins/Progress.qml +15 -0
  149. data/Components/Builtins/ProgressRing.qml +120 -0
  150. data/Components/Builtins/PropertyAction.qml +11 -0
  151. data/Components/Builtins/PropertyAnimation.qml +3 -0
  152. data/Components/Builtins/PropertyChanges.qml +10 -0
  153. data/Components/Builtins/RadarChart.qml +3 -0
  154. data/Components/Builtins/RadialGauge.qml +3 -0
  155. data/Components/Builtins/RadioButton.qml +46 -0
  156. data/Components/Builtins/RadioDelegate.qml +115 -0
  157. data/Components/Builtins/RadioGroup.qml +58 -0
  158. data/Components/Builtins/RangeSlider.qml +39 -0
  159. data/Components/Builtins/Rectangle.qml +23 -0
  160. data/Components/Builtins/RectangularShadow.qml +23 -0
  161. data/Components/Builtins/ReorderableList.qml +204 -0
  162. data/Components/Builtins/RichText.qml +23 -0
  163. data/Components/Builtins/RotationAnimation.qml +3 -0
  164. data/Components/Builtins/RotationAnimator.qml +3 -0
  165. data/Components/Builtins/RoundButton.qml +42 -0
  166. data/Components/Builtins/Row.qml +17 -0
  167. data/Components/Builtins/RowLayout.qml +13 -0
  168. data/Components/Builtins/ScaleAnimator.qml +3 -0
  169. data/Components/Builtins/ScatterChart.qml +3 -0
  170. data/Components/Builtins/ScreenCapture.qml +78 -0
  171. data/Components/Builtins/ScriptAction.qml +15 -0
  172. data/Components/Builtins/Scroll.qml +18 -0
  173. data/Components/Builtins/ScrollBar.qml +18 -0
  174. data/Components/Builtins/ScrollIndicator.qml +15 -0
  175. data/Components/Builtins/SearchField.qml +178 -0
  176. data/Components/Builtins/SearchableDropdown.qml +21 -0
  177. data/Components/Builtins/SectionHeader.qml +14 -0
  178. data/Components/Builtins/SelectableText.qml +33 -0
  179. data/Components/Builtins/SelectionRectangle.qml +17 -0
  180. data/Components/Builtins/Separator.qml +13 -0
  181. data/Components/Builtins/SequentialAnimation.qml +3 -0
  182. data/Components/Builtins/Settings.qml +10 -0
  183. data/Components/Builtins/ShaderEffect.qml +115 -0
  184. data/Components/Builtins/ShaderEffectSource.qml +61 -0
  185. data/Components/Builtins/Shaders/grayscale.frag +14 -0
  186. data/Components/Builtins/Shaders/grayscale.frag.qsb +0 -0
  187. data/Components/Builtins/Shaders/passthrough.frag +11 -0
  188. data/Components/Builtins/Shaders/passthrough.frag.qsb +0 -0
  189. data/Components/Builtins/Shaders/pixelate.frag +16 -0
  190. data/Components/Builtins/Shaders/pixelate.frag.qsb +0 -0
  191. data/Components/Builtins/Shaders/vignette.frag +18 -0
  192. data/Components/Builtins/Shaders/vignette.frag.qsb +0 -0
  193. data/Components/Builtins/Shaders/wave.frag +18 -0
  194. data/Components/Builtins/Shaders/wave.frag.qsb +0 -0
  195. data/Components/Builtins/Shape.qml +53 -0
  196. data/Components/Builtins/Skeleton.qml +78 -0
  197. data/Components/Builtins/Slider.qml +21 -0
  198. data/Components/Builtins/SmoothedAnimation.qml +3 -0
  199. data/Components/Builtins/Snackbar.qml +181 -0
  200. data/Components/Builtins/SortFilterProxyModel.qml +16 -0
  201. data/Components/Builtins/SoundEffect.qml +10 -0
  202. data/Components/Builtins/Spacer.qml +13 -0
  203. data/Components/Builtins/Sparkline.qml +3 -0
  204. data/Components/Builtins/SpinBox.qml +44 -0
  205. data/Components/Builtins/SplitView.qml +31 -0
  206. data/Components/Builtins/SpringAnimation.qml +3 -0
  207. data/Components/Builtins/Stack.qml +14 -0
  208. data/Components/Builtins/StackLayout.qml +19 -0
  209. data/Components/Builtins/StackView.qml +122 -0
  210. data/Components/Builtins/StackedBarChart.qml +3 -0
  211. data/Components/Builtins/StandardPaths.qml +9 -0
  212. data/Components/Builtins/State.qml +13 -0
  213. data/Components/Builtins/StateGroup.qml +11 -0
  214. data/Components/Builtins/Support/AnimationDriver.qml +79 -0
  215. data/Components/Builtins/Support/AnimationGroupDriver.qml +32 -0
  216. data/Components/Builtins/Support/ChartCanvas.qml +629 -0
  217. data/Components/Builtins/Support/ModelView3dScene.qml +292 -0
  218. data/Components/Builtins/Support/OptionalModuleState.js +5 -0
  219. data/Components/Builtins/SwipeDelegate.qml +231 -0
  220. data/Components/Builtins/SwipeView.qml +69 -0
  221. data/Components/Builtins/SwitchDelegate.qml +140 -0
  222. data/Components/Builtins/TabBar.qml +117 -0
  223. data/Components/Builtins/TabButton.qml +105 -0
  224. data/Components/Builtins/TableView.qml +388 -0
  225. data/Components/Builtins/TableViewDelegate.qml +17 -0
  226. data/Components/Builtins/Tabs.qml +138 -0
  227. data/Components/Builtins/Text.qml +24 -0
  228. data/Components/Builtins/TextArea.qml +59 -0
  229. data/Components/Builtins/TextField.qml +21 -0
  230. data/Components/Builtins/TextMetrics.qml +39 -0
  231. data/Components/Builtins/TimePicker.qml +213 -0
  232. data/Components/Builtins/Timer.qml +13 -0
  233. data/Components/Builtins/Toast.qml +213 -0
  234. data/Components/Builtins/Toggle.qml +19 -0
  235. data/Components/Builtins/ToggleSwitch.qml +22 -0
  236. data/Components/Builtins/ToolBar.qml +61 -0
  237. data/Components/Builtins/ToolButton.qml +41 -0
  238. data/Components/Builtins/ToolSeparator.qml +36 -0
  239. data/Components/Builtins/Tooltip.qml +20 -0
  240. data/Components/Builtins/Transition.qml +3 -0
  241. data/Components/Builtins/TreeView.qml +423 -0
  242. data/Components/Builtins/TreeViewDelegate.qml +46 -0
  243. data/Components/Builtins/Tumbler.qml +18 -0
  244. data/Components/Builtins/UniformAnimator.qml +3 -0
  245. data/Components/Builtins/VectorAnimation.qml +3 -0
  246. data/Components/Builtins/VectorImage.qml +62 -0
  247. data/Components/Builtins/VerticalHeader.qml +21 -0
  248. data/Components/Builtins/VerticalHeaderDelegate.qml +35 -0
  249. data/Components/Builtins/Video.qml +54 -0
  250. data/Components/Builtins/VideoOutput.qml +54 -0
  251. data/Components/Builtins/WebView.qml +57 -0
  252. data/Components/Builtins/WeekNumberColumn.qml +13 -0
  253. data/Components/Builtins/WidgetButton.qml +26 -0
  254. data/Components/Builtins/Window.qml +90 -0
  255. data/Components/Builtins/WindowCapture.qml +11 -0
  256. data/Components/Builtins/Wrap.qml +18 -0
  257. data/Components/Builtins/XAnimator.qml +3 -0
  258. data/Components/Builtins/YAnimator.qml +3 -0
  259. data/Components/README.md +45 -0
  260. data/ControlNode.qml +1369 -0
  261. data/Controls/BarIconButton.qml +27 -0
  262. data/Controls/BarIndicator.qml +22 -0
  263. data/Controls/BorderOverlay.qml +10 -0
  264. data/Controls/BorderSurface.qml +10 -0
  265. data/Controls/Button.qml +78 -0
  266. data/Controls/ButtonGroup.qml +19 -0
  267. data/Controls/ConfirmDialog.qml +37 -0
  268. data/Controls/CursorSurface.qml +29 -0
  269. data/Controls/Dropdown.qml +59 -0
  270. data/Controls/MultiSelect.qml +32 -0
  271. data/Controls/NumberField.qml +24 -0
  272. data/Controls/OpticalGlyph.qml +14 -0
  273. data/Controls/PanelActionButton.qml +10 -0
  274. data/Controls/PanelHero.qml +18 -0
  275. data/Controls/PanelKeyCatcher.qml +25 -0
  276. data/Controls/PanelSectionHeader.qml +11 -0
  277. data/Controls/PanelSeparator.qml +10 -0
  278. data/Controls/PanelSlider.qml +36 -0
  279. data/Controls/PanelToolTip.qml +13 -0
  280. data/Controls/SearchableDropdown.qml +11 -0
  281. data/Controls/TextField.qml +25 -0
  282. data/Controls/Toggle.qml +22 -0
  283. data/Controls/ToggleSwitch.qml +26 -0
  284. data/Controls/WidgetButton.qml +35 -0
  285. data/Controls/qmldir +25 -0
  286. data/Desktop.qml +76 -0
  287. data/LICENSE +22 -0
  288. data/README.md +112 -0
  289. data/Service.qml +430 -0
  290. data/Theme/Border.qml +22 -0
  291. data/Theme/Color.qml +22 -0
  292. data/Theme/Style.qml +47 -0
  293. data/Theme/Util.qml +6 -0
  294. data/Theme/qmldir +5 -0
  295. data/bin/zui +7 -0
  296. data/lib/zui/animation.rb +24 -0
  297. data/lib/zui/application.rb +327 -0
  298. data/lib/zui/builder.rb +725 -0
  299. data/lib/zui/cli.rb +91 -0
  300. data/lib/zui/command.rb +101 -0
  301. data/lib/zui/component_registry.rb +91 -0
  302. data/lib/zui/components.rb +262 -0
  303. data/lib/zui/distribution.rb +200 -0
  304. data/lib/zui/generator.rb +84 -0
  305. data/lib/zui/host.rb +123 -0
  306. data/lib/zui/node.rb +30 -0
  307. data/lib/zui/platform.rb +40 -0
  308. data/lib/zui/protocol.rb +29 -0
  309. data/lib/zui/runner.rb +37 -0
  310. data/lib/zui/runtime.rb +23 -0
  311. data/lib/zui/scheduler.rb +136 -0
  312. data/lib/zui/source_bundle.rb +63 -0
  313. data/lib/zui/state_store.rb +100 -0
  314. data/lib/zui/value.rb +44 -0
  315. data/lib/zui.rb +33 -0
  316. data/native/CMakeLists.txt +45 -0
  317. data/native/ZuiClipboard.cpp +16 -0
  318. data/native/ZuiClipboard.h +16 -0
  319. data/native/ZuiProcess.cpp +84 -0
  320. data/native/ZuiProcess.h +34 -0
  321. data/native/main.cpp +64 -0
  322. data/vendor/host/linux-x86_64/PROVENANCE.md +15 -0
  323. data/vendor/host/linux-x86_64/zui-host +0 -0
  324. data/vendor/host/linux-x86_64/zui-host.sha256 +1 -0
  325. metadata +365 -0
@@ -0,0 +1,629 @@
1
+ import QtQuick
2
+ import "../../../Theme"
3
+
4
+ Item {
5
+ id: chartRoot
6
+
7
+ required property var renderer
8
+ required property string chartType
9
+
10
+ function colors() {
11
+ var result = renderer.prop("colors", []);
12
+ return Array.isArray(result) && result.length > 0 ? result : [renderer.prop("color", Color.accent), "#e0af68", "#9ece6a", "#bb9af7", "#f7768e", "#7dcfff"];
13
+ }
14
+
15
+ function numericValues() {
16
+ var values = renderer.prop("values", []);
17
+ return Array.isArray(values) ? values.map(function(value) {
18
+ return Number(value && value.value !== undefined ? value.value : value);
19
+ }) : [];
20
+ }
21
+
22
+ function bounds(values, requestedMin, requestedMax) {
23
+ var low = renderer.prop(requestedMin, null);
24
+ var high = renderer.prop(requestedMax, null);
25
+ if (low === null)
26
+ low = values.length ? Math.min.apply(Math, values) : 0;
27
+
28
+ if (high === null)
29
+ high = values.length ? Math.max.apply(Math, values) : 1;
30
+
31
+ low = Number(low);
32
+ high = Number(high);
33
+ if (low === high) {
34
+ low -= 1;
35
+ high += 1;
36
+ }
37
+ return {
38
+ "low": low,
39
+ "high": high
40
+ };
41
+ }
42
+
43
+ function pointValue(point, key, index, fallback) {
44
+ if (Array.isArray(point))
45
+ return Number(point[index] === undefined ? fallback : point[index]);
46
+
47
+ if (point && typeof point === "object")
48
+ return Number(point[key] === undefined ? fallback : point[key]);
49
+
50
+ return Number(fallback);
51
+ }
52
+
53
+ function textStyle(ctx, color) {
54
+ ctx.fillStyle = color || renderer.prop("label_color", renderer.foreground);
55
+ ctx.font = Number(renderer.prop("font_size", 12)) + "px " + String(renderer.prop("font_family", renderer.fontFamily));
56
+ ctx.textAlign = "center";
57
+ ctx.textBaseline = "middle";
58
+ }
59
+
60
+ function labelAt(index, fallback) {
61
+ var labels = renderer.prop("labels", []);
62
+ return Array.isArray(labels) && index < labels.length ? String(labels[index]) : String(fallback);
63
+ }
64
+
65
+ function drawGrid(ctx, pad) {
66
+ if (renderer.prop("show_grid", true) === false)
67
+ return ;
68
+
69
+ ctx.strokeStyle = renderer.prop("grid_color", Qt.rgba(1, 1, 1, 0.15));
70
+ ctx.lineWidth = 1;
71
+ for (var line = 0; line <= 4; line++) {
72
+ var y = pad + (height - 2 * pad) * line / 4;
73
+ ctx.beginPath();
74
+ ctx.moveTo(pad, y);
75
+ ctx.lineTo(width - pad, y);
76
+ ctx.stroke();
77
+ }
78
+ }
79
+
80
+ function drawPie(ctx, donut) {
81
+ var values = numericValues();
82
+ var total = values.reduce(function(sum, value) {
83
+ return sum + Math.max(0, value);
84
+ }, 0);
85
+ if (total <= 0)
86
+ return ;
87
+
88
+ var palette = colors();
89
+ var cx = width / 2;
90
+ var cy = height / 2;
91
+ var radius = Math.max(1, Math.min(width, height) / 2 - 8);
92
+ var angle = Number(renderer.prop("start_angle", -90)) * Math.PI / 180;
93
+ var direction = renderer.prop("clockwise", true) === false ? -1 : 1;
94
+ var pad = Math.max(0, Number(renderer.prop("pad_angle", 0))) * Math.PI / 180;
95
+ for (var index = 0; index < values.length; index++) {
96
+ var sweep = Math.max(0, values[index]) / total * Math.PI * 2 * direction;
97
+ var edge = pad * direction / 2;
98
+ var start = angle + edge;
99
+ var end = angle + sweep - edge;
100
+ ctx.beginPath();
101
+ ctx.moveTo(cx, cy);
102
+ ctx.arc(cx, cy, radius, start, end, direction < 0);
103
+ ctx.closePath();
104
+ ctx.fillStyle = palette[index % palette.length];
105
+ ctx.fill();
106
+ if (renderer.prop("show_labels", false) === true) {
107
+ var middle = angle + sweep / 2;
108
+ chartRoot.textStyle(ctx, renderer.prop("label_color", renderer.foreground));
109
+ ctx.fillText(labelAt(index, values[index]), cx + Math.cos(middle) * radius * 0.7, cy + Math.sin(middle) * radius * 0.7);
110
+ }
111
+ angle += sweep;
112
+ }
113
+ var innerRadius = Number(renderer.prop("inner_radius", donut ? 0.58 : 0));
114
+ if (innerRadius > 0) {
115
+ ctx.beginPath();
116
+ ctx.arc(cx, cy, radius * Math.max(0, Math.min(0.98, innerRadius)), 0, Math.PI * 2);
117
+ ctx.fillStyle = renderer.prop("background", "transparent");
118
+ ctx.globalCompositeOperation = "destination-out";
119
+ ctx.fill();
120
+ ctx.globalCompositeOperation = "source-over";
121
+ }
122
+ if (donut && String(renderer.prop("center_text", "")) !== "") {
123
+ chartRoot.textStyle(ctx, renderer.prop("label_color", renderer.foreground));
124
+ ctx.fillText(String(renderer.prop("center_text", "")), cx, cy);
125
+ }
126
+ }
127
+
128
+ function drawLine(ctx, compact) {
129
+ var values = numericValues();
130
+ if (!values.length)
131
+ return ;
132
+
133
+ var pad = compact ? 2 : 20;
134
+ var range = bounds(values, "minimum", "maximum");
135
+ if (!compact)
136
+ drawGrid(ctx, pad);
137
+
138
+ ctx.beginPath();
139
+ var points = [];
140
+ for (var index = 0; index < values.length; index++) {
141
+ var x = pad + (values.length === 1 ? (width - 2 * pad) / 2 : (width - 2 * pad) * index / (values.length - 1));
142
+ var y = pad + (height - 2 * pad) * (1 - (values[index] - range.low) / (range.high - range.low));
143
+ points.push({
144
+ "x": x,
145
+ "y": y
146
+ });
147
+ if (index === 0)
148
+ ctx.moveTo(x, y);
149
+ else
150
+ ctx.lineTo(x, y);
151
+ }
152
+ var fill = String(renderer.prop("fill_color", "transparent"));
153
+ if (fill !== "" && fill !== "transparent") {
154
+ ctx.lineTo(points[points.length - 1].x, height - pad);
155
+ ctx.lineTo(points[0].x, height - pad);
156
+ ctx.closePath();
157
+ ctx.fillStyle = fill;
158
+ ctx.fill();
159
+ ctx.beginPath();
160
+ for (var pointIndex = 0; pointIndex < points.length; pointIndex++) {
161
+ if (pointIndex === 0)
162
+ ctx.moveTo(points[pointIndex].x, points[pointIndex].y);
163
+ else
164
+ ctx.lineTo(points[pointIndex].x, points[pointIndex].y);
165
+ }
166
+ }
167
+ ctx.strokeStyle = renderer.prop("color", Color.accent);
168
+ ctx.lineWidth = Number(renderer.prop("line_width", 2));
169
+ ctx.stroke();
170
+ if (renderer.prop("show_points", false) === true) {
171
+ ctx.fillStyle = renderer.prop("color", Color.accent);
172
+ for (var point = 0; point < points.length; point++) {
173
+ ctx.beginPath();
174
+ ctx.arc(points[point].x, points[point].y, Number(renderer.prop("point_size", 4)), 0, Math.PI * 2);
175
+ ctx.fill();
176
+ }
177
+ }
178
+ }
179
+
180
+ function seriesValues() {
181
+ var source = renderer.prop("series", renderer.prop("values", []));
182
+ if (!Array.isArray(source))
183
+ return [];
184
+
185
+ if (source.length > 0 && !Array.isArray(source[0]) && !(source[0] && Array.isArray(source[0].values)))
186
+ return [source];
187
+
188
+ return source.map(function(series) {
189
+ return series && Array.isArray(series.values) ? series.values : series;
190
+ });
191
+ }
192
+
193
+ function drawStacked(ctx) {
194
+ var series = seriesValues();
195
+ if (!series.length)
196
+ return ;
197
+
198
+ var count = series.reduce(function(max, values) {
199
+ return Math.max(max, values.length);
200
+ }, 0);
201
+ var totals = [];
202
+ for (var i = 0; i < count; i++) {
203
+ totals[i] = 0;
204
+ for (var s = 0; s < series.length; s++) totals[i] += Math.max(0, Number(series[s][i] || 0))
205
+ }
206
+ var range = bounds(totals, "minimum", "maximum");
207
+ range.low = Math.min(0, range.low);
208
+ var pad = 20;
209
+ drawGrid(ctx, pad);
210
+ var palette = colors();
211
+ var horizontal = String(renderer.prop("orientation", "vertical")) === "horizontal";
212
+ var available = horizontal ? height - pad * 2 : width - pad * 2;
213
+ var slot = available / Math.max(1, count);
214
+ var gap = Math.max(0, Number(renderer.prop("bar_spacing", 4)));
215
+ var stackGap = Math.max(0, Number(renderer.prop("stack_spacing", 0)));
216
+ for (var column = 0; column < count; column++) {
217
+ var cursor = horizontal ? pad : height - pad;
218
+ for (var si = 0; si < series.length; si++) {
219
+ var value = Math.max(0, Number(series[si][column] || 0));
220
+ var amount = (horizontal ? width - pad * 2 : height - pad * 2) * value / Math.max(1e-09, range.high - range.low);
221
+ ctx.fillStyle = palette[si % palette.length];
222
+ if (horizontal) {
223
+ ctx.fillRect(cursor + stackGap / 2, pad + column * slot + gap / 2, Math.max(1, amount - stackGap), Math.max(1, slot - gap));
224
+ cursor += amount;
225
+ } else {
226
+ ctx.fillRect(pad + column * slot + gap / 2, cursor - amount + stackGap / 2, Math.max(1, slot - gap), Math.max(1, amount - stackGap));
227
+ cursor -= amount;
228
+ }
229
+ }
230
+ chartRoot.textStyle(ctx, renderer.foreground);
231
+ var label = labelAt(column, "");
232
+ if (label !== "")
233
+ ctx.fillText(label, horizontal ? 8 : pad + (column + 0.5) * slot, horizontal ? pad + (column + 0.5) * slot : height - 7);
234
+
235
+ }
236
+ if (renderer.prop("legend", false) === true) {
237
+ var definitions = renderer.prop("series", []);
238
+ chartRoot.textStyle(ctx, renderer.foreground);
239
+ ctx.textAlign = "left";
240
+ for (var legendIndex = 0; legendIndex < definitions.length; legendIndex++) {
241
+ var name = definitions[legendIndex] && definitions[legendIndex].name !== undefined ? definitions[legendIndex].name : "Series " + (legendIndex + 1);
242
+ ctx.fillStyle = palette[legendIndex % palette.length];
243
+ ctx.fillRect(pad + legendIndex * 90, 2, 8, 8);
244
+ ctx.fillStyle = renderer.foreground;
245
+ ctx.fillText(String(name), pad + 12 + legendIndex * 90, 6);
246
+ }
247
+ }
248
+ }
249
+
250
+ function pointSeries() {
251
+ var source = renderer.prop("series", null);
252
+ if (!Array.isArray(source) || source.length === 0)
253
+ return [renderer.prop("values", [])];
254
+
255
+ if (Array.isArray(source[0]))
256
+ return source;
257
+
258
+ if (source[0] && Array.isArray(source[0].values))
259
+ return source.map(function(definition) {
260
+ return definition.values;
261
+ });
262
+
263
+ return [source];
264
+ }
265
+
266
+ function drawPoints(ctx, bubbles) {
267
+ var series = pointSeries();
268
+ var points = [];
269
+ for (var seriesIndex = 0; seriesIndex < series.length; seriesIndex++) if (Array.isArray(series[seriesIndex])) {
270
+ points = points.concat(series[seriesIndex]);
271
+ }
272
+ if (!points.length)
273
+ return ;
274
+
275
+ var xs = points.map(function(p, i) {
276
+ return pointValue(p, "x", 0, i);
277
+ });
278
+ var ys = points.map(function(p) {
279
+ return pointValue(p, "y", 1, 0);
280
+ });
281
+ var xb = bounds(xs, "minimum_x", "maximum_x");
282
+ var yb = bounds(ys, "minimum_y", "maximum_y");
283
+ var pad = 20;
284
+ drawGrid(ctx, pad);
285
+ var palette = colors();
286
+ var rawSizes = points.map(function(point) {
287
+ return pointValue(point, "size", 2, 1);
288
+ });
289
+ var rawMax = Math.max.apply(Math, rawSizes.concat([1]));
290
+ var globalIndex = 0;
291
+ for (var seriesNumber = 0; seriesNumber < series.length; seriesNumber++) {
292
+ var currentSeries = Array.isArray(series[seriesNumber]) ? series[seriesNumber] : [];
293
+ var coordinates = [];
294
+ for (var index = 0; index < currentSeries.length; index++) {
295
+ var point = currentSeries[index];
296
+ var pointX = pointValue(point, "x", 0, globalIndex);
297
+ var pointY = pointValue(point, "y", 1, 0);
298
+ var x = pad + (width - pad * 2) * (pointX - xb.low) / (xb.high - xb.low);
299
+ var y = pad + (height - pad * 2) * (1 - (pointY - yb.low) / (yb.high - yb.low));
300
+ coordinates.push({
301
+ "x": x,
302
+ "y": y
303
+ });
304
+ var minimumSize = Number(renderer.prop("minimum_size", 5));
305
+ var maximumSize = Number(renderer.prop("maximum_size", 30));
306
+ var rawSize = pointValue(point, "size", 2, 1);
307
+ var size = bubbles ? minimumSize + (maximumSize - minimumSize) * rawSize / rawMax : Number(renderer.prop("point_size", 5));
308
+ ctx.beginPath();
309
+ ctx.arc(x, y, Math.max(1, size), 0, Math.PI * 2);
310
+ ctx.fillStyle = point && point.color !== undefined ? point.color : palette[seriesNumber % palette.length];
311
+ ctx.fill();
312
+ var label = point && point.label !== undefined ? String(point.label) : labelAt(globalIndex, "");
313
+ if (label !== "") {
314
+ chartRoot.textStyle(ctx, renderer.foreground);
315
+ ctx.fillText(label, x, y - size - 8);
316
+ }
317
+ globalIndex++;
318
+ }
319
+ if (!bubbles && renderer.prop("connect_lines", false) === true && coordinates.length > 1) {
320
+ ctx.beginPath();
321
+ for (var lineIndex = 0; lineIndex < coordinates.length; lineIndex++) {
322
+ if (lineIndex === 0)
323
+ ctx.moveTo(coordinates[lineIndex].x, coordinates[lineIndex].y);
324
+ else
325
+ ctx.lineTo(coordinates[lineIndex].x, coordinates[lineIndex].y);
326
+ }
327
+ ctx.strokeStyle = palette[seriesNumber % palette.length];
328
+ ctx.stroke();
329
+ }
330
+ }
331
+ }
332
+
333
+ function drawRadar(ctx) {
334
+ var series = seriesValues();
335
+ if (!series.length)
336
+ return ;
337
+
338
+ var count = series.reduce(function(current, values) {
339
+ return Math.max(current, Array.isArray(values) ? values.length : 0);
340
+ }, 0);
341
+ if (count < 3)
342
+ return ;
343
+
344
+ var flattened = [];
345
+ for (var seriesIndex = 0; seriesIndex < series.length; seriesIndex++) for (var valueIndex = 0; valueIndex < series[seriesIndex].length; valueIndex++) flattened.push(Number(series[seriesIndex][valueIndex] || 0))
346
+ var max = Math.max.apply(Math, flattened.concat([1]));
347
+ var levels = Number(renderer.prop("levels", 5));
348
+ var cx = width / 2;
349
+ var cy = height / 2;
350
+ var radius = Math.min(width, height) / 2 - 20;
351
+ ctx.strokeStyle = renderer.prop("grid_color", Qt.rgba(1, 1, 1, 0.2));
352
+ for (var level = 1; level <= levels; level++) {
353
+ ctx.beginPath();
354
+ for (var i = 0; i < count; i++) {
355
+ var a = -Math.PI / 2 + i * Math.PI * 2 / count;
356
+ var r = radius * level / levels;
357
+ if (i === 0)
358
+ ctx.moveTo(cx + Math.cos(a) * r, cy + Math.sin(a) * r);
359
+ else
360
+ ctx.lineTo(cx + Math.cos(a) * r, cy + Math.sin(a) * r);
361
+ }
362
+ ctx.closePath();
363
+ ctx.stroke();
364
+ }
365
+ for (var labelIndex = 0; labelIndex < count; labelIndex++) {
366
+ var labelAngle = -Math.PI / 2 + labelIndex * Math.PI * 2 / count;
367
+ var label = labelAt(labelIndex, "");
368
+ if (label !== "") {
369
+ chartRoot.textStyle(ctx, renderer.foreground);
370
+ ctx.fillText(label, cx + Math.cos(labelAngle) * (radius + 10), cy + Math.sin(labelAngle) * (radius + 10));
371
+ }
372
+ }
373
+ var palette = colors();
374
+ var pointSize = Math.max(0, Number(renderer.prop("point_size", 0)));
375
+ for (var radarIndex = 0; radarIndex < series.length; radarIndex++) {
376
+ var values = series[radarIndex];
377
+ ctx.beginPath();
378
+ var radarPoints = [];
379
+ for (var index = 0; index < count; index++) {
380
+ var angle = -Math.PI / 2 + index * Math.PI * 2 / count;
381
+ var valueRadius = radius * Number(values[index] || 0) / max;
382
+ var pointX = cx + Math.cos(angle) * valueRadius;
383
+ var pointY = cy + Math.sin(angle) * valueRadius;
384
+ radarPoints.push({
385
+ "x": pointX,
386
+ "y": pointY
387
+ });
388
+ if (index === 0)
389
+ ctx.moveTo(pointX, pointY);
390
+ else
391
+ ctx.lineTo(pointX, pointY);
392
+ }
393
+ ctx.closePath();
394
+ ctx.globalAlpha = Number(renderer.prop("fill_opacity", 0.25));
395
+ ctx.fillStyle = palette[radarIndex % palette.length];
396
+ ctx.fill();
397
+ ctx.globalAlpha = 1;
398
+ ctx.strokeStyle = palette[radarIndex % palette.length];
399
+ ctx.lineWidth = Number(renderer.prop("line_width", 2));
400
+ ctx.stroke();
401
+ if (pointSize > 0) {
402
+ ctx.fillStyle = palette[radarIndex % palette.length];
403
+ for (var radarPoint = 0; radarPoint < radarPoints.length; radarPoint++) {
404
+ ctx.beginPath();
405
+ ctx.arc(radarPoints[radarPoint].x, radarPoints[radarPoint].y, pointSize, 0, Math.PI * 2);
406
+ ctx.fill();
407
+ }
408
+ }
409
+ }
410
+ }
411
+
412
+ function drawHeatmap(ctx) {
413
+ var matrix = renderer.prop("values", []);
414
+ if (!Array.isArray(matrix) || !matrix.length)
415
+ return ;
416
+
417
+ var flat = [];
418
+ matrix.forEach(function(row) {
419
+ if (Array.isArray(row))
420
+ row.forEach(function(v) {
421
+ flat.push(Number(v));
422
+ });
423
+
424
+ });
425
+ var range = bounds(flat, "minimum", "maximum");
426
+ var rows = matrix.length;
427
+ var columns = matrix.reduce(function(max, row) {
428
+ return Math.max(max, Array.isArray(row) ? row.length : 0);
429
+ }, 0);
430
+ var palette = colors();
431
+ var gap = Number(renderer.prop("cell_spacing", 1));
432
+ var xLabels = renderer.prop("x_labels", []);
433
+ var yLabels = renderer.prop("y_labels", []);
434
+ var left = yLabels.length ? 42 : 0;
435
+ var bottom = xLabels.length ? 24 : 0;
436
+ var cellWidth = (width - left) / columns;
437
+ var cellHeight = (height - bottom) / rows;
438
+ for (var y = 0; y < rows; y++) for (var x = 0; x < matrix[y].length; x++) {
439
+ var t = (Number(matrix[y][x]) - range.low) / (range.high - range.low);
440
+ var index = Math.max(0, Math.min(palette.length - 1, Math.floor(t * palette.length)));
441
+ ctx.fillStyle = palette[index];
442
+ ctx.fillRect(left + x * cellWidth + gap / 2, y * cellHeight + gap / 2, cellWidth - gap, cellHeight - gap);
443
+ if (renderer.prop("show_values", false) === true) {
444
+ chartRoot.textStyle(ctx, renderer.prop("value_color", renderer.foreground));
445
+ ctx.fillText(String(matrix[y][x]), left + (x + 0.5) * cellWidth, (y + 0.5) * cellHeight);
446
+ }
447
+ }
448
+ chartRoot.textStyle(ctx, renderer.foreground);
449
+ for (var xi = 0; xi < xLabels.length; xi++) ctx.fillText(String(xLabels[xi]), left + (xi + 0.5) * cellWidth, height - bottom / 2)
450
+ for (var yi = 0; yi < yLabels.length; yi++) ctx.fillText(String(yLabels[yi]), left / 2, (yi + 0.5) * cellHeight)
451
+ }
452
+
453
+ function drawGauge(ctx, radial) {
454
+ var values = numericValues();
455
+ var value = values.length ? values[0] : Number(renderer.prop("value", 0));
456
+ var min = Number(renderer.prop("minimum", 0));
457
+ var max = Number(renderer.prop("maximum", 1));
458
+ var t = Math.max(0, Math.min(1, (value - min) / Math.max(1e-09, max - min)));
459
+ var cx = width / 2;
460
+ var cy = height / 2;
461
+ var radius = Math.min(width, height) / 2 - 12;
462
+ var start = Number(renderer.prop("start_angle", radial ? 135 : 180)) * Math.PI / 180;
463
+ var end = Number(renderer.prop("end_angle", radial ? 405 : 360)) * Math.PI / 180;
464
+ var thickness = Number(renderer.prop("thickness", 12));
465
+ ctx.lineWidth = thickness;
466
+ ctx.lineCap = "round";
467
+ ctx.beginPath();
468
+ ctx.arc(cx, cy, radius, start, end);
469
+ ctx.strokeStyle = renderer.prop("track_color", Qt.rgba(1, 1, 1, 0.15));
470
+ ctx.stroke();
471
+ ctx.beginPath();
472
+ ctx.arc(cx, cy, radius, start, start + (end - start) * t);
473
+ ctx.strokeStyle = renderer.prop("color", Color.accent);
474
+ ctx.stroke();
475
+ if (renderer.prop("show_label", true) !== false) {
476
+ var format = String(renderer.prop("label_format", "%{value}"));
477
+ var text = format.replace("%{value}", String(value)).replace("%{label}", String(renderer.prop("label", "")));
478
+ chartRoot.textStyle(ctx, renderer.foreground);
479
+ ctx.fillText(text, cx, cy);
480
+ }
481
+ }
482
+
483
+ function drawHistogram(ctx) {
484
+ var values = numericValues();
485
+ if (!values.length)
486
+ return ;
487
+
488
+ var bins = Math.max(1, Number(renderer.prop("bins", Math.ceil(Math.sqrt(values.length)))));
489
+ var range = bounds(values, "minimum", "maximum");
490
+ var counts = new Array(bins).fill(0);
491
+ values.forEach(function(v) {
492
+ var i = Math.min(bins - 1, Math.floor((v - range.low) / (range.high - range.low) * bins));
493
+ counts[Math.max(0, i)]++;
494
+ });
495
+ if (renderer.prop("cumulative", false) === true)
496
+ for (var cumulativeIndex = 1; cumulativeIndex < counts.length; cumulativeIndex++) counts[cumulativeIndex] += counts[cumulativeIndex - 1];
497
+
498
+ if (renderer.prop("normalize", false) === true)
499
+ for (var normalizedIndex = 0; normalizedIndex < counts.length; normalizedIndex++) counts[normalizedIndex] /= values.length;
500
+
501
+ var max = Math.max.apply(Math, counts);
502
+ var pad = 20;
503
+ drawGrid(ctx, pad);
504
+ var slot = (width - pad * 2) / bins;
505
+ var gap = Math.max(0, Number(renderer.prop("bar_spacing", 2)));
506
+ ctx.fillStyle = colors()[0];
507
+ for (var i = 0; i < bins; i++) {
508
+ var h = (height - pad * 2) * counts[i] / Math.max(1e-09, max);
509
+ ctx.fillRect(pad + i * slot + gap / 2, height - pad - h, Math.max(1, slot - gap), h);
510
+ var label = labelAt(i, "");
511
+ if (label !== "") {
512
+ chartRoot.textStyle(ctx, renderer.foreground);
513
+ ctx.fillText(label, pad + (i + 0.5) * slot, height - 7);
514
+ }
515
+ }
516
+ }
517
+
518
+ function drawCandles(ctx) {
519
+ var candles = renderer.prop("values", []);
520
+ if (!Array.isArray(candles) || !candles.length)
521
+ return ;
522
+
523
+ var lows = candles.map(function(c) {
524
+ return pointValue(c, "low", 2, 0);
525
+ });
526
+ var highs = candles.map(function(c) {
527
+ return pointValue(c, "high", 1, 1);
528
+ });
529
+ var range = bounds(lows.concat(highs), "minimum", "maximum");
530
+ var pad = 20;
531
+ var py = function py(v) {
532
+ return pad + (height - pad * 2) * (1 - (v - range.low) / (range.high - range.low));
533
+ };
534
+ drawGrid(ctx, pad);
535
+ var slot = (width - pad * 2) / candles.length;
536
+ var spacing = Math.max(0, Number(renderer.prop("candle_spacing", 4)));
537
+ for (var i = 0; i < candles.length; i++) {
538
+ var c = candles[i];
539
+ var open = pointValue(c, "open", 0, 0);
540
+ var high = pointValue(c, "high", 1, open);
541
+ var low = pointValue(c, "low", 2, open);
542
+ var close = pointValue(c, "close", 3, open);
543
+ var x = pad + (i + 0.5) * slot;
544
+ ctx.strokeStyle = renderer.prop("wick_color", renderer.foreground);
545
+ ctx.beginPath();
546
+ ctx.moveTo(x, py(high));
547
+ ctx.lineTo(x, py(low));
548
+ ctx.stroke();
549
+ ctx.fillStyle = close >= open ? renderer.prop("up_color", "#9ece6a") : renderer.prop("down_color", "#f7768e");
550
+ var candleWidth = Math.max(1, slot - spacing);
551
+ ctx.fillRect(x - candleWidth / 2, Math.min(py(open), py(close)), candleWidth, Math.max(1, Math.abs(py(open) - py(close))));
552
+ var label = labelAt(i, "");
553
+ if (label !== "") {
554
+ chartRoot.textStyle(ctx, renderer.foreground);
555
+ ctx.fillText(label, x, height - 7);
556
+ }
557
+ }
558
+ }
559
+
560
+ implicitWidth: Number(renderer.prop("width", chartType === "sparkline" ? 160 : 420))
561
+ implicitHeight: Number(renderer.prop("height", chartType === "sparkline" ? 48 : 260))
562
+
563
+ Canvas {
564
+ id: canvas
565
+
566
+ anchors.fill: parent
567
+ antialiasing: true
568
+ onPaint: {
569
+ var ctx = getContext("2d");
570
+ ctx.reset();
571
+ ctx.clearRect(0, 0, width, height);
572
+ if (chartType === "pie")
573
+ chartRoot.drawPie(ctx, false);
574
+ else if (chartType === "donut")
575
+ chartRoot.drawPie(ctx, true);
576
+ else if (chartType === "stacked_bar")
577
+ chartRoot.drawStacked(ctx);
578
+ else if (chartType === "scatter")
579
+ chartRoot.drawPoints(ctx, false);
580
+ else if (chartType === "bubble")
581
+ chartRoot.drawPoints(ctx, true);
582
+ else if (chartType === "radar")
583
+ chartRoot.drawRadar(ctx);
584
+ else if (chartType === "heatmap")
585
+ chartRoot.drawHeatmap(ctx);
586
+ else if (chartType === "gauge")
587
+ chartRoot.drawGauge(ctx, false);
588
+ else if (chartType === "radial_gauge")
589
+ chartRoot.drawGauge(ctx, true);
590
+ else if (chartType === "histogram")
591
+ chartRoot.drawHistogram(ctx);
592
+ else if (chartType === "candlestick")
593
+ chartRoot.drawCandles(ctx);
594
+ else
595
+ chartRoot.drawLine(ctx, chartType === "sparkline");
596
+ }
597
+ }
598
+
599
+ Connections {
600
+ function onNodeChanged() {
601
+ canvas.requestPaint();
602
+ }
603
+
604
+ target: renderer
605
+ }
606
+
607
+ MouseArea {
608
+ function payload(mouse) {
609
+ var values = renderer.prop("values", []);
610
+ var index = Math.max(0, Math.min(values.length - 1, Math.floor(mouse.x / Math.max(1, width) * values.length)));
611
+ return {
612
+ "x": mouse.x,
613
+ "y": mouse.y,
614
+ "index": index,
615
+ "value": values[index]
616
+ };
617
+ }
618
+
619
+ anchors.fill: parent
620
+ hoverEnabled: renderer.subscribed("hover")
621
+ onClicked: function(mouse) {
622
+ renderer.bridge.sendEvent(renderer.surfaceName, renderer.controlId, "select", payload(mouse));
623
+ }
624
+ onPositionChanged: function(mouse) {
625
+ renderer.bridge.sendEvent(renderer.surfaceName, renderer.controlId, "hover", payload(mouse));
626
+ }
627
+ }
628
+
629
+ }