Add title support

This commit is contained in:
linarphy 2024-01-16 01:08:06 +01:00
parent f9b99feccd
commit b778460312
No known key found for this signature in database
GPG key ID: 0610ABB68DAA7B65
3 changed files with 209 additions and 57 deletions

View file

@ -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

View file

@ -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<Number> 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<array> Window where to write the title on
*
* @return plot_windows int<array> 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
*

View file

@ -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();