in progress: implementing some rules of tonal harmony as graph

This commit is contained in:
Mikayla Dobson
2022-12-19 18:49:57 -06:00
parent b377cefa78
commit 5c0128c3ff
6 changed files with 101 additions and 27 deletions

74
src/chordChart.ts Normal file
View File

@@ -0,0 +1,74 @@
import Edge from "./lib/Graph/Edge";
import GraphNode from "./lib/Graph/GraphNode";
import Graph from "./lib/Graph/index";
import { ChordQuality, EventData } from "./lib/helpers/index";
// factory to create data to populate graph
function createChord(root: string, quality: ChordQuality): EventData {
return {
root: root,
quality: quality
}
}
// primary usable triads in C major
const cmaj = createChord("C", ChordQuality.Major);
const dmin = createChord("D", ChordQuality.Minor);
const emin = createChord("E", ChordQuality.Minor);
const fmaj = createChord("F", ChordQuality.Major);
const gmaj = createChord("G", ChordQuality.Major);
const amin = createChord("A", ChordQuality.Minor);
// borrowed triads
const dmaj = createChord("D", ChordQuality.Major);
const emaj = createChord("E", ChordQuality.Major);
const ebmaj = createChord("Eb", ChordQuality.Major);
const fmin = createChord("F", ChordQuality.Minor);
const gmin = createChord("G", ChordQuality.Minor);
const abmaj = createChord("Ab", ChordQuality.Major);
const bbmaj = createChord("Bb", ChordQuality.Major);
const bmaj = createChord("B", ChordQuality.Major);
// graph to host music theory logic
class ChordNode<EventData> extends GraphNode<EventData> {
constructor(data: EventData, id = -1, edges?: Edge<EventData>[]) {
super(data, id, edges);
}
override print() {
if (this.edges.length) {
for (let edge of this.edges) {
console.log(this);
console.log(`${this.data.root, ChordQuality[this.data.quality]} --> ${edge.end.data.root, ChordQuality[edge.end.data.quality]}`);
}
}
console.log(this.data.root, ChordQuality[this.data.quality]);
}
}
const chordChart = new Graph<EventData>(true, true);
chordChart.addPoints(
new ChordNode<EventData>(cmaj),
new ChordNode<EventData>(dmin),
new ChordNode<EventData>(emin),
new ChordNode<EventData>(fmaj),
new ChordNode<EventData>(gmaj),
new ChordNode<EventData>(amin),
new ChordNode<EventData>(dmaj),
new ChordNode<EventData>(emaj),
new ChordNode<EventData>(ebmaj),
new ChordNode<EventData>(fmin),
new ChordNode<EventData>(gmin),
new ChordNode<EventData>(abmaj),
new ChordNode<EventData>(bbmaj),
new ChordNode<EventData>(bmaj)
);
const cmajnode = chordChart.getPointByData(cmaj) as ChordNode<EventData>;
const dminnode = chordChart.getPointByData(dmin) as ChordNode<EventData>;
chordChart.addEdge(cmajnode, dminnode);
export default chordChart;

View File

@@ -2,12 +2,16 @@ import Node from "../helpers/Node";
import Edge from "./Edge"; import Edge from "./Edge";
export default class GraphNode<T> extends Node<T> { export default class GraphNode<T> extends Node<T> {
edges: Edge<T>[] protected edges: Edge<T>[]
id: number protected id: number
constructor(data: T, id: number, edges?: Edge<T>[]) { constructor(data: T, id?: number, edges?: Edge<T>[]) {
super(data); super(data);
this.edges = edges || new Array<Edge<T>>(); this.edges = edges || new Array<Edge<T>>();
this.id = id || -1;
}
setID(id: number) {
this.id = id; this.id = id;
} }

View File

@@ -1,10 +1,10 @@
import GraphNode from "./GraphNode"; import GraphNode from "./GraphNode";
export default class Graph<T> { export default class Graph<T> {
private isWeighted: boolean; protected isWeighted: boolean;
private isDirected: boolean; protected isDirected: boolean;
private points: GraphNode<T>[]; protected points: GraphNode<T>[];
private count = 0; protected count = 0;
constructor(isWeighted: boolean, isDirected: boolean, points?: GraphNode<T>[]) { constructor(isWeighted: boolean, isDirected: boolean, points?: GraphNode<T>[]) {
this.isWeighted = isWeighted; this.isWeighted = isWeighted;
@@ -12,14 +12,21 @@ export default class Graph<T> {
this.points = points || new Array<GraphNode<T>>(); this.points = points || new Array<GraphNode<T>>();
} }
createPoint(data: T) { createPoint(data: T | GraphNode<T>) {
const newPoint = new GraphNode<T>(data, this.count); let newPoint: GraphNode<T>;
if (data instanceof GraphNode<T>) {
data.setID(this.count);
newPoint = data;
} else {
newPoint = new GraphNode<T>(data, this.count);
}
this.points.push(newPoint); this.points.push(newPoint);
this.count++; this.count++;
return newPoint; return newPoint;
} }
addPoints(...points: T[]) { addPoints(...points: T[] | GraphNode<T>[]) {
for (let point of points) { for (let point of points) {
this.createPoint(point); this.createPoint(point);
} }

View File

@@ -7,7 +7,7 @@
**/ **/
export default class Node<T> { export default class Node<T> {
data?: T public data: T
constructor(data: any) { constructor(data: any) {
this.data = data; this.data = data;

View File

@@ -1,8 +1,8 @@
export interface EventData { export interface EventData {
root: string root: string | number
quality: ChordQuality quality: ChordQuality
duration: number duration?: number
beatStrength: 'Weak' | 'Moderate' | 'Strong' beatStrength?: 'Weak' | 'Moderate' | 'Strong'
} }
export enum ChordQuality { export enum ChordQuality {

View File

@@ -1,14 +1,3 @@
import data from "./lib/helpers/sample"; import chordChart from "./chordChart";
const { eventlist, eventgraph } = data;
// eventlist.print(); chordChart.print();
eventgraph.print();
// export default content;
// const parser = new DOMParser();
// const document = parser.parseFromString(content, 'text/html');
// // const target = document.getElementById("where-thing-go") as HTMLElement;
// // target.appendChild(document);