1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 try:
16 from collections import OrderedDict
17 except ImportError:
18 from ordereddict import OrderedDict
19
20 from muntjac.util \
21 import OrderedSet
22
23 from datetime \
24 import datetime
25
26 from muntjac.ui.abstract_component \
27 import AbstractComponent
28
29 from muntjac.ui.component \
30 import Event as ComponentEvent
31
32 from muntjac.addon.invient.invient_charts_config \
33 import BaseLineConfig, PointConfig, SeriesConfig
34
35 from muntjac.addon.invient.invient_charts_util \
36 import writeTitleConfig, writeSubtitleConfig, writeCreditConfig, \
37 writeLegendConfig, writeTooltipConfig, writeGeneralChartConfig, \
38 writeSeriesConfigPerSeriesType, writeXAxes, writeYAxes, \
39 writeChartLabelConfig, writeSeries, writeChartDataUpdates, getDate
43 """A Muntjac component representing charts. It is a the main class of
44 InvientCharts library.
45
46 A chart typically contains one or more series of same or different types.
47 This class allows us to specify series of different types say line and pie
48 and hence it makes it easy to build a combination chart.
49
50 After a chart L{InvientCharts} is created, the following changes to the
51 chart will be reflected rendered on the webkit.
52
53 * Set or update chart L{Title} and/or L{SubTitle}
54 * Modify chart size
55 * Add, update and remove one or more instances of L{PlotBand} and
56 L{PlotLine}
57 * Set or update axis categories
58 * Set or update axis min and max values
59 * Add, update and remove one or more instances of L{Series}
60 * Show or hide one or more instances of L{Series}
61 * Add and remove one or more instances of L{Point}
62 * Register and unregister event listeners
63
64 @author: Invient
65 @author: Richard Lincoln
66 """
67
68 CLIENT_WIDGET = None
69
70 TYPE_MAPPING = 'com.invient.vaadin.charts.InvientCharts'
71
73 """Creates this chart object with given chart configuration
74
75 @param chartConfig
76 """
77 if chartConfig is None:
78 raise ValueError('The chart cannot be created without '
79 'chartConfig argument.')
80
81 super(InvientCharts, self).__init__()
82
83 self._chartConfig = chartConfig
84 self._chartConfig.setInvientCharts(self)
85
86 self._isRetrieveSVG = False
87 self._isPrint = False
88
89 self._pointClickListeners = dict()
90 self._pointRemoveListeners = dict()
91 self._pointUnselectListeners = dict()
92 self._pointSelectListeners = dict()
93 self._seriesClickListeners = dict()
94 self._seriesHideListeners = dict()
95 self._seriesShowListeners = dict()
96 self._seriesLegendItemClickListeners = dict()
97 self._pieChartLegendItemClickListener = set()
98 self._chartClickListener = set()
99 self._chartAddSeriesListener = set()
100 self._chartZoomListener = set()
101 self._chartResetZoomListener = set()
102 self._svgAvailableListener = None
103 self._chartSeries = OrderedSet()
104 self._reloadChartSeries = False
105 self._seriesCURMap = OrderedDict()
106
107
109 """Returns chart configuration object
110
111 @return: Returns chart configuration object
112 """
113 return self._chartConfig
114
115
116 - def paintContent(self, target):
117 super(InvientCharts, self).paintContent(target)
118
119
120 self.setAxisInAllSeriesIfNotSetAlready()
121
122
123 target.startTag('options')
124 if self._chartConfig is not None:
125 writeTitleConfig(target, self._chartConfig.getTitle())
126 writeSubtitleConfig(target, self._chartConfig.getSubtitle())
127 writeCreditConfig(target, self._chartConfig.getCredit())
128 writeLegendConfig(target, self._chartConfig.getLegend())
129 writeTooltipConfig(target, self._chartConfig.getTooltip())
130 writeGeneralChartConfig(target,
131 self._chartConfig.getGeneralChartConfig())
132 writeSeriesConfigPerSeriesType(target,
133 self._chartConfig.getSeriesConfig())
134 writeXAxes(target, self._chartConfig.getXAxes(), self._chartConfig)
135 writeYAxes(target, self._chartConfig.getYAxes(), self._chartConfig)
136 writeChartLabelConfig(target, self._chartConfig.getChartLabel())
137 target.endTag('options')
138 target.startTag('chartData')
139
140 writeSeries(target,
141 self._chartConfig.getGeneralChartConfig().getType(),
142 self._chartSeries,
143 self._chartConfig.getXAxes(),
144 self._chartConfig.getYAxes())
145 target.endTag('chartData')
146
147
148 target.addAttribute('isRetrieveSVG', self._isRetrieveSVG)
149
150
151 target.addAttribute('isPrint', self._isPrint)
152
153
154 target.startTag('events')
155
156
157 self.paintChartEvents(target)
158
159
160 self.paintSeriesAndPointEvents(target)
161 target.endTag('events')
162
163
164
165
166
167 target.addAttribute('reloadChartSeries', self._reloadChartSeries)
168 target.startTag('chartDataUpdates')
169 if not self._reloadChartSeries:
170 writeChartDataUpdates(target, self._seriesCURMap)
171 target.endTag('chartDataUpdates')
172
173
174 self._reloadChartSeries = False
175
176
177 self._seriesCURMap.clear()
178
179
180
181
182 self._isRetrieveSVG = False
183 self._isPrint = False
184
185
187 target.startTag('chartEvents')
188
189 if (self._chartAddSeriesListener is not None
190 and len(self._chartAddSeriesListener) > 0):
191 target.addAttribute('addSeries', True)
192
193 if (self._chartClickListener is not None
194 and len(self._chartClickListener) > 0):
195 target.addAttribute('click', True)
196
197 if (self._chartZoomListener is not None
198 and len(self._chartZoomListener) > 0):
199 target.addAttribute('selection', True)
200
201 target.endTag('chartEvents')
202
203
210
211
213 tagName = seriesType.getName()
214 target.startTag(tagName)
215
216 if (seriesType in self._seriesClickListeners
217 and len(self._seriesClickListeners[seriesType]) > 0):
218 target.addAttribute('click', True)
219
220 if (seriesType in self._seriesHideListeners
221 and len(self._seriesHideListeners[seriesType]) > 0):
222 target.addAttribute('hide', True)
223
224 if (seriesType in self._seriesShowListeners
225 and len(self._seriesShowListeners[seriesType]) > 0):
226 target.addAttribute('show', True)
227
228 if (seriesType in self._seriesLegendItemClickListeners
229 and len(self._seriesLegendItemClickListeners[seriesType]) > 0):
230 target.addAttribute('legendItemClick', True)
231
232
233 self.paintPointEvents(target, seriesType)
234 target.endTag(tagName)
235
236
238 target.startTag('pointEvents')
239
240 if (seriesType in self._pointClickListeners
241 and len(self._pointClickListeners[seriesType]) > 0):
242 target.addAttribute('click', True)
243
244 if (seriesType in self._pointRemoveListeners
245 and len(self._pointRemoveListeners[seriesType]) > 0):
246 target.addAttribute('remove', True)
247
248 if (seriesType in self._pointSelectListeners
249 and len(self._pointSelectListeners[seriesType]) > 0):
250 target.addAttribute('select', True)
251
252 if (seriesType in self._pointUnselectListeners
253 and len(self._pointUnselectListeners[seriesType]) > 0):
254 target.addAttribute('unselect', True)
255
256
257 if (SeriesType.PIE == seriesType
258 and len(self._pieChartLegendItemClickListener) > 0):
259 target.addAttribute('legendItemClick', True)
260
261 target.endTag('pointEvents')
262
263
265 if 'event' in variables:
266 eventData = variables.get('eventData')
267 eventName = variables.get('event')
268 if eventName.lower() == "addSeries".lower():
269 self.fireAddSeries()
270 elif eventName.lower() == "chartClick".lower():
271 xAxisPos = float(eventData.get("xAxisPos"))
272 yAxisPos = float(eventData.get("yAxisPos"))
273
274 mousePosition = self.getClickPosition(eventData)
275 self.fireChartClick(DecimalPoint(self, xAxisPos, yAxisPos),
276 mousePosition)
277 elif eventName.lower() == "chartZoom".lower():
278 xAxisMin = float(eventData.get("xAxisMin"))
279 xAxisMax = float(eventData.get("xAxisMax"))
280 yAxisMin = float(eventData.get("yAxisMin"))
281 yAxisMax = float(eventData.get("yAxisMax"))
282 self.fireChartZoom(ChartArea(xAxisMin, xAxisMax, yAxisMin,
283 yAxisMax))
284 elif eventName.lower() == "chartResetZoom".lower():
285 self.fireChartResetZoom()
286 elif eventName.lower() == "chartSVGAvailable".lower():
287 self.fireChartSVGAvailable(eventData.get("svg"))
288 elif eventName.lower() == "seriesClick".lower():
289 pointEventData = self.getPointEventData(eventData)
290
291 mousePosition = self.getClickPosition(eventData)
292 self.fireSeriesClick(
293 self.getSeriesFromEventData(
294 pointEventData.getSeriesName()),
295 self.getPointFromEventData(pointEventData),
296 mousePosition)
297 elif eventName.lower() == "seriesHide".lower():
298 seriesName = eventData.get("seriesName")
299 self.fireSeriesHide(self.getSeriesFromEventData(seriesName))
300 elif eventName.lower() == "seriesShow".lower():
301 seriesName = eventData.get("seriesName")
302 self.fireSeriesShow(self.getSeriesFromEventData(seriesName))
303 elif eventName.lower() == "seriesLegendItemClick".lower():
304 seriesName = eventData.get("seriesName")
305 self.fireSeriesLegendItemClick(
306 self.getSeriesFromEventData(seriesName))
307 elif eventName.lower() == "pieLegendItemClick".lower():
308 pointEventData = self.getPointEventData(eventData)
309 self.fireLegendItemClick(
310 self.getPointFromEventData(pointEventData))
311 elif eventName.lower() == "pointClick".lower():
312 mousePosition = self.getClickPosition(eventData)
313
314 pointEventData = self.getPointEventData(eventData)
315 self.firePointClick(pointEventData.getCategory(),
316 self.getPointFromEventData(pointEventData),
317 mousePosition)
318 elif eventName.lower() == "pointSelect".lower():
319 pointEventData = self.getPointEventData(eventData)
320 self.firePointSelect(pointEventData.getCategory(),
321 self.getPointFromEventData(pointEventData))
322 elif eventName.lower() == "pointUnselect".lower():
323 pointEventData = self.getPointEventData(eventData)
324 self.firePointUnselect(pointEventData.getCategory(),
325 self.getPointFromEventData(pointEventData))
326 elif eventName.lower() == "pointRemove".lower():
327 pointEventData = self.getPointEventData(eventData)
328 self.firePointRemove(pointEventData.getCategory(),
329 self.getPointFromEventData(pointEventData))
330
331
352
353
355 for series in self._chartSeries:
356 if series.getName() == seriesName:
357 return series
358
359 return None
360
361
364
365
368
369
372
373
376
377
380
381
385
386
389
390
393
394
397
398
402
403
406
407
410
411
414
415
418
419
421 seriesName = eventData['seriesName']
422 category = eventData['category']
423 pointX = float(eventData['pointX'])
424 pointY = float(eventData['pointY'])
425 return PointEventData(seriesName, category, pointX, pointY)
426
427
429 mouseX = None
430 if isinstance(eventData['mouseX'], int):
431 mouseX = eventData['mouseX']
432 mouseY = None
433 if isinstance(eventData['mouseY'], int):
434 mouseY = eventData['mouseY']
435 if mouseX is not None and mouseY is not None:
436 return MousePosition(mouseX, mouseY)
437 return None
438
439
441 """Adds the listener. If the argument seriesTypes is not specified
442 then the listener will be added for all series type otherwise it will
443 be added for a specific series type
444
445 @param listener:
446 the L{IListener} to be added.
447 """
448 if seriesTypes is None:
449 if isinstance(listener, ChartAddSeriesListener):
450 self._chartAddSeriesListener.add(listener)
451 self.registerListener(ChartAddSeriesEvent, listener,
452 _CHART_ADD_SERIES_METHOD)
453 elif isinstance(listener, ChartClickListener):
454 self._chartClickListener.add(listener)
455 self.registerListener(ChartClickEvent, listener,
456 _CHART_CLICK_METHOD)
457 elif isinstance(listener, ChartResetZoomListener):
458 self._chartResetZoomListener.add(listener)
459 self.registerListener(ChartResetZoomEvent, listener,
460 _CHART_RESET_ZOOM_METHOD)
461 elif isinstance(listener, ChartSVGAvailableListener):
462 if (self._svgAvailableListener is not None
463 and self._svgAvailableListener != listener):
464
465 self.removeListener(self._svgAvailableListener)
466 self._svgAvailableListener = listener
467 self.registerListener(ChartSVGAvailableEvent,
468 self._svgAvailableListener,
469 _CHART_SVG_AVAILABLE_METHOD)
470 self._isRetrieveSVG = True
471 self.requestRepaint()
472 elif isinstance(listener, ChartZoomListener):
473 self._chartZoomListener.add(listener)
474 self.registerListener(ChartZoomEvent, listener,
475 _CHART_ZOOM_METHOD)
476 elif isinstance(listener, PieChartLegendItemClickListener):
477 self._pieChartLegendItemClickListener.add(listener)
478 self.registerListener(PieChartLegendItemClickEvent, listener,
479 _LEGENDITEM_CLICK_METHOD)
480 else:
481 super(InvientCharts, self).addListener(listener, seriesTypes)
482 else:
483 if isinstance(listener, PointClickListener):
484 if len(seriesTypes) == 0:
485 seriesTypes = [SeriesType.COMMONSERIES]
486 for seriesType in seriesTypes:
487 if seriesType in self._pointClickListeners:
488 self._pointClickListeners[seriesType].add(listener)
489 else:
490 listeners = set()
491 listeners.add(listener)
492 self._pointClickListeners[seriesType] = listeners
493 self.registerListener(PointClickEvent, listener,
494 _POINT_CLICK_METHOD)
495 elif isinstance(listener, PointRemoveListener):
496 if len(seriesTypes) == 0:
497 seriesTypes = [SeriesType.COMMONSERIES]
498 for seriesType in seriesTypes:
499 if seriesType in self._pointRemoveListeners:
500 self._pointRemoveListeners[seriesType].add(listener)
501 else:
502 listeners = set()
503 listeners.add(listener)
504 self._pointRemoveListeners[seriesType] = listeners
505 self.registerListener(PointRemoveEvent, listener,
506 _POINT_REMOVE_METHOD)
507 elif isinstance(listener, PointSelectListener):
508 if len(seriesTypes) == 0:
509 seriesTypes = [SeriesType.COMMONSERIES]
510 for seriesType in seriesTypes:
511 if seriesType in self._pointSelectListeners:
512 self._pointSelectListeners[seriesType].add(listener)
513 else:
514 listeners = set()
515 listeners.add(listener)
516 self._pointSelectListeners[seriesType] = listeners
517 self.registerListener(PointSelectEvent, listener,
518 _POINT_SELECT_METHOD)
519 elif isinstance(listener, PointUnselectListener):
520 if len(seriesTypes) == 0:
521 seriesTypes = [SeriesType.COMMONSERIES]
522 for seriesType in seriesTypes:
523 if seriesType in self._pointUnselectListeners:
524 self._pointUnselectListeners[seriesType].add(listener)
525 else:
526 listeners = set()
527 listeners.add(listener)
528 self._pointUnselectListeners[seriesType] = listeners
529 self.registerListener(PointUnselectEvent, listener,
530 _POINT_UNSELECT_METHOD)
531 elif isinstance(listener, SeriesClickListerner):
532 if len(seriesTypes) == 0:
533 seriesTypes = [SeriesType.COMMONSERIES]
534 for seriesType in seriesTypes:
535 if seriesType in self._seriesClickListeners:
536 self._seriesClickListeners[seriesType].add(listener)
537 else:
538 listeners = set()
539 listeners.add(listener)
540 self._seriesClickListeners[seriesType] = listeners
541 self.registerListener(SeriesClickEvent, listener,
542 _SERIES_CLICK_METHOD)
543 elif isinstance(listener, SeriesHideListerner):
544 if len(seriesTypes) == 0:
545 seriesTypes = [SeriesType.COMMONSERIES]
546 for seriesType in seriesTypes:
547 if seriesType in self._seriesHideListeners:
548 self._seriesHideListeners[seriesType].add(listener)
549 else:
550 listeners = set()
551 listeners.add(listener)
552 self._seriesHideListeners[seriesType] = listeners
553 self.registerListener(SeriesHideEvent, listener,
554 _SERIES_HIDE_METHOD)
555 elif isinstance(listener, SeriesLegendItemClickListerner):
556 if len(seriesTypes) == 0:
557 seriesTypes = [SeriesType.COMMONSERIES]
558 for seriesType in seriesTypes:
559 if seriesType in self._seriesLegendItemClickListeners:
560 self._seriesLegendItemClickListeners[seriesType].add(
561 listener)
562 else:
563 listeners = set()
564 listeners.add(listener)
565 self._seriesLegendItemClickListeners[seriesType] = \
566 listeners
567 self.registerListener(SeriesLegendItemClickEvent, listener,
568 _SERIES_LEGENDITEM_CLICK_METHOD)
569 elif isinstance(listener, SeriesShowListerner):
570 if len(seriesTypes) == 0:
571 seriesTypes = [SeriesType.COMMONSERIES]
572 for seriesType in seriesTypes:
573 if seriesType in self._seriesShowListeners:
574 self._seriesShowListeners[seriesType].add(listener)
575 else:
576 listeners = set()
577 listeners.add(listener)
578 self._seriesShowListeners[seriesType] = listeners
579 self.registerListener(SeriesShowEvent, listener,
580 _SERIES_SHOW_METHOD)
581 else:
582 iface = seriesTypes
583 super(InvientCharts, self).addListener(listener, iface)
584
585
587 """Removes the listener. If the argument seriesTypes is not specified
588 then the listener will be removed only for a series type
589 SeriesType.COMMONSERIES otherwise the listener will be removed for all
590 specified series types.
591
592 @param listener:
593 the listener to be removed
594 @param seriesTypes:
595 one or more series types as defined by L{SeriesType}
596 """
597 if seriesTypes is None:
598 if isinstance(listener, ChartAddSeriesListener):
599 self._chartAddSeriesListener.remove(listener)
600 self.withdrawListener(ChartAddSeriesEvent, listener,
601 _CHART_ADD_SERIES_METHOD)
602 elif isinstance(listener, ChartClickListener):
603 self._chartClickListener.remove(listener)
604 self.withdrawListener(ChartClickEvent, listener,
605 _CHART_CLICK_METHOD)
606 elif isinstance(listener, ChartResetZoomListener):
607 self._chartResetZoomListener.remove(listener)
608 self.withdrawListener(ChartResetZoomEvent, listener,
609 _CHART_RESET_ZOOM_METHOD)
610 elif isinstance(listener, ChartSVGAvailableListener):
611 if self._svgAvailableListener == listener:
612 self.withdrawListener(ChartSVGAvailableEvent, listener,
613 _CHART_SVG_AVAILABLE_METHOD)
614 self._isRetrieveSVG = False
615 self._svgAvailableListener = None
616 elif isinstance(listener, ChartZoomListener):
617 self._chartZoomListener.remove(listener)
618 self.withdrawListener(ChartZoomEvent, listener,
619 _CHART_ZOOM_METHOD)
620 elif isinstance(listener, PieChartLegendItemClickListener):
621 self._pieChartLegendItemClickListener.remove(listener)
622 self.withdrawListener(PieChartLegendItemClickEvent, listener,
623 _LEGENDITEM_CLICK_METHOD)
624 else:
625 super(InvientCharts, self).removeListener(listener, seriesTypes)
626 else:
627 if isinstance(listener, PointClickListener):
628 if len(seriesTypes) == 0:
629 seriesTypes = [SeriesType.COMMONSERIES]
630 for seriesType in seriesTypes:
631 if seriesType in self._pointClickListeners:
632 self._pointClickListeners[seriesType].remove(listener)
633 self.withdrawListener(PointClickEvent, listener,
634 _POINT_CLICK_METHOD)
635 elif isinstance(listener, PointRemoveListener):
636 if len(seriesTypes) == 0:
637 seriesTypes = [SeriesType.COMMONSERIES]
638 for seriesType in seriesTypes:
639 if seriesType in self._pointRemoveListeners:
640 self._pointRemoveListeners[seriesType].remove(listener)
641 self._pointRemoveListeners.remove(listener)
642 self.withdrawListener(PointRemoveEvent, listener,
643 _POINT_REMOVE_METHOD)
644 elif isinstance(listener, PointSelectListener):
645 if len(seriesTypes) == 0:
646 seriesTypes = [SeriesType.COMMONSERIES]
647 for seriesType in seriesTypes:
648 if seriesType in self._pointSelectListeners:
649 self._pointSelectListeners[seriesType].remove(listener)
650 self.withdrawListener(PointSelectEvent, listener,
651 _POINT_SELECT_METHOD)
652 elif isinstance(listener, PointUnselectListener):
653 if len(seriesTypes) == 0:
654 seriesTypes = [SeriesType.COMMONSERIES]
655 for seriesType in seriesTypes:
656 if seriesType in self._pointUnselectListeners:
657 self._pointUnselectListeners[seriesType].remove(
658 listener)
659 self.withdrawListener(PointUnselectEvent, listener,
660 _POINT_UNSELECT_METHOD)
661 elif isinstance(listener, SeriesClickListerner):
662 if len(seriesTypes) == 0:
663 seriesTypes = [SeriesType.COMMONSERIES]
664 for seriesType in seriesTypes:
665 if seriesType in self._seriesClickListeners:
666 self._seriesClickListeners[seriesType].remove(listener)
667 self.withdrawListener(SeriesClickEvent, listener,
668 _SERIES_CLICK_METHOD)
669 elif isinstance(listener, SeriesHideListerner):
670 if len(seriesTypes) == 0:
671 seriesTypes = [SeriesType.COMMONSERIES]
672 for seriesType in seriesTypes:
673 if seriesType in self._seriesHideListeners:
674 self._seriesHideListeners[seriesType].remove(listener)
675 self.withdrawListener(SeriesHideEvent, listener,
676 _SERIES_HIDE_METHOD)
677 elif isinstance(listener, SeriesLegendItemClickListerner):
678 if len(seriesTypes) == 0:
679 seriesTypes = [SeriesType.COMMONSERIES]
680 for seriesType in seriesTypes:
681 if seriesType in self._seriesLegendItemClickListeners:
682 self._seriesLegendItemClickListeners[
683 seriesType].remove(listener)
684 self.withdrawListener(SeriesLegendItemClickEvent, listener,
685 _SERIES_LEGENDITEM_CLICK_METHOD)
686 elif isinstance(listener, SeriesShowListerner):
687 if len(seriesTypes) == 0:
688 seriesTypes = [SeriesType.COMMONSERIES]
689 for seriesType in seriesTypes:
690 if seriesType in self._seriesShowListeners:
691 self._seriesShowListeners[seriesType].remove(listener)
692 self.withdrawListener(SeriesShowEvent, listener,
693 _SERIES_SHOW_METHOD)
694 else:
695 iface = seriesTypes
696 super(InvientCharts, self).removeListener(listener, iface)
697
698
700 """The data of a chart is defined in terms of L{Series}. This method
701 removes all previously set series of this chart and adds the argument
702 series. If the argument series is null then no actions are taken.
703
704 @param series:
705 A collection of series to set as chart's data
706 """
707 if series is not None:
708 self._reloadChartSeries = True
709 self._chartSeries.clear()
710 self._seriesCURMap.clear()
711 for seriesData in series:
712 self.addSeries(seriesData)
713
714
716 """Returns a series whose name matches the argument name.
717
718 @param name:
719 the name of the series
720 @return: Returns a series with the given name
721 """
722 for series in self._chartSeries:
723 if series.getName() == name:
724 return series
725 return None
726
727
729 """Returns all series associated with this chart.
730 @return: returns all series associated with this chart.
731 """
732 return self._chartSeries
733
734
749
750
754
755
766
767
793
794
855
856
877
878
880 if (seriesCURSet is None) or (len(seriesCURSet) == 0):
881 return None
882 lastSeriesCur = None
883 for seriesCur in seriesCURSet:
884 lastSeriesCur = seriesCur
885 return lastSeriesCur
886
887
889 for seriesCur in seriesCURSet:
890 if matchAgainstSeriesCUR == seriesCur:
891 return seriesCur
892 return None
893
894
915
916
918 """After a series is added or removed, there is no need to call this
919 method as it is handled implicitly. This method will send updates to
920 the client. This method should be called after adding/removing
921 plotbands and plotlines. This inconsistency will be fixed in next
922 revision.
923 """
924 super(InvientCharts, self).requestRepaint()
925
926
928 """Displays a Print dialog of the Webkit to print this chart. Invoking
929 this method causes the Webkit to hide other widgets on the screen and
930 only this chart widget will be visible. Also it prints this chart
931 widget as it is displayed.
932 """
933 self._isPrint = True
934 self.requestRepaint()
935
938 """This class contain mouse coordinates when a click event occurs
939 on a chart, a series or a point.
940
941 The mouse coordinates are in pixels.
942
943 @author: Invient
944 @author: Richard Lincoln
945 """
946
948 """Creates this object with given arguments.
949
950 @param mouseX:
951 x position of mouse when a click event occurred, in pixel
952 @param mouseY:
953 y position of mouse when a click event occurred, in pixel
954 """
955 self._mouseX = mouseX
956 self._mouseY = mouseY
957
958
960 """@return: Returns x position of mouse when a click event occurred,
961 in pixel
962 """
963 return self._mouseX
964
965
967 """@return: Returns y position of mouse when a click event occurred,
968 in pixel
969 """
970 return self._mouseY
971
972
974 return ('MousePosition [mouseX=' + str(self._mouseX)
975 + ', mouseY=' + str(self._mouseY) + ']')
976
979
980 - def __init__(self, seriesName, category, pointX, pointY):
981 self._seriesName = seriesName
982 self._category = category
983 self._pointX = pointX
984 self._pointY = pointY
985
987 return self._seriesName
988
990 return self._category
991
994
997
999 return ('PointEventData [seriesName=' + self._seriesName
1000 + ', category=' + self._category
1001 + ', pointX=' + str(self._pointX)
1002 + ', pointY=' + str(self._pointY) + ']')
1003
1006 """Click event. This event is thrown, when any point of this chart is
1007 clicked and the point marker is enabled. The point marker is enabled by
1008 default.
1009
1010 @author: Invient
1011 @author: Richard Lincoln
1012 """
1013
1014 - def __init__(self, source, chart, category, point, mousePosition):
1015 """New instance of the point click event.
1016
1017 @param source:
1018 the chart object itself
1019 @param chart:
1020 the chart object itself
1021 @param category:
1022 a category to which point is associated in case of
1023 categorized axis,
1024 @param point:
1025 the point on which the click event occurred
1026 @param mousePosition:
1027 the position of a mouse when the click event occurred
1028 """
1029 super(PointClickEvent, self).__init__(source)
1030
1031 self._chart = chart
1032 self._category = category
1033 self._point = point
1034 self._mousePosition = mousePosition
1035
1037 """@return: Returns a category to which point is associated in case
1038 of categorized axis only.
1039 """
1040 return self._category
1041
1043 """@return: Returns the chart object associated with the point"""
1044 return self._chart
1045
1047 """@return: Returns the point on which the click event occurred"""
1048 return self._point
1049
1051 """@return: Returns the position of a mouse when the click event
1052 occurred"""
1053 return self._mousePosition
1054
1057 """Interface for listening for a L{PointClickEvent} triggered by
1058 L{InvientCharts}
1059
1060 @author: Invient
1061 @author: Richard Lincoln
1062 """
1063
1065 raise NotImplementedError
1066
1069 """Point remove event. This event is thrown, when any point of this chart
1070 is removed from its series.
1071
1072 This event is EXPERIMENTAL ONLY.
1073
1074 @author: Invient
1075 @author: Richard Lincoln
1076 """
1077
1078 - def __init__(self, source, chart, category, point):
1079 """New instance of the point remove event.
1080
1081 @param source:
1082 the chart object itself
1083 @param chart:
1084 the chart object itself
1085 @param category:
1086 a category to which point is associated in case of
1087 categorized axis,
1088 @param point:
1089 the point removed
1090 """
1091 super(PointRemoveEvent, self).__init__(source)
1092
1093 self._chart = chart
1094 self._category = category
1095 self._point = point
1096
1097
1099 """@return: Returns a category to which point is associated in case
1100 of categorized axis only.
1101 """
1102 return self._category
1103
1104
1106 """@return: Returns the chart object associated with the point"""
1107 return self._chart
1108
1109
1111 """@return: Returns the point which has been removed"""
1112 return self._point
1113
1116 """Interface for listening for a L{PointRemoveEvent} triggered by
1117 L{InvientCharts}
1118
1119 @author: Invient
1120 @author: Richard Lincoln
1121 """
1122
1124 raise NotImplementedError
1125
1128 """Point unselect event. This event is thrown, when any point of this
1129 chart is unselected and the point marker is enabled. The point marker
1130 is enabled by default.
1131
1132 @author: Invient
1133 @author: Richard Lincoln
1134 """
1135
1136 - def __init__(self, source, chart, category, point):
1137 """New instance of the point unselect event.
1138
1139 @param source:
1140 the chart object itself
1141 @param chart:
1142 the chart object itself
1143 @param category:
1144 a category to which point is associated in case of
1145 categorized axis,
1146 @param point:
1147 the point unselected as a result of this event
1148 """
1149 super(PointUnselectEvent, self).__init__(source)
1150
1151 self._chart = chart
1152 self._category = category
1153 self._point = point
1154
1156 """@return: Returns a category to which point is associated in case
1157 of categorized axis only.
1158 """
1159 return self._category
1160
1162 """@return: Returns the chart object associated with the point"""
1163 return self._chart
1164
1166 """@return: Returns the unselected point"""
1167 return self._point
1168
1171 """Interface for listening for a L{PointUnselectEvent} triggered by
1172 L{InvientCharts}
1173
1174 @author: Invient
1175 @author: Richard Lincoln
1176 """
1177
1179 raise NotImplementedError
1180
1183 """Point select event. This event is thrown, when any point of this chart
1184 is selected and the point marker is enabled. The point marker is enabled
1185 by default.
1186
1187 @author: Invient
1188 @author: Richard Lincoln
1189 """
1190
1191 - def __init__(self, source, chart, category, point):
1192 """New instance of the point select event.
1193
1194 @param source:
1195 the chart object itself
1196 @param chart:
1197 the chart object itself
1198 @param category:
1199 a category to which point is associated in case of
1200 categorized axis,
1201 @param point:
1202 the point selected as a result of this event
1203 """
1204 super(PointSelectEvent, self).__init__(source)
1205
1206 self._chart = chart
1207 self._category = category
1208 self._point = point
1209
1211 """@return: Returns a category to which point is associated in case
1212 of categorized axis only.
1213 """
1214 return self._category
1215
1217 """@return: Returns the chart object associated with the point"""
1218 return self._chart
1219
1221 """@return: Returns the selected point"""
1222 return self._point
1223
1226 """Interface for listening for a L{PointSelectListener} triggered by
1227 L{InvientCharts}
1228
1229 @author: Invient
1230 @author: Richard Lincoln
1231 """
1232
1234 raise NotImplementedError
1235
1236
1237 _POINT_CLICK_METHOD = getattr(PointClickListener, 'pointClick')
1238 _POINT_REMOVE_METHOD = getattr(PointRemoveListener, 'pointRemove')
1239 _POINT_SELECT_METHOD = getattr(PointSelectListener, 'pointSelected')
1240 _POINT_UNSELECT_METHOD = getattr(PointUnselectListener, 'pointUnSelect')
1246 """Series click event. This event is thrown, when any series of this
1247 chart is clicked.
1248
1249 @author: Invient
1250 @author: Richard Lincoln
1251 """
1252
1253 - def __init__(self, source, chart, series, point, mousePosition):
1254 """New instance of the series click event.
1255
1256 @param source:
1257 the chart object itself
1258 @param chart:
1259 the chart object itself
1260 @param series:
1261 the series on which click event occurred
1262 @param point:
1263 the closest point of a series
1264 @param mousePosition:
1265 the position of a mouse when the click event occurred
1266 """
1267 super(SeriesClickEvent, self).__init__(source)
1268
1269 self._chart = chart
1270 self._series = series
1271 self._point = point
1272 self._mousePosition = mousePosition
1273
1275 """@return: Returns the chart object associated with the point"""
1276 return self._chart
1277
1279 """@return: Returns the series object on which the click event
1280 occurred"""
1281 return self._series
1282
1284 """@return: Returns the point of a series closest to the position
1285 where mouse click event occurred.
1286 """
1287 return self._point
1288
1290 """@return: Returns the position of a mouse when the click event
1291 occurred"""
1292 return self._mousePosition
1293
1296 """Interface for listening for a L{SeriesClickListerner} triggered by
1297 L{InvientCharts}
1298
1299 @author: Invient
1300 @author: Richard Lincoln
1301 """
1302
1304 raise NotImplementedError
1305
1308 """Series Hide event. This event is thrown, when any series of this chart
1309 is hidden.
1310
1311 @author: Invient
1312 @author: Richard Lincoln
1313 """
1314
1315 - def __init__(self, source, chart, series):
1316 """@param source:
1317 the chart object itself
1318 @param chart:
1319 the chart object itself
1320 @param series:
1321 the series which got hidden
1322 """
1323 super(SeriesHideEvent, self).__init__(source)
1324 self._chart = chart
1325 self._series = series
1326
1328 """@return: Returns the chart object associated with the point"""
1329 return self._chart
1330
1332 """@return: Returns the series which got hidden"""
1333 return self._series
1334
1337 """Interface for listening for a L{SeriesHideEvent} triggered by
1338 L{InvientCharts}
1339
1340 @author: Invient
1341 @author: Richard Lincoln
1342 """
1343
1345 raise NotImplementedError
1346
1349 """Series show event. This event is thrown, when any series of this
1350 chart is displayed after a chart is created.
1351
1352 @author: Invient
1353 @author: Richard Lincoln
1354 """
1355
1356 - def __init__(self, source, chart, series):
1357 """New instance of the series show event.
1358
1359 @param source:
1360 the chart object itself
1361 @param chart:
1362 the chart object itself
1363 @param series:
1364 the series which got displayed
1365 """
1366 super(SeriesShowEvent, self).__init__(source)
1367 self._chart = chart
1368 self._series = series
1369
1371 """@return: Returns the chart object associated with the series"""
1372 return self._chart
1373
1375 """@return: Returns the series which got displayed"""
1376 return self._series
1377
1380 """Interface for listening for a L{SeriesShowEvent} triggered by
1381 L{InvientCharts}
1382
1383 @author: Invient
1384 @author: Richard Lincoln
1385 """
1386
1388 raise NotImplementedError
1389
1392 """Series legend item click event. This event is thrown, when legend item
1393 is clicked. This event is not applicable for PieChart instead use
1394 L{LegendItemClickEvent}
1395
1396 @author: Invient
1397 @author: Richard Lincoln
1398 """
1399
1400 - def __init__(self, source, chart, series):
1401 """New instance of the point click event.
1402
1403 @param source:
1404 the chart object itself
1405 @param chart:
1406 the chart object itself
1407 @param series:
1408 the series associated with the legend item
1409 """
1410 super(SeriesLegendItemClickEvent, self).__init__(source)
1411 self._chart = chart
1412 self._series = series
1413
1415 """@return: Returns the chart object associated with the series"""
1416 return self._chart
1417
1419 """@return: Returns the series associated with the legend item"""
1420 return self._series
1421
1424 """Interface for listening for a L{SeriesLegendItemClickEvent}
1425 triggered by L{InvientCharts}
1426
1427 @author: Invient
1428 @author: Richard Lincoln
1429 """
1430
1432 raise NotImplementedError
1433
1434
1435 _SERIES_CLICK_METHOD = getattr(SeriesClickListerner, 'seriesClick')
1436 _SERIES_HIDE_METHOD = getattr(SeriesHideListerner, 'seriesHide')
1437 _SERIES_SHOW_METHOD = getattr(SeriesShowListerner, 'seriesShow')
1438 _SERIES_LEGENDITEM_CLICK_METHOD = getattr(SeriesLegendItemClickListerner,
1439 'seriesLegendItemClick')
1443 """PieChart legend item click event. This event is thrown, when the
1444 legend item belonging to the pie point (slice) is clicked.
1445
1446 @author: Invient
1447 @author: Richard Lincoln
1448 """
1449
1450 - def __init__(self, source, chart, point):
1451 """New instance of the piechart legend item click event
1452
1453 @param source:
1454 the chart object itself
1455 @param chart:
1456 the chart object itself
1457 @param point:
1458 the pie point (slice) associated with the legend item
1459 """
1460 super(PieChartLegendItemClickEvent, self).__init__(source)
1461 self._chart = chart
1462 self._point = point
1463
1465 """@return: Returns the chart object associated with the point"""
1466 return self._chart
1467
1469 """@return: Returns the pie point (slice) associated with the legend
1470 item"""
1471 return self._point
1472
1475 """Interface for listening for a L{PieChartLegendItemClickEvent}
1476 triggered by L{InvientCharts}
1477
1478 @author: Invient
1479 @author: Richard Lincoln
1480 """
1481
1483 raise NotImplementedError
1484
1485
1486 _LEGENDITEM_CLICK_METHOD = getattr(PieChartLegendItemClickListener,
1487 'legendItemClick')
1491 """Chart Click event. This event is thrown, when this chart is clicked.
1492
1493 @author: Invient
1494 @author: Richard Lincoln
1495 """
1496
1497 - def __init__(self, source, chart, point, mousePosition):
1498 """New instance of the chart click event.
1499
1500 @param source:
1501 the chart object itself
1502 @param chart:
1503 the chart object itself
1504 @param point:
1505 the position where the click event occurred in axes units
1506 @param mousePosition:
1507 the coordinate of mouse where the click event occurred in
1508 pixels
1509 """
1510 super(ChartClickEvent, self).__init__(source)
1511
1512 self._chart = chart
1513 self._point = point
1514 self._mousePosition = mousePosition
1515
1516
1518 """Returns the chart object on which the click event occurred
1519
1520 @return: Returns the chart object on which the click event occurred
1521 @see: L{InvientCharts}
1522 """
1523 return self._chart
1524
1525
1527 """Returns the point representing the position where the click event
1528 occurred in axes units
1529
1530 @return: Returns the point representing the position where the click
1531 event occurred in axes units
1532 @see: L{Point}
1533 """
1534 return self._point
1535
1536
1538 """Returns the position of a mouse when the click event occurred
1539
1540 @return: Returns the position of a mouse when the click event occurred
1541 @see: L{MousePosition}
1542 """
1543 return self._mousePosition
1544
1545
1547 return ('ChartClickEvent [point=' + str(self._point)
1548 + ', mousePosition=' + str(self._mousePosition) + ']')
1549
1552 """Interface for listening for a L{ChartClickEvent} triggered by
1553 L{InvientCharts}
1554
1555 @author: Invient
1556 @author: Richard Lincoln
1557 """
1558
1560 raise NotImplementedError
1561
1564 """Add series event. This event is thrown, when a series is added to
1565 the chart.
1566
1567 @author: Invient
1568 @author: Richard Lincoln
1569 """
1570
1572 """New instance of the chart add series event.
1573
1574 @param source
1575 @param chart
1576 """
1577 super(ChartAddSeriesEvent, self).__init__(source)
1578
1579 self._chart = chart
1580
1582 """Returns the chart object to which a series is added
1583
1584 @return: Returns the chart object to which a series has been added.
1585 @see: L{InvientCharts}
1586 """
1587 return self._chart
1588
1591 """Interface for listening for a L{ChartAddSeriesEvent} triggered by
1592 L{InvientCharts}
1593
1594 @author: Invient
1595 @author: Richard Lincoln
1596 """
1597
1599 raise NotImplementedError
1600
1603 """Defines information on the selected area.
1604
1605 @author: Invient
1606 @author: Richard Lincoln
1607 """
1608
1609 - def __init__(self, xAxisMin, xAxisMax, yAxisMin, yAxisMax):
1610 self._xAxisMin = xAxisMin
1611 self._xAxisMax = xAxisMax
1612 self._yAxisMin = yAxisMin
1613 self._yAxisMax = yAxisMax
1614
1616 return self._xAxisMin
1617
1619 return self._xAxisMax
1620
1622 return self._yAxisMin
1623
1625 return self._yAxisMax
1626
1628 return ('ChartSelectedArea [xAxisMin=' + str(self._xAxisMin)
1629 + ', xAxisMax=' + str(self._xAxisMax)
1630 + ', yAxisMin=' + str(self._yAxisMin)
1631 + ', yAxisMax=' + str(self._yAxisMax) + ']')
1632
1635 """Chart zoom event. This event is thrown, when an area of the chart has
1636 been selected.
1637
1638 @author: Invient
1639 @author: Richard Lincoln
1640 """
1641
1642 - def __init__(self, source, chart, chartArea):
1643 """New instance of the chart zoom event.
1644
1645 @param source
1646 the chart object itself
1647 @param chart
1648 the chart object itself
1649 @param chartArea
1650 the chartArea object containing dimensions of zoomed area
1651 of the chart
1652 """
1653 super(ChartZoomEvent, self).__init__(source)
1654
1655 self._chart = chart
1656 self._chartArea = chartArea
1657
1658
1660 """Returns the chart object for which the zoom event has occurred
1661
1662 @return: Returns the chart object for which the zoom event has
1663 occurred
1664 """
1665 return self._chart
1666
1667
1669 """Returns the chartArea object containing dimensions of zoomed area
1670 of the chart
1671
1672 @return: Returns the chartArea object containing dimensions of zoomed
1673 area of the chart
1674 """
1675 return self._chartArea
1676
1679 """Interface for listening for a L{ChartZoomEvent} triggered by
1680 L{InvientCharts}
1681
1682 @author: Invient
1683 @author: Richard Lincoln
1684 """
1685
1687 raise NotImplementedError
1688
1691 """Chart reset zoom event. This event is thrown, when a chart is reset
1692 by setting its zoom level to normal.
1693
1694 @author: Invient
1695 @author: Richard Lincoln
1696 """
1697
1699 """New instance of the chart reset zoom event
1700
1701 @param source
1702 the chart object itself
1703 @param chart
1704 the chart object itself
1705 """
1706 super(ChartResetZoomEvent, self).__init__(source)
1707 self._chart = chart
1708
1709
1711 """Returns the chart object for which zoom has been reset to normal
1712
1713 @return: Returns the chart object for which zoom has been reset to
1714 normal
1715 """
1716 return self._chart
1717
1720 """Interface for listening for a L{@link ChartResetZoomEvent} triggered
1721 by L{InvientCharts}
1722
1723 @author: Invient
1724 @author: Richard Lincoln
1725 """
1726
1728 raise NotImplementedError
1729
1732 """Chart SVG event. This event is thrown, when an SVG string representing
1733 the chart is received or ready.
1734
1735 Note that this event is thrown only once after a
1736 L{ChartSVGAvailableListener} is registered.
1737
1738 @author: Invient
1739 @author: Richard Lincoln
1740 """
1741
1742 - def __init__(self, source, chart, svg):
1743 """New instance of the chart svg available event.
1744
1745 @param source:
1746 the chart object itself
1747 @param chart:
1748 the chart object itself
1749 @param svg:
1750 an svg string representing the chart object
1751 """
1752 super(ChartSVGAvailableEvent, self).__init__(source)
1753 self._chart = chart
1754 self._svg = svg
1755
1756
1758 """Returns the chart object for which an svg string representation
1759 is available
1760
1761 @return: Returns the chart object for which an svg string
1762 representation is available
1763 """
1764 return self._chart
1765
1766
1768 """@return: Returns an SVG string representing the chart"""
1769 return self._svg
1770
1773 """Interface for listening for a L{ChartSVGAvailableEvent} triggered by
1774 L{InvientCharts}.
1775
1776 The chart can have only one listener of this type registered at any time.
1777 If a listener has already been registered and an attempt is made to
1778 register another listener then the previously registered listener will be
1779 unregistered and the new listener will be registered.
1780
1781 A listener will be called only once after it has been registered though
1782 it will be called again if the same listener is registered again.
1783
1784 @author: Invient
1785 @author: Richard Lincoln
1786 """
1787
1790
1791
1792 _CHART_CLICK_METHOD = getattr(ChartClickListener, 'chartClick')
1793 _CHART_ADD_SERIES_METHOD = getattr(ChartAddSeriesListener, 'chartAddSeries')
1794 _CHART_ZOOM_METHOD = getattr(ChartZoomListener, 'chartZoom')
1795 _CHART_RESET_ZOOM_METHOD = getattr(ChartResetZoomListener, 'chartResetZoom')
1796 _CHART_SVG_AVAILABLE_METHOD = getattr(ChartSVGAvailableListener,
1797 'svgAvailable')
1798
1799
1800 -class Point(object):
1801 """This class represents a point of the chart's series. A series can have
1802 one or more points. A point has (X, Y) coordinates. None of the
1803 coordinates are mandatory. The name of a point can be displayed in a
1804 tooltip.
1805
1806 To represent no activity or missing points in the chart, create a point
1807 with both X and Y as null or just Y as null.
1808
1809 It is possible to specify custom configuration for each point. e.g. If a
1810 highest point can be marked in a chart with a different color using this
1811 configuration.
1812
1813 A point cannot be created without a series. It must belong to a series.
1814 However, the point must be added to a series by calling Series.addPoint()
1815 or Series.setPoints() to permanently add point to the series.
1816
1817 @author: Invient
1818 @author: Richard Lincoln
1819
1820 @see: L{DecimalPoint}
1821 @see: L{DateTimePoint}
1822 @see: L{PointConfig}
1823 """
1824
1825 - def __init__(self, series, name_or_config=None, config=None):
1826 """Creates a point with given arguments.
1827
1828 @param series:
1829 The series to which the point must be associated.
1830 @param name_or_config:
1831 The configuration for this point, or the name of this point
1832 @param config:
1833 The configuration for this point, if any
1834 @exception ValueError:
1835 If the argument series is null
1836 """
1837 self._id = None
1838 self._isAutosetX = None
1839 self._shift = False
1840
1841 name = None
1842 if name_or_config is not None:
1843 if isinstance(name_or_config, PointConfig):
1844 config = name_or_config
1845 name = None
1846 else:
1847 name = name_or_config
1848 config = None
1849
1850 self._series = series
1851 self._name = name
1852 self._config = config
1853
1854
1857
1858
1860 """@return: Returns name of this point"""
1861 return self._name
1862
1863
1865 """Sets name of this point
1866
1867 @param name:
1868 name of this point
1869 """
1870 self._name = name
1871
1872
1874 """@return: Returns L{Series} associated with this point"""
1875 return self._series
1876
1877
1879 """@return: Returns L{PointConfig} for this point"""
1880 return self._config
1881
1882
1884 """Sets L{PointConfig} for this point
1885
1886 @param config:
1887 configuration of this point
1888 @see: L{PointConfig}
1889 """
1890 self._config = config
1891
1892
1894 """@return: Returns true if X value of this point is set
1895 programmatically"""
1896 return self._isAutosetX
1897
1898
1900 """If the argument is true it indicates that the X value of this point
1901 is set programmatically and user has not specified it.
1902 """
1903 self._isAutosetX = isAutosetX
1904
1905
1907 """@return: Returns true if a point at the start of the series should
1908 beshifted off when this point is appended otherwise false.
1909 """
1910 return self._shift
1911
1912
1914 """A value of true means one point is shifted off the start of the
1915 series as one is appended to the end.
1916 """
1917 self._shift = shift
1918
1919
1921 """@return: Returns X value of this point"""
1922 raise NotImplementedError
1923
1924
1926 """@return: Returns Y value of this point"""
1927 raise NotImplementedError
1928
1929
1931 return ('Point [id=' + self._id
1932 + ', name=' + self._name
1933 + ', series=' + self._series.getName()
1934 + ', config=' + str(self._config) + ']')
1935
1938 """This class represent a point with (X, Y) both as number. It should be
1939 used to add points to L{XYSeries}
1940
1941 @author: Invient
1942 @author: Richard Lincoln
1943 """
1944
1946 """@param invientCharts:
1947 @param args:
1948 tuple of the form:
1949 - (series)
1950 - the series to which this belongs to
1951 - (series, y)
1952 - the series to which this belongs to
1953 - the y value of this point
1954 - (series, name, y)
1955 - the series to which this belongs to
1956 - the name of this point
1957 - the y value of this point
1958 - (x, y)
1959 - the x value of this point
1960 - the y value of this point
1961 - (series, name, y, config)
1962 - the series to which this belongs to
1963 - the name of this point
1964 - the y value of this point
1965 - the configuration of this point
1966 - (series, y, config)
1967 - the series to which this belongs to
1968 - the y value of this point
1969 - the configuration of this point
1970 - (series, x, y)
1971 - the series to which this belongs to
1972 - the x value of this point
1973 - the y value of this point
1974 - (series, x, y, config)
1975 - the series to which this belongs to
1976 - the x value of this point
1977 - the y value of this point
1978 - the configuration of this point
1979 """
1980 self._x = None
1981 self._y = None
1982
1983 nargs = len(args)
1984 if nargs == 1:
1985 series, = args
1986 super(DecimalPoint, self).__init__(series)
1987 elif nargs == 2:
1988 if isinstance(args[0], Series):
1989 series, y = args
1990 super(DecimalPoint, self).__init__(series)
1991 self._y = y
1992 else:
1993 x, y = args
1994 super(DecimalPoint, self).__init__(None)
1995 self._x = x
1996 self._y = y
1997 elif nargs == 3:
1998 if isinstance(args[1], (float, int)):
1999 if isinstance(args[2], PointConfig):
2000 series, y, config = args
2001 super(DecimalPoint, self).__init__(series, config)
2002 self._y = y
2003 else:
2004 series, x, y = args
2005 self.__init__(series, x, y, None)
2006 series, x, y = args
2007 self.__init__(series, x, y, None)
2008 else:
2009 series, name, y = args
2010 super(DecimalPoint, self).__init__(series, name)
2011 self._y = y
2012 elif nargs == 4:
2013 if isinstance(args[1], (float, int)):
2014 series, x, y, config = args
2015 super(DecimalPoint, self).__init__(series, config)
2016 self._x = x
2017 self._y = y
2018 else:
2019 series, name, y, config = args
2020 super(DecimalPoint, self).__init__(series, name, config)
2021 self._y = y
2022 else:
2023 raise ValueError
2024
2025
2028
2029
2030 - def setX(self, x):
2031 """Sets the x value of this point
2032 """
2033 self._x = x
2034
2035
2038
2039
2040 - def setY(self, y):
2041 """Sets the y value of this point
2042 """
2043 self._y = y
2044
2045
2047 return ('DecimalPoint [x=' + self._x
2048 + ', y=' + self._y
2049 + ', id=' + self.getId()
2050 + ', name=' + self.getName()
2051 + ', seriesName='
2052 + (self._series.getName()
2053 if self._series is not None else '')
2054 + ']')
2055
2056
2058 prime = 31
2059 result = 1
2060 result = ((prime * result)
2061 + (0 if self._y is None else hash(self._y)))
2062 return result
2063
2064
2066 if self is obj:
2067 return True
2068 if obj is None:
2069 return False
2070 if self.__class__ != obj.__class__:
2071 return False
2072 other = obj
2073
2074
2075 if (self._x is None) or (other._x is None):
2076 return False
2077 if not (self._x == other._x):
2078 return False
2079 if self._y is None:
2080 if other._y is not None:
2081 return False
2082 elif other._y is None:
2083 return False
2084 elif cmp(self._y, other._y) != 0:
2085 return False
2086 return True
2087
2090 """This class represent a point with (X, Y) both as number. It should
2091 be used to add points to L{DateTimeSeries}
2092
2093 @author: Invient
2094 @author: Richard Lincoln
2095 """
2096
2098 """@param args:
2099 tuple of the form:
2100 - (series)
2101 - the series to which this belongs to
2102 - (series, y)
2103 - the series to which this belongs to
2104 - the y value of this point
2105 - (series, name, y)
2106 - the series to which this belongs to
2107 - the name of this point
2108 - the y value of this point
2109 - (series, name, y, config)
2110 - the series to which this belongs to
2111 - the name of this point
2112 - the y value of this point
2113 - the configuration of this point
2114 - (series, x, y)
2115 - the series to which this belongs to
2116 - the x value of this point
2117 - the y value of this point
2118 """
2119 self._x = None
2120 self._y = None
2121
2122 nargs = len(args)
2123 if nargs == 1:
2124 series, = args
2125 super(DateTimePoint, self).__init__(series)
2126 elif nargs == 2:
2127 series, y = args
2128 self.__init__(series, '', y)
2129 elif nargs == 3:
2130 if isinstance(args[1], datetime):
2131 series, x, y = args
2132 self.__init__(series, y)
2133 self._x = x
2134 else:
2135 series, name, y = args
2136 super(DateTimePoint, self).__init__(series, name)
2137 self._y = y
2138 elif nargs == 4:
2139 series, name, y, config = args
2140 super(DateTimePoint, self).__init__(series, name, config)
2141 self._y = y
2142 else:
2143 raise ValueError
2144
2145
2148
2149
2150 - def setX(self, x):
2151 """Sets the x value of this point
2152
2153 @param x
2154 """
2155 self._x = x
2156
2157
2160
2161
2162 - def setY(self, y):
2163 """Sets the y value of this point
2164
2165 @param y
2166 """
2167 self._y = y
2168
2169
2171 return ('DateTimePoint [x='
2172 + getDate(self._x,
2173 self._series.isIncludeTime()
2174 if self._series is not None else False)
2175 + ', y=' + str(self._y) + ', id=' + self.getId()
2176 + ', name=' + self.getName()
2177 + ', seriesName=' + (self._series.getName()
2178 if self._series is not None else '')
2179 + ']')
2180
2181
2183 prime = 31
2184 result = 1
2185 result = ((prime * result) + (0 if self._y is None else hash(self._y)))
2186 return result
2187
2188
2190 if self is obj:
2191 return True
2192 if obj is None:
2193 return False
2194 if self.__class__ != obj.__class__:
2195 return False
2196 other = obj
2197
2198
2199 if (self._x is None) or (other._x is None):
2200 return False
2201 pointIncludeTime = (self.getSeries().isIncludeTime()
2202 if isinstance(self.getSeries(), DateTimeSeries) else False)
2203 pointOtherIncludeTime = (other.getSeries().isIncludeTime()
2204 if isinstance(other.getSeries(), DateTimeSeries) else False)
2205 pointX = getDate(self._x, pointIncludeTime)
2206 pointOtherX = getDate(other._x, pointOtherIncludeTime)
2207 if cmp(pointX, pointOtherX) != 0:
2208 return False
2209 if self._y is None:
2210 if other._y is not None:
2211 return False
2212 elif other._y is None:
2213 return False
2214 elif cmp(self._y, other._y) != 0:
2215 return False
2216 return True
2217
2220 """This class defines a series of the chart. A series contains a collection
2221 of points. Series can be one of types defined by L{SeriesType}.
2222
2223 Each series must have unique name. If an attempt is made to add two
2224 series with same then only the first added series will be in effect.
2225
2226 If the series type is not specified, it defaults to chart type and the
2227 default chart type is SeriesType.LINE. A series has unique xAxis and
2228 yAxis object associated with it. There is no need to set xAxis and yAxis
2229 unless the chart has more than one one axis of any type and the series
2230 must belong to any of the secondary axis.
2231
2232 It is also possible to specify configuration for individual series and
2233 not just series type.
2234
2235 @author: Invient
2236 @author: Richard Lincoln
2237 """
2238
2239 - def __init__(self, name, seriesType_or_config=None, config=None):
2240 """Creates a series with given name, type and configuration
2241
2242 @param name:
2243 the name of this series
2244 @param seriesType_or_config:
2245 the type of this series or the configuration for this series
2246 @param config:
2247 the configuration for this series
2248 """
2249 self._points = OrderedSet()
2250 self._name = ''
2251 self._type = None
2252 self._stack = None
2253 self._xAxis = None
2254 self._yAxis = None
2255 self._config = None
2256 self._invientCharts = None
2257
2258 seriesType = None
2259 if seriesType_or_config is not None:
2260 if isinstance(seriesType_or_config, SeriesType):
2261 seriesType = seriesType_or_config
2262 else:
2263 config = seriesType_or_config
2264
2265 self._name = name
2266 self._type = seriesType
2267 self._config = config
2268
2269
2271 """@return: Returns the configuration object associated with this
2272 series"""
2273 return self._config
2274
2275
2277 """@return: Returns name of this series"""
2278 return self._name
2279
2280
2282 """Sets name of this series
2283 """
2284 self._name = name
2285
2286
2288 """@return"""
2289 return self._type
2290
2291
2293 """Sets type of this series
2294 """
2295 self._type = typ
2296
2297
2299 """@return: Returns stack of this series"""
2300 return self._stack
2301
2302
2304 """By using this stack property, it is possible to group series in a
2305 stacked chart. Sets stack for this series. If two series belongs to
2306 the same stack then the resultant chart will be stacked chart
2307 """
2308 self._stack = stack
2309
2310
2312 """@return: Returns x-axis associated with this series.
2313 @see: L{Axis}
2314 """
2315 return self._xAxis
2316
2317
2319 """Sets x-axis of this series. A series can be associated with at most
2320 one x-axis.
2321 """
2322 self._xAxis = xAxis
2323
2324
2326 """@return: Returns y-axis of this series."""
2327 return self._yAxis
2328
2329
2331 """Sets y-axis of this series. A series can be associated with at most
2332 one y-axis.
2333 """
2334 self._yAxis = yAxis
2335
2336
2351
2352
2360
2361
2363 """Adds one or more points into this series, specified as an argument
2364 to this method
2365
2366 @return: Returns null if the argument is null otherwise returns a
2367 collection of points which are added in this series. If a
2368 point has same (x, y) value as any other point in the
2369 argument points then it will not be added.
2370 """
2371 points = [points] if isinstance(points, Point) else points
2372
2373 if shift:
2374
2375 pointsItr = iter(self._points)
2376 try:
2377 p = pointsItr.next()
2378 self._points.remove(p)
2379 except StopIteration:
2380 pass
2381
2382 pointsAddedList = list()
2383
2384 for point in points:
2385 if point not in self._points:
2386 self._points.add(point)
2387 pointsAddedList.append(point)
2388
2389 self.updatePointXValuesIfNotPresent()
2390
2391
2392 for point in pointsAddedList:
2393 if self._invientCharts is not None:
2394 self._invientCharts.addSeriesPointAddedOperation(
2395 point.getSeries().getName(), point)
2396 self._invientCharts.requestRepaint()
2397
2398 return OrderedSet(pointsAddedList)
2399
2400
2402 for point in points:
2403 self._points.add(point)
2404
2405
2407 """@return: Returns all points of this series. Adding or removing any
2408 point to or from the returned collection will not impact the
2409 chart. To add a point or points, use addPoint() or
2410 removePoint() method.
2411 """
2412 return OrderedSet(self._points)
2413
2414
2416 """Sets points into this series
2417
2418 @return: Returns null if the argument is null otherwise returns a
2419 collection of points which are set in this series. If a point
2420 has same (x, y) value as any other point in the argument
2421 points then it will not be added.
2422 """
2423 if points is not None:
2424 self._points.clear()
2425 self.addPointsInternal(points)
2426 self.updatePointXValuesIfNotPresent()
2427 if self._invientCharts is not None:
2428 cur = SeriesCUR(SeriesCURType.UPDATE, self.getName(), True)
2429 self._invientCharts.addSeriesCUROperation(cur)
2430 self._invientCharts.requestRepaint()
2431 return self.getPoints()
2432 return None
2433
2434
2436 """Each of the subclass needs to implement this method to ensure that
2437 each point has appropriate X value even if it is not specified.
2438 """
2439 pass
2440
2441
2450
2451
2460
2461
2463 self._invientCharts = invientCharts
2464
2465
2467 prime = 31
2468 result = 1
2469 result = ((prime * result)
2470 + (0 if self._name is None else hash(self._name)))
2471 return result
2472
2473
2475 if self is obj:
2476 return True
2477 if obj is None:
2478 return False
2479 if self.__class__ != obj.__class__:
2480 return False
2481 other = obj
2482 if self._name is None:
2483 if other._name is not None:
2484 return False
2485 elif not (self._name == other._name):
2486 return False
2487 return True
2488
2489
2491 return ('Series [points=' + self._points
2492 + ', name=' + self._name
2493 + ', type=' + str(self._type)
2494 + ', stack=' + self._stack
2495 + ', xAxis=' + str(self._xAxis)
2496 + ', yAxis=' + str(self._yAxis)
2497 + ', config=' + str(self._config) + ']')
2498
2501 """This class defines a number series. In this series both X and Y values
2502 must be number. To use date values, use L{DateTimeSeries}
2503
2504 @author: Invient
2505 @author: Richard Lincoln
2506
2507 @see: L{DateTimeSeries}
2508 """
2509
2510 - def __init__(self, name, seriesType_or_config=None, config=None):
2511 """Creates a series with given name, type and configuration
2512
2513 @param name:
2514 the name of this series
2515 @param seriesType_or_config:
2516 the type of this series or the configuration for this series
2517 @param config:
2518 the configuration for this series
2519 """
2520 seriesType = None
2521 if seriesType_or_config is not None:
2522 if isinstance(seriesType_or_config, SeriesType):
2523 seriesType = seriesType_or_config
2524 else:
2525 config = seriesType_or_config
2526
2527 super(XYSeries, self).__init__(name, seriesType, config)
2528
2529
2531 """Removes the specified point from the series
2532 """
2533 super(XYSeries, self).removePoint(*points)
2534
2535
2538
2539
2540 - def addPoint(self, point_or_points, shift=None):
2541 """Appends the specified point(s) into the series if they do not exists
2542 in this series. The points which already exists will not be appended. A
2543 collection of points appended to this series will be returned.
2544
2545 @param point_or_points:
2546 @param shift:
2547 If true then one point is shifted off the start of this
2548 series as one is appended to the end.
2549 @return: Returns a collection of points which are added in this
2550 series. If a point has same (x, y) value as any other point
2551 in the input argument points then it will not be added in
2552 this series.
2553 """
2554 if shift is None:
2555 points = point_or_points
2556 return super(XYSeries, self).addPoint(False, points)
2557 else:
2558 point = point_or_points
2559 point.setShift(shift)
2560 return super(XYSeries, self).addPoint(shift, point)
2561
2562
2565
2566
2568 """Sets points into this series. This method removes all of its points
2569 and then add points specified in the method argument. If the argument
2570 is null then no actions are taken.
2571
2572 @param points:
2573 the collection of points to set into this series.
2574 @return: Returns a collection of points which are set in this series.
2575 If a point has same (x, y) value as any other point in the
2576 argument points then it will not be added.
2577 """
2578 return super(XYSeries, self).setPoints(points)
2579
2580
2604
2607 """This class defines a datetime series. In this series, the X value must
2608 be date and Y values must be number. To use number values, use L{XYSeries}
2609
2610 By default, the time of a day is not included in the X value. In order to
2611 include time, use a constructor with argument isIncludeTime and pass true
2612 value for the argument.
2613
2614 @author: Invient
2615 @author: Richard Lincoln
2616
2617 @see: L{XYSeries}
2618 """
2619
2620 - def __init__(self, invientCharts, *args):
2621 """Creates a series with given name. This series will not consider time
2622 in the X property of L{DateTimePoint}.
2623
2624 @param args:
2625 tuple of the form:
2626 - (name)
2627 - the name of this series
2628 - (name, isIncludeTime)
2629 - the name of this series
2630 - If true then the time in the X property of L{DateTimePoint}
2631 will be considered when drawing the chart. Defaults to false.
2632 - (name, config)
2633 - the name of this series
2634 - the configuration for this series
2635 - (name, config, isIncludeTime)
2636 - the name of this series
2637 - the configuration for this series
2638 - If true then the time in the X property of L{DateTimePoint}
2639 will be considered when drawing the chart. Defaults to false.
2640 - (name, seriesType, isIncludeTime)
2641 - the name of this series
2642 - the type of this series
2643 - If true then the time in the X property of L{DateTimePoint}
2644 will be considered when drawing the chart. Defaults to false.
2645 - (name, seriesType, config)
2646 - the name of this series
2647 - the type of this series
2648 - the configuration for this series
2649 - (name, seriesType, config, isIncludeTime)
2650 - the name of this series
2651 - the type of this series
2652 - the configuration for this series
2653 - If true then the time in the X property of L{DateTimePoint}
2654 will be considered when drawing the chart. Defaults to false.
2655 """
2656 self._invientCharts = invientCharts
2657
2658 self._includeTime = None
2659
2660 args = args
2661 nargs = len(args)
2662 if nargs == 1:
2663 name, = args
2664 self.__init__(invientCharts, name, False)
2665 elif nargs == 2:
2666 if isinstance(args[1], SeriesType):
2667 name, seriesType = args
2668 self.__init__(invientCharts, name, seriesType, False)
2669 elif isinstance(args[1], SeriesConfig):
2670 name, config = args
2671 self.__init__(invientCharts, name, config, False)
2672 else:
2673 name, isIncludeTime = args
2674 super(DateTimeSeries, self).__init__(name)
2675 self._includeTime = isIncludeTime
2676 elif nargs == 3:
2677 if isinstance(args[1], SeriesType):
2678 if isinstance(args[2], SeriesConfig):
2679 name, seriesType, config = args
2680 self.__init__(invientCharts, name, seriesType, config, False)
2681 else:
2682 name, seriesType, isIncludeTime = args
2683 super(DateTimeSeries, self).__init__(name, seriesType)
2684 self._includeTime = isIncludeTime
2685 else:
2686 name, config, isIncludeTime = args
2687 super(DateTimeSeries, self).__init__(name, config)
2688 self._includeTime = isIncludeTime
2689 elif nargs == 4:
2690 name, seriesType, config, isIncludeTime = args
2691 super(DateTimeSeries, self).__init__(name, seriesType, config)
2692 self._includeTime = isIncludeTime
2693 else:
2694 raise ValueError
2695
2696
2698 """Removes all points specified as method argument into this series
2699 """
2700 super(DateTimeSeries, self).removePoint(points)
2701
2702
2705
2706
2707 - def addPoint(self, point_or_points, shift=None):
2708 """Appends the specified point(s) into the series if they do not exists in
2709 this series. The points which already exists will not be appended. A
2710 collection of points appended to this series will be returned.
2711
2712 @param point_or_points:
2713 @param shift:
2714 If true then one point is shifted off the start of this
2715 series as one is appended to the end.
2716 @return Returns a collection of points which are added in this
2717 series. If a point has same (x, y) value as any other point
2718 in the input argument points then it will not be added in
2719 this series.
2720 """
2721 if shift is None:
2722 points = point_or_points
2723 return super(DateTimeSeries, self).addPoint(False, points)
2724 else:
2725 point = point_or_points
2726 point.setShift(shift)
2727 return super(DateTimeSeries, self).addPoint(shift, point)
2728
2729
2731 """@return: Returns true if the time in the X property of
2732 L{DateTimePoint} will be considered when drawing the
2733 chart otherwise false.
2734 """
2735 return self._includeTime
2736
2737
2740
2741
2743 """Sets points into this series. This method removes all of its points
2744 and then add points specified in the method argument. If the argument
2745 is null then no actions are taken.
2746
2747 @param points:
2748 the collection of points to set into this series.
2749 @return: Returns a collection of points which are added in this
2750 series. If a point has same (x, y) value as any other point
2751 in the input argument points then it will not be added in
2752 this series.
2753 """
2754 return super(DateTimeSeries, self).setPoints(points)
2755
2756
2779
2780
2781 @classmethod
2783
2784
2785 return -3600000.0
2786
2787
2788 @classmethod
2790 ts = getDate(dt) + milliseconds
2791 return datetime.fromtimestamp(ts / 1e03)
2792
2793
2795 return ('DateTimeSeries [includeTime=' + self._includeTime
2796 + ', getConfig()=' + str(self._invientCharts.getConfig())
2797 + ', getName()=' + self.getName()
2798 + ', getType()=' + str(self.getType())
2799 + ', getStack()=' + self.getStack()
2800 + ', getXAxis()=' + str(self.getXAxis())
2801 + ', getYAxis()=' + str(self.getYAxis())
2802 + ']')
2803
2826
2827 SeriesType.COMMONSERIES = SeriesType('series')
2828 SeriesType.LINE = SeriesType('line')
2829 SeriesType.SPLINE = SeriesType('spline')
2830 SeriesType.SCATTER = SeriesType('scatter')
2831 SeriesType.AREA = SeriesType('area')
2832 SeriesType.AREASPLINE = SeriesType('areaspline')
2833 SeriesType.BAR = SeriesType('bar')
2834 SeriesType.COLUMN = SeriesType('column')
2835 SeriesType.PIE = SeriesType('pie')
2839
2842
2845
2846 - def __init__(self, typ, name, reloadPoints=False):
2847 self._type = typ
2848 self._name = name
2849 self._reloadPoints = reloadPoints
2850 self._pointsAdded = OrderedSet()
2851 self._pointsRemoved = OrderedSet()
2852
2853 super(SeriesCUR, self).__init__()
2854
2855
2857 """Indicates whether the client/terminal should update series by
2858 setting all data of a series instead of adding or removing individual
2859 points
2860
2861 @return: Returns true if the data of the series must be reloaded
2862 otherwise false.
2863 """
2864 return self._reloadPoints
2865
2866
2868 self._reloadPoints = reloadPoints
2869
2870
2872 self._pointsAdded.add(point)
2873
2874
2881
2882
2884
2885
2886
2887 return self._pointsAdded.remove(point)
2888
2889
2891 self._pointsAdded.clear()
2892 self._pointsRemoved.clear()
2893
2894
2896 return self._pointsAdded
2897
2898
2900 return self._pointsRemoved
2901
2902
2904 prime = 31
2905 result = 1
2906 result = ((prime * result)
2907 + (0 if self._name is None else hash(self._name)))
2908 result = ((prime * result)
2909 + (0 if self._type is None else hash(self._type)))
2910 return result
2911
2912
2914 if self is obj:
2915 return True
2916 if obj is None:
2917 return False
2918 if self.__class__ != obj.__class__:
2919 return False
2920 other = obj
2921 if self._name is None:
2922 if other._name is not None:
2923 return False
2924 elif not (self._name == other._name):
2925 return False
2926 if self._type is None:
2927 if other._type is not None:
2928 return False
2929 elif not (self._type == other._type):
2930 return False
2931 return True
2932
2933
2935 return ('SeriesCUR [type=' + str(self._type)
2936 + ', name=' + self._name
2937 + ', reloadPoints=' + str(self._reloadPoints)
2938 + ', pointsAdded=' + str(self._pointsAdded)
2939 + ', pointsRemoved=' + str(self._pointsRemoved)
2940 + ']')
2941
2944
2945 ADD = None
2946 UPDATE = None
2947 REMOVE = None
2948
2951
2954
2955 @classmethod
2958
2959 SeriesCURType.ADD = SeriesCURType('Add')
2960 SeriesCURType.UPDATE = SeriesCURType('Update')
2961 SeriesCURType.REMOVE = SeriesCURType('Remove')
2962