Source code for compas_rhino.forms.chart
from __future__ import print_function
from __future__ import absolute_import
from __future__ import division
try:
basestring
except NameError:
basestring = str
from compas_rhino.forms.base import BaseForm
import clr
from System.Drawing import Size
from System.Drawing import Point
from System.Drawing import Color
clr.AddReference("System.Windows.Forms.DataVisualization")
from System.Windows.Forms.DataVisualization import Charting # noqa: E402
__all__ = ['ChartForm']
class Series(object):
pass
[docs]class ChartForm(BaseForm):
"""A form for displaying charts.
Parameters
----------
series : list of dict
A list of dictionaries with each dictionary defining the attributes of a series.
The following attributes are supported:
* name: The name of the series.
* data: A dictionary with x-y pairs.
* color (optional): A hex color or an RGB(255) color specification.
* linewidth (optional): The width of the series graph line.
* linetype (optional): The visual style of the graph line.
Should be one of ``{'solid', 'dotted', 'dashed'}``.
xlimits : 2-tuple
Minimum and maximum values on the X-axis.
xstep : int
Size of the steps along the X-axis.
ylimits : 2-tuple, optional
Minimum and maximum values on the Y-axis.
Default is ``None``, in which case the limits will be computed from the
min/max values of the data in the series.
ystep : int, optional
Size of the steps along the Y-axis.
Default is ``int((ymax - ymin) / 10.)```.
Other Parameters
----------------
bgcolor : str, tuple, System.Drawing.Color
The background color of the chart area.
Examples
--------
.. code-block:: python
import random
from compas.utilities import fibonacci
from compas_rhino.forms import ChartForm
series = [
{
'name' : 'series1',
'color' : (255, 0, 0),
'linewidth' : 1,
'linestyle' : 'dashed',
'data' : dict((str(i), random.randint(30, 70)) for i in range(10)),
},
{
'name' : 'series2',
'color' : (0, 255, 0),
'linewidth' : 1,
'linestyle' : 'solid',
'data' : dict((str(i), i ** 2) for i in range(10)),
},
{
'name' : 'series3',
'color' : (0, 0, 255),
'linewidth' : 1,
'linestyle' : 'dotted',
'data' : dict((str(i), fibonacci(i)) for i in range(10)),
},
]
form = ChartForm(series, (0, 10), 1)
form.show()
"""
def __init__(self, series,
xlimits, xstep,
ylimits=None, ystep=None,
chartsize=(800, 600), padding=(20, 20, 20, 20),
bgcolor=None,
title='Chart', **kwargs):
self._bgcolor = None
w, h = chartsize
self.chartwidth = w
self.chartheight = h
self.padding = padding
self.series = series
self.xmin = xlimits[0]
self.xmax = xlimits[1]
self.xstep = xstep
self.bgcolor = bgcolor
self.ymin = 0
self.ymax = 0
self.ystep = None
for attr in series:
keys = sorted(attr['data'].keys(), key=int)
values = [attr['data'][key] for key in keys]
y = map(float, values)
self.ymin = min(min(y), self.ymin)
self.ymax = max(max(y), self.ymax)
self.ystep = int((self.ymax - self.ymin) / 10.)
super(ChartForm, self).__init__(title)
@property
def bgcolor(self):
return self._bgcolor
@bgcolor.setter
def bgcolor(self, colour):
if not colour:
self._bgcolor = Color.White
elif isinstance(colour, Color):
self._bgcolor = colour
elif isinstance(colour, basestring):
raise NotImplementedError
elif isinstance(colour, tuple):
self._bgcolor = Color.FromArgb(* colour)
else:
raise NotImplementedError
[docs] def init(self):
w = self.chartwidth + self.padding[1] + self.padding[3]
h = self.chartheight + self.padding[0] + self.padding[2]
self.ClientSize = Size(w, h)
charting = Charting
chart = charting.Chart()
chart.Location = Point(self.padding[3], self.padding[0])
chart.Size = Size(self.chartwidth, self.chartheight)
chart.ChartAreas.Add('series')
area = chart.ChartAreas['series']
x = area.AxisX
x.Minimum = self.xmin
x.Maximum = self.xmax
x.Interval = self.xstep
x.MajorGrid.LineColor = Color.White
x.MajorGrid.LineDashStyle = charting.ChartDashStyle.NotSet
y = area.AxisY
y.Minimum = self.ymin
y.Maximum = self.ymax
y.Interval = self.ystep
y.MajorGrid.LineColor = Color.Gray
y.MajorGrid.LineDashStyle = charting.ChartDashStyle.Dot
for attr in self.series:
name = attr['name']
color = attr['color']
linewidth = attr['linewidth']
chart.Series.Add(name)
series = chart.Series[name]
series.ChartType = charting.SeriesChartType.Line
series.Color = Color.FromArgb(*color)
series.BorderWidth = linewidth
keys = sorted(attr['data'].keys(), key=int)
for key in keys:
value = attr['data'][key]
series.Points.AddXY(int(key), value)
area.BackColor = self.bgcolor
self.Controls.Add(chart)
# ==============================================================================
# Main
# ==============================================================================
if __name__ == '__main__':
import random
from compas.utilities import fibonacci
series = [
{
'name': 'series1',
'color': (255, 0, 0),
'linewidth': 1,
'data': {str(i): random.randint(30, 70) for i in range(10)},
},
{
'name': 'series2',
'color': (0, 255, 0),
'linewidth': 1,
'data': {str(i): i ** 2 for i in range(10)},
},
{
'name': 'series3',
'color': (0, 0, 255),
'linewidth': 1,
'data': {str(i): fibonacci(i) for i in range(10)},
},
]
form = ChartForm(series, (0, 10), 1)
form.show()