From b778460312c71cdf945dc83b4f4b5b53c4c12fcc Mon Sep 17 00:00:00 2001 From: linarphy Date: Tue, 16 Jan 2024 01:08:06 +0100 Subject: [PATCH] Add title support --- README.md | 4 +- lichartee.js | 256 ++++++++++++++++++++++++++++++++++++++++----------- test.js | 6 +- 3 files changed, 209 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index 0b21786..fcb2dc0 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,9 @@ This project is licensied under the Chocolate-Ware license - see the ## Changelog +*v 0.1.3* +- Add text support (title only) + *v 0.1.2* - Add documentation @@ -40,6 +43,5 @@ This project is licensied under the Chocolate-Ware license - see the ## Roadmap -- Add text to plots - Add more option to stylize the line - Add **point** style diff --git a/lichartee.js b/lichartee.js index abf4d3d..314a0bd 100644 --- a/lichartee.js +++ b/lichartee.js @@ -111,57 +111,13 @@ class Canvas let axes = this.figure.list_axes[index_axes]; let x_proportion = axes.width/this.figure.width; let end_x = start_x + this.ctx.canvas.width * x_proportion; - this.ctx.beginPath(); - this.ctx.strokeStyle = 'black'; - this.ctx.setLineDash([]); - this.ctx.strokeRect( - start_x, 0 , - end_x, this.ctx.canvas.height + axes.draw( + this.ctx, + [ + [start_x, 0 ], + [end_x , this.ctx.canvas.height], + ], ); - const x_min = get_ext_array( - axes.lines.map( - (element) => element.x.reduce( - (a, b) => Math.min(a, b), - Infinity - ) - ) , - Math.min, - 1 - ); - const y_min = get_ext_array( - axes.lines.map( - (element) => element.y.reduce( - (a, b) => Math.min(a, b), - Infinity - ) - ) , - Math.min, - 1 - ); - const x_max = get_ext_array( - axes.lines.map( - (element) => element.x.reduce( - (a, b) => Math.max(a, b), - -Infinity - ) - ) - ); - const y_max = get_ext_array( - axes.lines.map( - (element) => element.y.reduce( - (a, b) => Math.max(a, b), - -Infinity - ) - ) - ); - for (const index_line in axes.lines) - { - axes.lines[index_line].draw( - this.ctx , - [[start_x, 0],[end_x, this.ctx.canvas.height]], - [[x_min, y_min], [x_max, y_max]] - ); - } start_x = end_x; } } @@ -233,10 +189,10 @@ class Axes title = '' , ) { - this.width = width ; - this.height = height ; - this.title = title ; - this.lines = [] ; + this.width = width; + this.height = height; + this.title = new Title( title ); + this.lines = []; } /** @@ -262,6 +218,93 @@ class Axes let line = new Line(x, y, linestyle, label); this.lines.push(line); } + + /** + * render the axes to the canvas + * + * @param ctx CanvasRenderingContext2D Context of the canvas + * @param window 2darray Window where to draw the canvas + */ + draw(ctx, window) + { + const x_min = get_ext_array( + this.lines.map( + (element) => element.x.reduce( + (a, b) => Math.min(a, b), + Infinity + ) + ) , + Math.min, + 1 + ); + const y_min = get_ext_array( + this.lines.map( + (element) => element.y.reduce( + (a, b) => Math.min(a, b), + Infinity + ) + ) , + Math.min, + 1 + ); + const x_max = get_ext_array( + this.lines.map( + (element) => element.x.reduce( + (a, b) => Math.max(a, b), + -Infinity + ) + ) + ); + const y_max = get_ext_array( + this.lines.map( + (element) => element.y.reduce( + (a, b) => Math.max(a, b), + -Infinity + ) + ) + ); + let plot_window = this.title.draw( + ctx , + window, + ); + for (const index_line in this.lines) + { + this.lines[index_line].draw( + ctx , + plot_window, + [ + [x_min, y_min], + [x_max, y_max], + ] , + ); + } + ctx.beginPath(); + ctx.strokeStyle = 'black'; + ctx.setLineDash([]); + ctx.strokeRect( + plot_window[0][0], plot_window[0][1], + plot_window[1][0] - plot_window[0][0], + plot_window[1][1] - plot_window[0][1], + ); + } + + /** + * title setter + * + * @param content String Content of the title + */ + set title(content) + { + this._title = new Title(content); + } + + /** + * title getter + */ + get title() + { + return this._title; + } } /** @@ -383,6 +426,111 @@ class Line } } +/** + * font object + * + * @property size int font-size (px) + * @property family string font-family + * @property color string font color + */ +class Font +{ + /** + * @param size int font-size (px) + * @param family string font-family + * @param color string font color + */ + constructor( + size = 20 , + family = 'sans-serif', + color = 'black' , + ) + { + this.size = size; + this.family = family; + this.color = color; + } + + /** + * Convert font to css font proprety's syntax + * + * @return String + */ + toString() + { + return this.size.toString() + 'px ' + self.family; + } +} + +/** + * title of an axes + * + * @property content String Content of a title + * @property font Font Font of a title + */ +class Title +{ + /** + * @param content Content Content of a title + * @param font Font Font of a title + */ + constructor( + content = '' , + font = undefined, + margin = 5 , + ) + { + this.content = content; + if (font === undefined) + { + font = new Font(); + } + this.font = font; + this.margin = margin; + } + + /** + * draw the title in the given windows + * + * @param ctx CanvasRenderingContext2D Context of the canvas + * @param window int Window where to write the title on + * + * @return plot_windows int New windows for the plot + */ + draw(ctx, window) + { + ctx.font = this.font.toString(); + let width = ctx.measureText(this.content).width; + if (width > window[1][0] - window[0][0] + 2 * this.margin) + { + ctx.fillText( + this.content , + window[0][0] , + this.font.size + this.margin, + window[1][0] - window[0][0], + ); + } + else + { + let text_position = window[0][0] + ( + window[1][0] - window[0][0] - width + ) / 2 + ctx.fillText( + this.content, + text_position, + this.font.size + this.margin, + ); + } + return [ + [ + window[0][0], + window[0][1] + this.font.size + 2 * this.margin, + ], + [window[1][0], window[1][1]], + ]; + } +} + /** * get max or min of a 1d array of number * diff --git a/test.js b/test.js index 9a92f7f..996d91b 100644 --- a/test.js +++ b/test.js @@ -1,8 +1,8 @@ let manager = new Manager( document.getElementsByTagName('main')[0] ); -manager.add_canvas(500, 500); -manager.add_canvas(500, 500).figure.add_axes().plot( +manager.add_canvas(1000, 500); +manager.add_canvas(1000, 500).figure.add_axes().plot( [0,1,2,3,4,5] , [0,1,4,9,16,25], { @@ -10,6 +10,7 @@ manager.add_canvas(500, 500).figure.add_axes().plot( style: 'dashed' } ); +manager.list_canvas[0].figure.list_axes[0].title = 'squared and x2'; manager.list_canvas[0].figure.list_axes[0].plot( [0,1,2,3,4,5], [0,2,4,6,8,10] @@ -22,4 +23,5 @@ manager.list_canvas[0].figure.add_axes().plot( style: 'dashdot' } ); +manager.list_canvas[0].figure.list_axes[0].title = '1/x'; manager.draw();