Ethosa пре 3 година
родитељ
комит
69aab50836

+ 7 - 0
src/nodesnim/core/chartdata.nim

@@ -90,6 +90,13 @@ proc getNum*(val: ChartDataValue): float =
   of STRING_VALUE:
     0f
 
+proc getSorted*(data: ChartData): seq[tuple[x, y: ChartDataValue]] =
+  zip(data.x_axis, data.y_axis).sorted do (a, b: tuple[x, y: ChartDataValue]) -> int: cmp(a.y.getNum(), b.y.getNum())
+
+proc getSum*(data: ChartData): float =
+  for i in data.y_axis:
+    result += i.getNum()
+
 
 converter toChartDataValue*(val: seq[int]): seq[ChartDataValue] =
   result = @[]

+ 4 - 1
src/nodesnim/core/enums.nim

@@ -50,6 +50,8 @@ type
     TEXTURE_RECT_NODE,
     VBOX_NODE,
     SUB_WINDOW_NODE,
+    TOOLTIP_NODE,
+    CHART_NODE,
     # 3D nodes
     NODE3D_NODE,
     GEOMETRY_INSTANCE_NODE,
@@ -101,7 +103,8 @@ type
 
   ChartType* = enum
     LINE_CHART,
-    BAR_CHART
+    BAR_CHART,
+    PIE_CHART
 
   ChartDataValueType* = enum
     INTEGER_VALUE,

+ 0 - 1
src/nodesnim/core/tileset.nim

@@ -38,7 +38,6 @@ proc TileSet*(img: string, tile_size: Vector2Obj, mode: Glenum = GL_RGB): TileSe
   )
 
   surface.freeSurface()
-  surface = nil
 
 proc draw*(self: TileSetObj, tilex, tiley, x, y, z: float) =
   ## Draws tile at position `tilex`,`tiley` to `x`,`y` position.

+ 5 - 0
src/nodesnim/core/vector2.nim

@@ -25,6 +25,11 @@ proc newVector2*(vec2: Vector2Obj): ref Vector2Obj =
   new result
   result[] = vec2
 
+proc newVector2*(x, y: float): ref Vector2Obj =
+  new result
+  result.x = x
+  result.y = y
+
 
 proc abs*(a: Vector2Obj): Vector2Obj =
   Vector2(abs(a.x), abs(a.y))

+ 40 - 8
src/nodesnim/nodescontrol/chart.nim

@@ -12,7 +12,8 @@ import
   ../nodes/node,
 
   control,
-  sequtils
+  sequtils,
+  math
 
 
 type
@@ -28,6 +29,15 @@ proc Chart*(name: string = "Chart"): ChartRef =
   controlpattern()
   result.data = @[]
   result.line_color = current_theme~foreground
+  result.kind = CHART_NODE
+
+method hasAxis*(self: ChartRef): bool {.base.} =
+  ## Returns true, if chart contains axis data.
+  ## For example: LINE_CHART, BAR_CHART.
+  for data in self.data:
+    if data.chart_type in [LINE_CHART, BAR_CHART]:
+      return true
+  false
 
 
 method draw*(self: ChartRef, w, h: GLfloat) =
@@ -39,13 +49,14 @@ method draw*(self: ChartRef, w, h: GLfloat) =
     start_x = x + self.rect_size.x/10
     end_y = y - self.rect_size.y + self.rect_size.y/10
 
-  glColor(self.line_color)
-  glLineWidth(2)
-  glBegin(GL_LINE_STRIP)
-  glVertex2f(start_x, y)
-  glVertex2f(start_x, end_y)
-  glVertex2f(x + self.rect_size.x - self.rect_size.x/10, end_y)
-  glEnd()
+  if self.hasAxis():
+    glColor(self.line_color)
+    glLineWidth(2)
+    glBegin(GL_LINE_STRIP)
+    glVertex2f(start_x, y)
+    glVertex2f(start_x, end_y)
+    glVertex2f(x + self.rect_size.x - self.rect_size.x/10, end_y)
+    glEnd()
 
   for chart_data in self.data:
     let
@@ -65,6 +76,7 @@ method draw*(self: ChartRef, w, h: GLfloat) =
           h = max_height * (data[i][1].getNum() / max_val)
         glVertex2f(start_x + section_width*j + section_width/2, end_y + h)
       glEnd()
+
     of BAR_CHART:
       for i in data.low..data.high:
         let
@@ -72,6 +84,26 @@ method draw*(self: ChartRef, w, h: GLfloat) =
           h = max_height * (data[i][1].getNum() / max_val)
         glRectf(start_x + section_width*j, end_y + h, start_x + section_width*(j+1), end_y)
 
+    of PIE_CHART:
+      let
+        d = chart_data.getSorted()
+        sum = chart_data.getSum()
+        radius = min(self.rect_size.x, self.rect_size.y)/2
+        center = Vector2(x + self.rect_size.x/2, y - self.rect_size.y/2)
+      var
+        angle = PI/2
+        a: float
+      for i in d.low..d.high:
+        glBegin(GL_TRIANGLE_FAN)
+        glVertex2f(center.x, center.y)
+        a = angle
+        angle += d[i][1].getNum() / sum * TAU
+        while a <= angle:
+          glVertex2f(center.x + cos(a)*radius, center.y + sin(a)*radius)
+          a += 0.01
+        glEnd()
+        glColor4f(angle/6, angle/5, angle/4, 1f)
+
 method addChartData*(self: ChartRef, chart_data: ChartData) {.base.} =
   self.data.add(chart_data)
 

+ 1 - 0
src/nodesnim/nodescontrol/tooltip.nim

@@ -40,6 +40,7 @@ proc ToolTip*(name: string = "ToolTip",
   result.background.enableShadow(true)
   result.background.setShadowOffset(Vector2(0, 5))
   result.mousemode = MOUSEMODE_IGNORE
+  result.kind = TOOLTIP_NODE
   result.hide()
 
 

+ 15 - 2
tests/test3.nim

@@ -339,7 +339,7 @@ suite "Work with Control nodes.":
 
   test "Line & Bar chart test":
     build:
-      - Chart line_chart:
+      - Chart my_chart:
         call addChartData(
           newChartData(
             @["one", "two", "three", "four", "five", "six"],
@@ -352,7 +352,20 @@ suite "Work with Control nodes.":
         call move(100, 450)
         call resize(320, 196)
 
-    getSceneByName("main").addChildren(line_chart)
+    getSceneByName("main").addChildren(my_chart)
+
+  test "Pie chart test":
+    build:
+      - Chart circle_chart:
+        call addChartData(
+          newChartData(
+            @["one", "two", "three", "four", "five", "six"],
+            @[1, 8, 18, 32, 4, 16], "myData", current_theme~accent_dark, PIE_CHART))
+
+        call move(900, 450)
+        call resize(128, 128)
+
+    getSceneByName("main").addChildren(circle_chart)
 
 
   test "Launch window":