Skip to content

Commit

Permalink
Curves improve (#257)
Browse files Browse the repository at this point in the history
* add curves

* fix draw_sound_2d

* 🚨 fix: linter errors

* 🐛 fix Sound import

* fix merge issues

* Revert "fix merge issues"

This reverts commit 7b163bb.

* commit plotly changes
  • Loading branch information
srj31 authored Nov 16, 2023
1 parent 05f5791 commit 419f242
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 103 deletions.
14 changes: 9 additions & 5 deletions src/bundles/plotly/curve_functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export function z_of(pt: Point): number {
* ```
*/
export function r_of(pt: Point): number {
return pt.color.r * 255;
return pt.color[0] ?? 0 * 255;
}

/**
Expand All @@ -62,7 +62,7 @@ export function r_of(pt: Point): number {
* ```
*/
export function g_of(pt: Point): number {
return pt.color.g * 255;
return pt.color[1] ?? 0 * 255;
}

/**
Expand All @@ -77,7 +77,7 @@ export function g_of(pt: Point): number {
* ```
*/
export function b_of(pt: Point): number {
return pt.color.b * 255;
return pt.color[2] ?? 0 * 255;
}
export function generatePlot(
type: string,
Expand All @@ -98,6 +98,7 @@ export function generatePlot(
z_s.push(z_of(point));
color_s.push(`rgb(${r_of(point)},${g_of(point)},${b_of(point)})`);
}

const plotlyData: Data = {
x: x_s,
y: y_s,
Expand All @@ -106,6 +107,9 @@ export function generatePlot(
size: 2,
color: color_s,
},
line: {
color: color_s,
},
};
return new CurvePlot(
draw_new_curve,
Expand All @@ -119,5 +123,5 @@ export function generatePlot(
}

function draw_new_curve(divId: string, data: Data, layout: Partial<Layout>) {
Plotly.newPlot(divId, [data], layout);
}
Plotly.react(divId, [data], layout);
}

Check warning on line 127 in src/bundles/plotly/curve_functions.ts

View workflow job for this annotation

GitHub Actions / deploy

Newline required at end of file but not found
148 changes: 137 additions & 11 deletions src/bundles/plotly/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@ import context from 'js-slang/context';
import Plotly, { type Data, type Layout } from 'plotly.js-dist';
import {
type Curve,
type CurvePlot,
CurvePlot,
type CurvePlotFunction,
DrawnPlot,
type ListOfPairs,
} from './plotly';
import { generatePlot } from './curve_functions';
import { get_duration, get_wave, is_sound } from './sound_functions';
import { type Sound } from '../sound/types';

let drawnPlots: (DrawnPlot | CurvePlot)[] = [];

const drawnPlots: (DrawnPlot | CurvePlot)[] = [];
context.moduleContexts.plotly.state = {
drawnPlots,
};
Expand Down Expand Up @@ -121,7 +124,6 @@ export function new_plot(data: ListOfPairs): void {
drawnPlots.push(new DrawnPlot(draw_new_plot, data));
}


/**
* Adds a new plotly plot to the context which will be rendered in the Plotly Tabs
* @example
Expand Down Expand Up @@ -236,7 +238,6 @@ export function new_plot_json(data: any): void {
drawnPlots.push(new DrawnPlot(draw_new_plot_json, data));
}


/**
* @param data The data which plotly will use
* @param divId The id of the div element on which the plot will be displayed
Expand Down Expand Up @@ -309,34 +310,159 @@ function createPlotFunction(
/**
* Returns a function that turns a given Curve into a Drawing, by sampling the
* Curve at `num` sample points and connecting each pair with a line.
* The parts between (0,0) and (1,1) of the resulting Drawing are shown in the window.
*
* @param num determines the number of points, lower than 65535, to be sampled.
* Including 0 and 1, there are `num + 1` evenly spaced sample points
* @return function of type Curve → Drawing
* @example
* ```
* draw_connected(100)(t => make_point(t, t));
* draw_connected_2d(100)(t => make_point(t, t));
* ```
*/
export const draw_connected_2d = createPlotFunction(
'scatter',
{ mode: 'lines' },
'scattergl',
{
mode: 'lines',
},
{
xaxis: { visible: false },
yaxis: {
visible: false,
scaleanchor: 'x',
},
},

true,
);

export const draw_3D_points = createPlotFunction(
/**
* Returns a function that turns a given 3D Curve into a Drawing, by sampling the
* 3D Curve at `num` sample points and connecting each pair with a line.
*
* @param num determines the number of points, lower than 65535, to be sampled.
* Including 0 and 1, there are `num + 1` evenly spaced sample points
* @return function of type 3D Curve → Drawing
* @example
* ```
* draw_connected_3d(100)(t => make_point(t, t));
* ```
*/
export const draw_connected_3d = createPlotFunction(
'scatter3d',
{ mode: 'lines' },
{},
true,
);

/**
* Returns a function that turns a given Curve into a Drawing, by sampling the
* Curve at num sample points. The Drawing consists of isolated points, and does not connect them.
* When a program evaluates to a Drawing, the Source system displays it graphically, in a window,
*
* * @param num determines the number of points, lower than 65535, to be sampled.
* Including 0 and 1, there are `num + 1` evenly spaced sample points
* @return function of type 2D Curve → Drawing
* @example
* ```
* draw_points_2d(100)(t => make_point(t, t));
*/
export const draw_points_2d = createPlotFunction(
'scatter',
{ mode: 'markers' },
{

xaxis: { visible: false },
yaxis: {
visible: false,
scaleanchor: 'x',
},
},
true,
);

/**
* Returns a function that turns a given 3D Curve into a Drawing, by sampling the
* 3D Curve at num sample points. The Drawing consists of isolated points, and does not connect them.
* When a program evaluates to a Drawing, the Source system displays it graphically, in a window,
*
* * @param num determines the number of points, lower than 65535, to be sampled.
* Including 0 and 1, there are `num + 1` evenly spaced sample points
* @return function of type 3D Curve → Drawing
* @example
* ```
* draw_points_3d(100)(t => make_point(t, t));
*/
export const draw_points_3d = createPlotFunction(
'scatter3d',
{ mode: 'markers' },
{},
);

/**
* Visualizes the sound on a 2d line graph
* @param sound the sound which is to be visualized on plotly
*/
export const draw_sound_2d = (sound: Sound) => {
const FS: number = 44100; // Output sample rate
if (!is_sound(sound)) {
throw new Error(
`draw_sound_2d is expecting sound, but encountered ${sound}`,
);
// If a sound is already displayed, terminate execution.
} else if (get_duration(sound) < 0) {
throw new Error('draw_sound_2d: duration of sound is negative');
} else {
// Instantiate audio context if it has not been instantiated.

// Create mono buffer
const channel: number[] = [];
const time_stamps: number[] = [];
const len = Math.ceil(FS * get_duration(sound));

const wave = get_wave(sound);
for (let i = 0; i < len; i += 1) {
time_stamps[i] = i / FS;
channel[i] = wave(i / FS);
}

let x_s: number[] = [];
let y_s: number[] = [];

for (let i = 0; i < channel.length; i += 1) {
x_s.push(time_stamps[i]);
y_s.push(channel[i]);
}

const plotlyData: Data = {
x: x_s,
y: y_s,
};
const plot = new CurvePlot(
draw_new_curve,
{
...plotlyData,
type: 'scattergl',
mode: 'lines',
line: { width: 0.5 },
} as Data,
{
xaxis: {
type: 'linear',
title: 'Time',
anchor: 'y',
position: 0,
rangeslider: { visible: true },
},
yaxis: {
type: 'linear',
visible: false,
},
bargap: 0.2,
barmode: 'stack',
},
);
if (drawnPlots) drawnPlots.push(plot);
}
};

function draw_new_curve(divId: string, data: Data, layout: Partial<Layout>) {
Plotly.react(divId, [data], layout);
}
9 changes: 5 additions & 4 deletions src/bundles/plotly/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ export {
new_plot,
new_plot_json,
draw_connected_2d,
draw_3D_points,
} from './functions';

export { draw_sound_2d } from './sound_functions';
draw_connected_3d,
draw_points_2d,
draw_points_3d,
draw_sound_2d,
} from './functions';

Check warning on line 14 in src/bundles/plotly/index.ts

View workflow job for this annotation

GitHub Actions / deploy

Newline required at end of file but not found
11 changes: 7 additions & 4 deletions src/bundles/plotly/plotly.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { type Data, type Layout } from 'plotly.js-dist';
import { type ReplResult } from '../../typings/type_helpers';
import type { Pair } from 'js-slang/dist/stdlib/list';

/**
* Represents plots with a draw method attached
Expand Down Expand Up @@ -37,15 +38,14 @@ export class CurvePlot implements ReplResult {

export type ListOfPairs = (ListOfPairs | any)[] | null;
export type Data2d = number[];
export type Color = { r: number, g: number, b: number };
export type Color = { r: number; g: number; b: number };

export type DataTransformer = (c: Data2d[]) => Data2d[];
export type CurvePlotFunction = ((func: Curve) => CurvePlot);
export type CurvePlotFunction = (func: Curve) => CurvePlot;

export type Curve = ((n: number) => Point);
export type Curve = (n: number) => Point;
export type CurveTransformer = (c: Curve) => Curve;


/** Encapsulates 3D point with RGB values. */
export class Point implements ReplResult {
constructor(
Expand All @@ -57,3 +57,6 @@ export class Point implements ReplResult {

public toReplString = () => `(${this.x}, ${this.y}, ${this.z}, Color: ${this.color})`;
}

export type Wave = (...t: any) => number;
export type Sound = Pair<Wave, number>;

Check warning on line 62 in src/bundles/plotly/plotly.ts

View workflow job for this annotation

GitHub Actions / deploy

Newline required at end of file but not found
Loading

0 comments on commit 419f242

Please sign in to comment.