Add marker style and update drawing step

This commit is contained in:
linarphy 2024-01-25 16:26:48 +01:00
parent 3aaa944986
commit 3b9242e287
2 changed files with 233 additions and 90 deletions

View file

@ -197,25 +197,42 @@ class Axes
} }
/** /**
* plot y versus x as lines * plot y versus x as line
* *
* @param 1darray<Number> x x data * @param 1darray<Number> x x data
* @param 1darray<Number> y y data * @param 1darray<Number> y y data
* @param object linestyle Object defining a style for a line. The * @param String linestyle style of the line (can be "solid",
* structure of the object should be: * "dotted", "dashdot", "dashed" or ""
* { * for no line)
* color: color * @param String linecolor color of the line (can be "#abcdef",
* style: style * "rgb(x,y,z)" or a name of a color.
* } * @param String markerstyle style of the marker used for each
* where color is a string containing * point (can be "circle", "point",
* "rgb(x,y,z)", "#abcdef" or a name of * "small", "cross" or "" for no
* a color, and style is "solid", "dotted", * marker)
* "dashdot" or "dashed". Default value is * @param String markercolor color of the marker (same
* color = "black" and style = "solid" * definition than linecolor)
* @param Number markersize size of the marker
*/ */
plot(x, y, linestyle = {color: "black", style: "solid"}) plot(
x ,
y ,
linestyle = 'solid' ,
linecolor = 'black' ,
markerstyle = 'circle',
markercolor = 'black' ,
markersize = 5 ,
)
{ {
let line = new Line(x, y, linestyle); let line = new Line(
x ,
y ,
linestyle = linestyle ,
linecolor = linecolor ,
markerstyle = markerstyle,
markercolor = markercolor,
markersize = markersize ,
);
this.lines.push(line); this.lines.push(line);
} }
@ -223,9 +240,9 @@ class Axes
* render the axes to the canvas * render the axes to the canvas
* *
* @param ctx CanvasRenderingContext2D Context of the canvas * @param ctx CanvasRenderingContext2D Context of the canvas
* @param window 2darray<Number> Window where to draw the canvas * @param view 2darray<Number> Window where to draw the canvas
*/ */
draw(ctx, window) draw(ctx, view)
{ {
const x_min = get_ext_array( const x_min = get_ext_array(
this.lines.map( this.lines.map(
@ -263,20 +280,20 @@ class Axes
) )
) )
); );
let n_window = this.title.draw( let n_view = this.title.draw(
ctx , ctx ,
window, view,
); );
n_window = this.axis.draw( n_view = this.axis.draw(
ctx , ctx ,
n_window, n_view,
[ [x_min, y_min], [x_max, y_max] ], [ [x_min, y_min], [x_max, y_max] ],
); );
for (const index_line in this.lines) for (const index_line in this.lines)
{ {
this.lines[index_line].draw( this.lines[index_line].draw(
ctx , ctx ,
n_window, n_view,
[ [
[x_min, y_min], [x_min, y_min],
[x_max, y_max], [x_max, y_max],
@ -287,9 +304,9 @@ class Axes
ctx.strokeStyle = 'black'; ctx.strokeStyle = 'black';
ctx.setLineDash([]); ctx.setLineDash([]);
ctx.strokeRect( ctx.strokeRect(
n_window[0][0], n_window[0][1], n_view[0][0], n_view[0][1],
n_window[1][0] - n_window[0][0], n_view[1][0] - n_view[0][0],
n_window[1][1] - n_window[0][1], n_view[1][1] - n_view[0][1],
); );
} }
@ -317,52 +334,62 @@ class Axes
* *
* @property 1darray<float> x xdata * @property 1darray<float> x xdata
* @property 1darray<float> y ydata * @property 1darray<float> y ydata
* @property object linestyle Object defining a style for a line. The * @property String linestyle style of the line (can be "solid",
* structure of the object should be: * "dotted", "dashdot", "dashed" or ""
* { * for no line)
* color: color * @property String linecolor color of the line (can be "#abcdef",
* style: style * "rgb(x,y,z)" or a name of a color.
* } * @property String markerstyle style of the marker used for each
* where color is a string containing * point (can be "circle", "point",
* "rgb(x,y,z)", "#abcdef" or a name of * "small", "cross" or "" for no
* a color, and style is "solid", "dotted", * marker)
* "dashdot" or "dashed". Default value is * @property String markercolor color of the marker (same
* color = "black" and style = "solid" * definition than linecolor)
* @property Number markersize size of the marker
*/ */
class Line class Line
{ {
/** /**
* @param 1darray<float> x xdata * @param 1darray<float> x xdata
* @param 1darray<float> y ydata * @param 1darray<float> y ydata
* @param object linestyle Object defining a style for a line. The * @param string linestyle style of the line (can be "solid",
* structure of the object should be: * "dotted", "dashdot", "dashed" or ""
* { * for no line)
* color: color * @param string linecolor color of the line (can be "#abcdef",
* style: style * "rgb(x,y,z)" or a name of a color.
* } * @param string markerstyle style of the marker used for each
* where color is a string containing * point (can be "circle", "point",
* "rgb(x,y,z)", "#abcdef" or a name of * "small", "cross" or "" for no
* a color, and style is "solid", "dotted", * marker)
* "dashdot" or "dashed". Default value is * @param string markercolor color of the marker (same
* color = "black" and style = "solid" * definition than linecolor)
* @param Number markersize size of the marker
*/ */
constructor( constructor(
x , x ,
y , y ,
linestyle = {color: "black", style: "solid"}, linestyle = 'solid' ,
linecolor = 'black' ,
markerstyle = 'circle' ,
markercolor = 'black' ,
markersize = 5 ,
) )
{ {
this.x = x ; this.x = x ;
this.y = y ; this.y = y ;
this.linestyle = linestyle ; this.linestyle = linestyle ;
this.linecolor = linecolor ;
this.markerstyle = markerstyle;
this.markercolor = markercolor;
this.markersize = markersize ;
} }
/** /**
* draw the line in the box coordinate * draw the line in the box coordinate
* *
* @param CanvasRenderingContext2d ctx Context of the canvas * @param CanvasRenderingContext2d ctx context of the canvas
* @param 2dlist<int> box Box where to draw the line * @param 2dlist<int> box box where to draw the line
* @param 2dlist<float> view Scale of the box (link value <-> * @param 2dlist<float> view scale of the box (link value <->
* coordinate * coordinate
*/ */
draw(ctx, box, view) draw(ctx, box, view)
@ -390,19 +417,52 @@ class Line
); );
} }
); );
if (this.linestyle.style === 'solid') if (this.linestyle != '')
{
this.drawLine(
ctx,
x_coordinates,
y_coordinates,
);
}
if (this.markerstyle != '')
{
this.drawPoints(
ctx ,
x_coordinates,
y_coordinates,
);
}
}
/**
* draw a line in the given context at the given positions
*
* @param CanvasRenderingContext2d ctx context of the canvas
* @param 1darray<Number> x_coordinates X coordinates of the point
* @param 1darray<Number> y_coordinates Y coordinates of the point
*/
drawLine(ctx, x_coordinates, y_coordinates)
{
ctx.beginPath();
ctx.strokeStyle = this.linecolor;
ctx.moveTo(
x_coordinates[0],
y_coordinates[0],
);
if (this.linestyle === 'solid')
{ {
ctx.setLineDash([]); ctx.setLineDash([]);
} }
else if (this.linestyle.style === 'dashed') else if (this.linestyle === 'dashed')
{ {
ctx.setLineDash([15, 5]); ctx.setLineDash([15, 5]);
} }
else if (this.linestyle.style === 'dotted') else if (this.linestyle === 'dotted')
{ {
ctx.setLineDash([2,2]); ctx.setLineDash([2,2]);
} }
else if (this.linestyle.style === 'dashdot') else if (this.linestyle === 'dashdot')
{ {
ctx.setLineDash([15,2,2,2]); ctx.setLineDash([15,2,2,2]);
} }
@ -410,21 +470,102 @@ class Line
{ {
throw _('the style of the line is not correctly defined'); throw _('the style of the line is not correctly defined');
} }
ctx.strokeStyle = this.linestyle.color;
ctx.beginPath();
ctx.moveTo(
x_coordinates[0],
y_coordinates[0]
);
for (const index in x_coordinates) for (const index in x_coordinates)
{ {
ctx.lineTo( ctx.lineTo(
x_coordinates[index], x_coordinates[index],
y_coordinates[index] y_coordinates[index],
); );
} }
ctx.stroke(); ctx.stroke();
} }
/**
* draw points in the given context at the given positions
*
* @param CanvasRenderingContext2d ctx context of the canvas
* @param 1darray<Number> x_coordinates x coordinate of the point
* @param 1darray<Number> y_coordinates y coordinate of the point
*/
drawPoints(ctx, x_coordinates, y_coordinates)
{
for (const index in x_coordinates)
{
let x = x_coordinates[index];
let y = y_coordinates[index];
ctx.beginPath();
if (this.markerstyle == 'circle')
{
ctx.fillStyle = this.markercolor;
ctx.ellipse(
x ,
y ,
this.markersize,
this.markersize,
0 ,
0 ,
2*Math.PI ,
);
ctx.fill();
}
else if (this.markerstyle == 'point')
{
ctx.fillStyle = this.markercolor;
ctx.ellipse(
x ,
y ,
0.5*this.markersize,
0.5*this.markersize,
0 ,
0 ,
2*Math.PI ,
);
ctx.fill();
}
else if (this.markerstyle == 'small')
{
ctx.fillStyle = this.markercolor;
ctx.ellipse(
x ,
y ,
0.1*this.markersize,
0.1*this.markersize,
0 ,
0 ,
2*Math.PI ,
);
ctx.fill();
}
else if (this.markerstyle == 'cross')
{
ctx.setLineDash([]);
ctx.strokeStyle = this.markercolor;
ctx.moveTo(
x - this.markersize,
y - this.markersize,
);
ctx.lineTo(
x + this.markersize,
y + this.markersize,
);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(
x + this.markersize,
y - this.markersize,
);
ctx.lineTo(
x - this.markersize,
y + this.markersize,
);
ctx.stroke();
}
else
{
throw _('the style of the marker is not correctly defined');
}
}
}
} }
/** /**
@ -494,27 +635,29 @@ class Title
* draw the title in the given windows * draw the title in the given windows
* *
* @param ctx CanvasRenderingContext2D Context of the canvas * @param ctx CanvasRenderingContext2D Context of the canvas
* @param window int<array> Window where to write the title on * @param box int<array> Window where to write the title on
* *
* @return plot_windows int<array> New windows for the plot * @return plot_box int<array> New windows for the plot
*/ */
draw(ctx, window) draw(ctx, box)
{ {
ctx.font = this.font.toString(); ctx.font = this.font.toString();
ctx.fillStyle = 'black';
ctx.strokeStyle = 'black';
let width = ctx.measureText(this.content).width; let width = ctx.measureText(this.content).width;
if (width > window[1][0] - window[0][0] + 2 * this.margin) if (width > box[1][0] - box[0][0] + 2 * this.margin)
{ {
ctx.fillText( ctx.fillText(
this.content , this.content ,
window[0][0] , box[0][0] ,
this.font.size + this.margin, this.font.size + this.margin,
window[1][0] - window[0][0], box[1][0] - box[0][0],
); );
} }
else else
{ {
let text_position = window[0][0] + ( let text_position = box[0][0] + (
window[1][0] - window[0][0] - width box[1][0] - box[0][0] - width
) / 2 ) / 2
ctx.fillText( ctx.fillText(
this.content, this.content,
@ -524,10 +667,10 @@ class Title
} }
return [ return [
[ [
window[0][0], box[0][0],
window[0][1] + this.font.size + 2 * this.margin, box[0][1] + this.font.size + 2 * this.margin,
], ],
[window[1][0], window[1][1]], [box[1][0], box[1][1]],
]; ];
} }
} }
@ -574,6 +717,8 @@ class Axis
*/ */
draw(ctx, window, view) draw(ctx, window, view)
{ {
ctx.strokeStyle = 'black';
ctx.fillStyle = 'black';
let index = 0; let index = 0;
let start_pos = window[0][1]; let start_pos = window[0][1];
let padding = ( let padding = (
@ -588,7 +733,6 @@ class Axis
view[1][1] - index * step view[1][1] - index * step
).toString().slice(0,3); ).toString().slice(0,3);
let text_position = current_y + this.text_height / 2 let text_position = current_y + this.text_height / 2
ctx.strokeStyle = 'black';
ctx.beginPath(); ctx.beginPath();
ctx.moveTo( ctx.moveTo(
window[0][0] + this.margin + width, window[0][0] + this.margin + width,

23
test.js
View file

@ -3,12 +3,11 @@ let manager = new Manager(
); );
manager.add_canvas(1000, 500); manager.add_canvas(1000, 500);
manager.add_canvas(1000, 500).figure.add_axes().plot( manager.add_canvas(1000, 500).figure.add_axes().plot(
[0,1,2,3,4,5] , [0,1,2,3,4,5] ,
[0,1,4,9,16,25], [0,1,4,9,16,25] ,
{ linestyle = 'dashed' ,
color: 'rgb(255,0,0)', linecolor = 'rgb(255,0,0)',
style: 'dashed' markerstyle = 'cross' ,
}
); );
manager.list_canvas[0].figure.list_axes[0].title = 'squared and x2'; manager.list_canvas[0].figure.list_axes[0].title = 'squared and x2';
manager.list_canvas[0].figure.list_axes[0].plot( manager.list_canvas[0].figure.list_axes[0].plot(
@ -16,12 +15,12 @@ manager.list_canvas[0].figure.list_axes[0].plot(
[0,2,4,6,8,10] [0,2,4,6,8,10]
); );
manager.list_canvas[0].figure.add_axes().plot( manager.list_canvas[0].figure.add_axes().plot(
[2,4,6,8,10], [2,4,6,8,10] ,
[1/2,1/4,1/6,1/8,1/10], [1/2,1/4,1/6,1/8,1/10] ,
{ linestyle = 'dashdot' ,
color: 'rgb(0,255,0)', linecolor = 'rgb(0,255,0)',
style: 'dashdot' markerstyle = 'circle' ,
} markercolor = 'rgb(0,0,255)',
); );
manager.list_canvas[0].figure.list_axes[0].title = '1/x'; manager.list_canvas[0].figure.list_axes[0].title = '1/x';
manager.draw(); manager.draw();