bugfix
This commit is contained in:
parent
5317227fbd
commit
5103a9a8d8
@ -1,85 +0,0 @@
|
|||||||
from kivy.uix.widget import Widget
|
|
||||||
from kivy.graphics import Color, Rectangle
|
|
||||||
from kivyblocks.colorcalc import *
|
|
||||||
from kivyblocks.charts.chart import Chart,ChartPart
|
|
||||||
|
|
||||||
class BarPart(ChartPart):
|
|
||||||
def __init__(self,widget,pos,size,color,data_offset):
|
|
||||||
self.widget = widget
|
|
||||||
self.pos = pos
|
|
||||||
self.size = size
|
|
||||||
self.color = color
|
|
||||||
self.data_offset = data_offset
|
|
||||||
|
|
||||||
def collide_point(self,x,y):
|
|
||||||
minx = self.widget.pos[0] + self.pos[0]
|
|
||||||
maxx = minx + self.size[0]
|
|
||||||
miny = self.widget.pos[1] + self.pos[1]
|
|
||||||
maxy = miny + self.size[1]
|
|
||||||
if minx <= x and x <= maxx and \
|
|
||||||
miny <= y and y <= maxy:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def draw(self):
|
|
||||||
with self.widget.canvas:
|
|
||||||
Color(*self.color)
|
|
||||||
Rectangle(pos=(self.widget.pos[0] + self.pos[0],
|
|
||||||
self.widget.pos[1] + self.pos[1]),
|
|
||||||
size = self.size)
|
|
||||||
|
|
||||||
def mark(self):
|
|
||||||
rcolor = reverseColor(self.color)
|
|
||||||
rcolor.append(0.8)
|
|
||||||
with self.widget.canvas.after:
|
|
||||||
Color(*reverseColor(self.color))
|
|
||||||
Rectangle(pos=(self.widget.pos[0] + self.pos[0],
|
|
||||||
self.widget.pos[1] + self.pos[1]),
|
|
||||||
size = self.size)
|
|
||||||
|
|
||||||
class Bar(Chart):
|
|
||||||
"""
|
|
||||||
a BAR class
|
|
||||||
"""
|
|
||||||
def __init__(self,**options):
|
|
||||||
"""
|
|
||||||
options={
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
title,
|
|
||||||
keyField,
|
|
||||||
valueField,
|
|
||||||
color1:
|
|
||||||
color2:
|
|
||||||
data=[
|
|
||||||
{
|
|
||||||
name,
|
|
||||||
value,
|
|
||||||
},{
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
self.data = None
|
|
||||||
super().__init__(**options)
|
|
||||||
|
|
||||||
def data2part(self):
|
|
||||||
data = self.data
|
|
||||||
kvs = [ [i[self.options['keyField']],i[self.options['valueField']]] for i in data ]
|
|
||||||
m = max([i[1] for i in kvs ])
|
|
||||||
cnt = len(kvs)
|
|
||||||
points = divide([0,0],[self.width,0],cnt)
|
|
||||||
color1='8833ee'
|
|
||||||
color2='ed8234'
|
|
||||||
colors = divideColor(color1,color2,cnt-1)
|
|
||||||
for i in range(cnt):
|
|
||||||
h = self.height * kvs[i][1] / m
|
|
||||||
c = colors[i]
|
|
||||||
part = BarPart(self,
|
|
||||||
points[i],
|
|
||||||
(points[i+1][0] - points[i][0],h),
|
|
||||||
colors[i],
|
|
||||||
i
|
|
||||||
)
|
|
||||||
self.chartparts.append(part)
|
|
||||||
|
|
@ -1,79 +0,0 @@
|
|||||||
from kivy.app import App
|
|
||||||
from kivy.graphics import Color, Rectangle
|
|
||||||
from kivy.uix.widget import Widget
|
|
||||||
from kivyblocks.colorcalc import toArrayColor
|
|
||||||
|
|
||||||
class ChartPart(object):
|
|
||||||
def __init__(self,pos,width,height):
|
|
||||||
self.pos = pos
|
|
||||||
self.width = width
|
|
||||||
self.height = height
|
|
||||||
|
|
||||||
def collide_point(self,x,y):
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def draw(self):
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def mark(self):
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
class Chart(Widget):
|
|
||||||
def __init__(self,**options):
|
|
||||||
super().__init__()
|
|
||||||
self.options = options
|
|
||||||
self.bg_color = toArrayColor(self.options.get('bg_color',[0.3,0.3,0.3,1]))
|
|
||||||
self.markpart = None
|
|
||||||
self.bind(size=self.onSize,pos=self.onSize)
|
|
||||||
self.register_event_type("on_press")
|
|
||||||
|
|
||||||
def unmark(self):
|
|
||||||
self.canvas.after.clear()
|
|
||||||
|
|
||||||
def getData(self):
|
|
||||||
url = self.options.get('url')
|
|
||||||
if url:
|
|
||||||
hc = App.get_running_app().hc
|
|
||||||
params = self.options.get('params',{})
|
|
||||||
d = hc.get(url,parms=param)
|
|
||||||
self.data = d.get('data',[])
|
|
||||||
else:
|
|
||||||
self.data = self.options.get('data',[])
|
|
||||||
self.chartparts = []
|
|
||||||
|
|
||||||
def on_touch_down(self,touch):
|
|
||||||
if touch.is_mouse_scrolling:
|
|
||||||
return False
|
|
||||||
if not self.collide_point(touch.x,touch.y):
|
|
||||||
return False
|
|
||||||
self.markpart = None
|
|
||||||
self.unmark()
|
|
||||||
for part in self.chartparts:
|
|
||||||
if part.collide_point(touch.x,touch.y):
|
|
||||||
self.markPart(part)
|
|
||||||
self.dispatch('on_press',self,self.data[part.data_offset])
|
|
||||||
return super(Chart, self).on_touch_down(touch)
|
|
||||||
|
|
||||||
def on_press(self,o,data):
|
|
||||||
print('data=',data)
|
|
||||||
|
|
||||||
def draw(self):
|
|
||||||
with self.canvas.before:
|
|
||||||
Color(*self.bg_color)
|
|
||||||
Rectangle(pos=self.pos,size=self.size)
|
|
||||||
|
|
||||||
self.canvas.clear()
|
|
||||||
for part in self.chartparts:
|
|
||||||
part.draw()
|
|
||||||
|
|
||||||
def markPart(self,part):
|
|
||||||
self.markpart = part
|
|
||||||
part.mark()
|
|
||||||
|
|
||||||
def onSize(self,o,v):
|
|
||||||
self.build()
|
|
||||||
|
|
||||||
def build(self):
|
|
||||||
self.getData()
|
|
||||||
self.data2part()
|
|
||||||
self.draw()
|
|
@ -1,81 +0,0 @@
|
|||||||
import math
|
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
class Point(object):
|
|
||||||
def __init__(self, x=0, y=0):
|
|
||||||
super().__init__()
|
|
||||||
self.x = x
|
|
||||||
self.y = y
|
|
||||||
|
|
||||||
class Line(object): # 直线由两个点组成
|
|
||||||
def __init__(self, p1, p2):
|
|
||||||
if isinstance(p1,list) or isinstance(p1,tuple):
|
|
||||||
self.p1 = Point(*p1)
|
|
||||||
else:
|
|
||||||
self.p1 = p1
|
|
||||||
if isinstance(p2,list) or isinstance(p2,tuple):
|
|
||||||
self.p2 = Point(*p2)
|
|
||||||
else:
|
|
||||||
self.p2 = p2
|
|
||||||
|
|
||||||
def vector(self):
|
|
||||||
return self.p1.x - self.p2.x,self.p1.y - self.p2.y
|
|
||||||
|
|
||||||
def lenght(self):
|
|
||||||
return math.sqrt(pow((self.p1.x - self.p2.x), 2)
|
|
||||||
+ pow((self.p1.y - self.p2.y), 2))
|
|
||||||
|
|
||||||
def get_cross_angle(self, l):
|
|
||||||
# 向量a
|
|
||||||
arr_a = np.array(self.vector())
|
|
||||||
# 向量b
|
|
||||||
arr_b = np.array(l.vector())
|
|
||||||
cos_value = float(arr_a.dot(arr_b)) / (np.sqrt(arr_a.dot(arr_a)) \
|
|
||||||
* np.sqrt(arr_b.dot(arr_b)))
|
|
||||||
# 注意转成浮点数运算
|
|
||||||
return np.arccos(cos_value) * (180 / np.pi)
|
|
||||||
# 两个向量的夹角的角度,
|
|
||||||
# 余弦值:cos_value, np.cos(para),
|
|
||||||
# 其中para是弧度,不是角度
|
|
||||||
|
|
||||||
class EllipseUtils(object):
|
|
||||||
def __init__(self,pos,size):
|
|
||||||
self.pos = Point(pos)
|
|
||||||
self.size = size
|
|
||||||
self.slides = []
|
|
||||||
super().__init__()
|
|
||||||
|
|
||||||
def split(self,data,colors):
|
|
||||||
self.slides = []
|
|
||||||
kvs = [ [i[self.options['keyField']],i[self.options['valueField']]] for i in data ]
|
|
||||||
total = sum([i[1] for i in kvs ])
|
|
||||||
start_degree = 0
|
|
||||||
cnt = len(kvs)
|
|
||||||
for i in range(cnt):
|
|
||||||
degree = start_degree + 360 * kvs[i][1] / total
|
|
||||||
self.slides.append((degress,colors[i]))
|
|
||||||
start_degree = degree
|
|
||||||
|
|
||||||
def isInside(self,a,b,x,y):
|
|
||||||
if a>b:
|
|
||||||
return x**x / a**a + y**y/b**b <= 1
|
|
||||||
return x**x / b**b + y**y / a**a <= 1
|
|
||||||
|
|
||||||
def collide_point(self,x,y):
|
|
||||||
a = float(self.size[0] / 2)
|
|
||||||
b = float(self.size[1] / 2)
|
|
||||||
x = x - self.pos[0]
|
|
||||||
y = y - self.pos[1]
|
|
||||||
if not self.isInside(a,b,x,y):
|
|
||||||
return -1
|
|
||||||
start_degress = 0
|
|
||||||
l = Line((a,b),(a,b*2))
|
|
||||||
l1 = Line((a,b),(x,y))
|
|
||||||
degress = l.get_cross_angle(l1)
|
|
||||||
if x < a:
|
|
||||||
degress = 360 - degress
|
|
||||||
for i in range(len(self.slides)):
|
|
||||||
if start_degress <= degress and degress < self.slides[i][0]:
|
|
||||||
return i
|
|
||||||
start_degress += self.slides[i][0]
|
|
||||||
return -1
|
|
@ -1,66 +0,0 @@
|
|||||||
|
|
||||||
import math
|
|
||||||
import numpy as np
|
|
||||||
from kivy.uix.widget import Widget
|
|
||||||
from kivyblocks.charts.geometry import EllipseUtils
|
|
||||||
|
|
||||||
class PiePart(ChartPart):
|
|
||||||
def collide_point(self,x,y):
|
|
||||||
if not self.isInSideEllipse(x,y):
|
|
||||||
return False
|
|
||||||
return self.isInSidePart(x,y)
|
|
||||||
|
|
||||||
def isInSideEllipse(self,x,y):
|
|
||||||
a = self.width / 2
|
|
||||||
b = self.height / 2
|
|
||||||
v = x ** x / a ** a + y**y / b ** b
|
|
||||||
if v <= 1:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
class Pie(Widget):
|
|
||||||
def __init__(self,**options):
|
|
||||||
"""
|
|
||||||
options={
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
title,
|
|
||||||
keyField,
|
|
||||||
valueField,
|
|
||||||
data=[
|
|
||||||
{
|
|
||||||
name,
|
|
||||||
value,
|
|
||||||
},{
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
self.options = options
|
|
||||||
self.initflag = False
|
|
||||||
super().__init__()
|
|
||||||
self.bind(size=self.onSize,pos=self.onSize)
|
|
||||||
|
|
||||||
def data2pie(self):
|
|
||||||
data = self.options.get('data',[])
|
|
||||||
kvs = [ [i[self.options['keyField']],i[self.options['valueField']]] for i in data ]
|
|
||||||
total = sum([i[1] for i in kvs ])
|
|
||||||
start_degree = 0
|
|
||||||
cnt = len(kvs)
|
|
||||||
color1='8833ee'
|
|
||||||
color2='ed8234'
|
|
||||||
colors = divideColor(color1,color2,cnt-1)
|
|
||||||
self.canvas.clear()
|
|
||||||
for i in range(cnt):
|
|
||||||
degree = start_degree + 360 * kvs[i][1] / total
|
|
||||||
with self.canvas:
|
|
||||||
Color(*colors[i])
|
|
||||||
Ellipse(pos=self.pos,
|
|
||||||
size=self.size,
|
|
||||||
angle_start=start_degree,
|
|
||||||
angle_end= degree)
|
|
||||||
start_degree = degree
|
|
||||||
|
|
||||||
def onSize(self,o,v):
|
|
||||||
self.data2pie()
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -1 +0,0 @@
|
|||||||
__version__ = '0.4.1.dev0'
|
|
@ -1,6 +0,0 @@
|
|||||||
import pytest
|
|
||||||
|
|
||||||
|
|
||||||
def test_flower():
|
|
||||||
from kivy_garden.graph import Graph
|
|
||||||
widget = Graph()
|
|
Loading…
Reference in New Issue
Block a user