Procházet zdrojové kódy

update `Chart` :eyes:

Ethosa před 3 roky
rodič
revize
47d03d19fe

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

@@ -18,20 +18,22 @@ type
       cval*: char
 
   ChartData* = ref object
+    chart_type*: ChartType
     data_color*: ColorRef
     data_name*: string
     x_axis*: seq[ChartDataValue]
     y_axis*: seq[ChartDataValue]
 
 
-proc newChartData*(data_name: string = "data", data_color: ColorRef = Color()): ChartData =
+proc newChartData*(data_name: string = "data", data_color: ColorRef = Color(),
+                   chart_type: ChartType = LINE_CHART): ChartData =
   ## Creates a new empty ChartData.
   runnableExamples:
     var my_chart_data = newChartData()
-  ChartData(x_axis: @[], y_axis: @[], data_name: data_name, data_color: data_color)
+  ChartData(x_axis: @[], y_axis: @[], data_name: data_name, data_color: data_color, chart_type: chart_type)
 
 proc newChartData*(x_length, y_length: int, data_name: string = "data",
-                   data_color: ColorRef = Color()): ChartData =
+                   data_color: ColorRef = Color(), chart_type: ChartType = LINE_CHART): ChartData =
   ## Creates a new ChartData with specified length.
   ##
   ## Arguments:
@@ -39,12 +41,12 @@ proc newChartData*(x_length, y_length: int, data_name: string = "data",
   ## - y_length -- length of `y_axis`.
   runnableExamples:
     var my_chart_data1 = newChartData(5, 5)
-  result = newChartData(data_name, data_color)
+  result = newChartData(data_name, data_color, chart_type)
   result.x_axis.setLen(x_length)
   result.y_axis.setLen(y_length)
 
-proc newChartData*(x_data, y_data: seq[ChartDataValue],
-                   data_name: string = "data", data_color: ColorRef = Color()): ChartData =
+proc newChartData*(x_data, y_data: seq[ChartDataValue], data_name: string = "data",
+                   data_color: ColorRef = Color(), chart_type: ChartType = LINE_CHART): ChartData =
   ## Creates a new ChartData from specified data.
   ##
   ## Arguments:
@@ -52,7 +54,7 @@ proc newChartData*(x_data, y_data: seq[ChartDataValue],
   ## - y_data -- specified data for `y_axis`.
   runnableExamples:
     var my_chart_data2 = newChartData(@[1, 5, 2], @["10.10.2021", "10.11.2021", "10.01.2021"])
-  ChartData(x_axis: x_data, y_axis: y_data, data_name: data_name, data_color: data_color)
+  ChartData(x_axis: x_data, y_axis: y_data, data_name: data_name, data_color: data_color, chart_type: chart_type)
 
 
 proc cmp(x, y: ChartDataValue): int =

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

@@ -211,11 +211,6 @@ proc copyColorTo*(dest, src: ColorRef) =
 proc glColor*(clr: ColorRef) =
   glColor4f(clr.r, clr.g, clr.b, clr.a)
 
-proc matchColor*(source: string): bool =
-  source.match(re"\A\s*rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+\.?\d*?)\s*\)\s*\Z") or
-  source.match(re"\A\s*rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)\s*\Z") or
-  source.match(re"\A(#|0x|0X)[0-9a-fA-F]{3,8}\Z")
-
 
 # --- Operators --- #
 proc `$`*(color: ColorRef): string =

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

@@ -100,7 +100,8 @@ type
     SCREEN_MODE_EXPANDED  ## Keep screen size.
 
   ChartType* = enum
-    LINE_CHART
+    LINE_CHART,
+    BAR_CHART
 
   ChartDataValueType* = enum
     INTEGER_VALUE,

+ 9 - 0
src/nodesnim/core/tools.nim

@@ -1,5 +1,6 @@
 # author: Ethosa
 import
+  re,
   math,
   vector2
 
@@ -26,3 +27,11 @@ iterator cubic_bezier_iter*(step: float, p0, p1, p2, p3: Vector2Obj): Vector2Obj
   while t <= 1f:
     yield Vector2(cubic_bezier(t, p0.x, p1.x, p2.x, p3.x), cubic_bezier(t, p0.y, p1.y, p2.y, p3.y))
     t += s
+
+proc matchBackgroundImage*(source: string, matches: var array[20, string]): bool =
+  source.match(re"\A\s*url\(([^\)]+)\)\s*\Z", matches)
+
+proc matchColor*(source: string): bool =
+  source.match(re"\A\s*rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+\.?\d*?)\s*\)\s*\Z") or
+  source.match(re"\A\s*rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)\s*\Z") or
+  source.match(re"\A(#|0x|0X)[0-9a-fA-F]{3,8}\Z")

+ 0 - 3
src/nodesnim/graphics/drawable.nim

@@ -259,9 +259,6 @@ method setShadowOffset*(self: DrawableRef, offset: Vector2Obj) {.base.} =
   self.shadow_offset = offset
 
 
-proc matchBackgroundImage*(source: string, matches: var array[20, string]): bool =
-  source.match(re"\A\s*url\(([^\)]+)\)\s*\Z", matches)
-
 method setStyle*(self: DrawableRef, s: StyleSheetRef) {.base.} =
   ## Sets new stylesheet.
   ##

+ 30 - 15
src/nodesnim/nodescontrol/chart.nim

@@ -3,10 +3,8 @@
 import
   ../thirdparty/opengl,
 
-  ../core/font,
   ../core/enums,
   ../core/color,
-  ../core/exceptions,
   ../core/vector2,
   ../core/chartdata,
   ../core/themes,
@@ -20,17 +18,15 @@ import
 type
   ChartObj* = object of ControlObj
     line_color*: ColorRef
-    chart_type*: ChartType
-    data*: ChartData
+    data*: seq[ChartData]
   ChartRef* = ref ChartObj
 
 
-proc Chart*(name: string = "Chart", chart_type: ChartType = LINE_CHART): ChartRef =
+proc Chart*(name: string = "Chart"): ChartRef =
   ## Creates a new Chart object.
   nodepattern(ChartRef)
   controlpattern()
-  result.chart_type = chart_type
-  result.data = newChartData("some data", current_theme~accent)
+  result.data = @[]
   result.line_color = current_theme~foreground
 
 
@@ -42,9 +38,6 @@ method draw*(self: ChartRef, w, h: GLfloat) =
     y = h/2 - self.global_position.y
     start_x = x + self.rect_size.x/10
     end_y = y - self.rect_size.y + self.rect_size.y/10
-    data = zip(self.data.x_axis, self.data.y_axis)
-    width = (self.rect_size.x - self.rect_size.x/5) / data.len.float
-    max_val = self.data.findMax().y.getNum()
 
   glColor(self.line_color)
   glLineWidth(2)
@@ -54,10 +47,32 @@ method draw*(self: ChartRef, w, h: GLfloat) =
   glVertex2f(x + self.rect_size.x - self.rect_size.x/10, end_y)
   glEnd()
 
-  glColor(self.data.data_color)
-  for i in data.low..data.high:
+  for chart_data in self.data:
     let
-      j = i.float
-      h = (self.rect_size.y - self.rect_size.y/5) * (data[i][1].getNum() / max_val)
-    glRectf(start_x + width*j, end_y + h, start_x + width*(j+1), end_y)
+      data = zip(chart_data.x_axis, chart_data.y_axis)
+      max_height = self.rect_size.y - self.rect_size.y/5
+      max_val = chart_data.findMax().y.getNum()
+
+    glColor(chart_data.data_color)
+
+    case chart_data.chart_type
+    of LINE_CHART:
+      let section_width = (self.rect_size.x - self.rect_size.x/5) / (data.len.float-1)
+      glBegin(GL_LINE_STRIP)
+      for i in data.low..data.high:
+        let
+          j = i.float
+          h = max_height * (data[i][1].getNum() / max_val)
+        glVertex2f(start_x + section_width*j, end_y + h)
+      glEnd()
+    of BAR_CHART:
+      let section_width = (self.rect_size.x - self.rect_size.x/5) / data.len.float
+      for i in data.low..data.high:
+        let
+          j = i.float
+          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)
+
+method addChartData*(self: ChartRef, chart_data: ChartData) {.base.} =
+  self.data.add(chart_data)
 

+ 0 - 9
src/nodesnim/runtime/scene_loader.nim

@@ -15,15 +15,6 @@ import
   macros
 
 
-macro `!`(props, fn, code: untyped): untyped =
-  let
-    node = ident("node")
-    value = ident("value")
-  result = quote do:
-    `props`[`fn[1]`] =
-      proc(`node`: NodeRef, `value`: string) =
-        `code`
-
 macro `mkattrs`*(properties_var, prop_list: untyped): untyped =
   if prop_list.kind != nnkStmtList and properties_var.kind != nnkCall:
     return

+ 9 - 4
tests/test3.nim

@@ -337,12 +337,17 @@ suite "Work with Control nodes.":
           tooltip.showAtMouse()
     getSceneByName("main").addChild(tooltip)
 
-  test "Line chart test":
+  test "Line & Bar chart test":
     build:
       - Chart line_chart:
-        data: newChartData(
-          @["one", "two", "three", "four", "five", "six"],
-          @[1, 8, 18, 32, 4, 16], "myData", current_theme~accent)
+        call addChartData(
+          newChartData(
+            @["one", "two", "three", "four", "five", "six"],
+            @[1, 8, 18, 32, 4, 16], "myData", current_theme~accent_dark, BAR_CHART))
+        call addChartData(
+          newChartData(
+            @["one", "two", "three", "four", "five", "six"],
+            @[1, 8, 18, 32, 4, 16], "myData", current_theme~accent, LINE_CHART))
 
         call move(100, 450)
         call resize(320, 196)