Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

chart2music

Package Overview
Dependencies
Maintainers
1
Versions
50
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

chart2music - npm Package Compare versions

Comparing version 0.2.0 to 0.3.0

dist/types/dataPoint.d.ts

49

dist/index.d.ts

@@ -6,4 +6,21 @@ interface AudioEngine {

interface DataPoint {
x: number;
}
interface SimpleDataPoint extends DataPoint {
y: number;
}
interface AlternateAxisDataPoint extends DataPoint {
y2: number;
}
interface HighLowDataPoint extends DataPoint {
high: number;
low: number;
}
declare type SupportedDataPointType = SimpleDataPoint | AlternateAxisDataPoint | HighLowDataPoint;
declare type SupportedInputType = SupportedDataPointType | number;
declare type SonifyTypes = {
data: dataSet | dataPoint[] | number[];
type: SUPPORTED_CHART_TYPES | SUPPORTED_CHART_TYPES[];
data: dataSet | SupportedInputType[];
element: HTMLElement;

@@ -17,3 +34,2 @@ axes?: {

cc?: HTMLElement;
type?: SUPPORTED_CHART_TYPES;
audioEngine?: AudioEngine;

@@ -23,9 +39,4 @@ options?: c2mOptions;

declare type dataSet = {
[groupName: string]: dataPoint[];
[groupName: string]: SupportedInputType[];
};
declare type dataPoint = {
x: number;
y?: number | StatBundle;
y2?: number;
};
declare type AxisData = {

@@ -38,8 +49,6 @@ minimum?: number;

declare enum SUPPORTED_CHART_TYPES {
LINE = "line"
LINE = "line",
BAR = "bar",
BAND = "band"
}
declare type StatBundle = {
high?: number;
low?: number;
};
declare type c2mCallbackType = {

@@ -54,4 +63,9 @@ slice: string;

};
declare type c2mGolangReturn = {
err: null | string;
data?: c2m;
};
declare class c2mChart {
declare const c2mChart: (input: SonifyTypes) => c2mGolangReturn;
declare class c2m {
private _chartElement;

@@ -82,3 +96,3 @@ private _ccElement;

group: string;
point: dataPoint;
point: SupportedDataPointType;
stat: string;

@@ -88,4 +102,2 @@ };

private _initializeData;
private _calculateMetadataByGroup;
private _initializeAxis;
private _startListening;

@@ -104,5 +116,6 @@ private _playAndSpeak;

private _playCurrent;
private _onFocus;
private _speakCurrent;
}
export { c2mChart };
export { c2m, c2mChart };

@@ -87,3 +87,2 @@ var c2mChart = (function (exports) {

const NOTE_LENGTH = 0.25;
const statReadOrder = ["high", "low"];

@@ -235,2 +234,15 @@ const keyboardEventToString = (e) => {

function isDataPoint(obj) {
return typeof obj === "object" && "x" in obj;
}
function isSimpleDataPoint(obj) {
return isDataPoint(obj) && "y" in obj;
}
function isAlternateAxisDataPoint(obj) {
return isDataPoint(obj) && "y2" in obj;
}
function isHighLowDataPoint(obj) {
return isDataPoint(obj) && "high" in obj && "low" in obj;
}
const interpolateBin = (point, min, max, bins) => {

@@ -242,5 +254,11 @@ const pct = (point - min) / (max - min);

const generateSummary = ({ type, title, dataRows, x, y, y2 }) => {
const text = [`Sonified ${type} chart "${title}"`];
const text = [];
if (Array.isArray(type)) {
text.push(`Sonified ${type.sort().join("-")} chart "${title}"`);
}
else {
text.push(`Sonified ${type} chart "${title}"`);
}
if (dataRows > 1) {
text.push(`contains ${dataRows} ${type}s`);
text.push(`contains ${dataRows} categories`);
}

@@ -257,9 +275,27 @@ text.push(`x is "${x.label}" from ${x.format(x.minimum)} to ${x.format(x.maximum)}`);

.flat()
.filter((point) => prop in point)
.map((point) => {
if (typeof point[prop] === "number") {
return point[prop];
if (isSimpleDataPoint(point)) {
if (prop === "x" || prop === "y") {
return point[prop];
}
}
return Math.min(...Object.values(point[prop]));
});
else if (isAlternateAxisDataPoint(point)) {
if (prop === "x" || prop === "y2") {
return point[prop];
}
}
else if (isHighLowDataPoint(point)) {
if (prop === "x") {
return point.x;
}
if (prop === "y") {
return Math.min(point.high, point.low);
}
}
return NaN;
})
.filter((num) => !isNaN(num));
if (values.length === 0) {
return NaN;
}
return Math.min(...values);

@@ -270,9 +306,27 @@ };

.flat()
.filter((point) => prop in point)
.map((point) => {
if (typeof point[prop] === "number") {
return point[prop];
if (isSimpleDataPoint(point)) {
if (prop === "x" || prop === "y") {
return point[prop];
}
}
return Math.max(...Object.values(point[prop]));
});
else if (isAlternateAxisDataPoint(point)) {
if (prop === "x" || prop === "y2") {
return point[prop];
}
}
else if (isHighLowDataPoint(point)) {
if (prop === "x") {
return point.x;
}
if (prop === "y") {
return Math.max(point.high, point.low);
}
}
return NaN;
})
.filter((num) => !isNaN(num));
if (values.length === 0) {
return NaN;
}
return Math.max(...values);

@@ -283,16 +337,14 @@ };

const generatePointDescription = (point, xAxis, yAxis, stat) => {
if (typeof stat !== "undefined" && typeof point.y !== "number") {
return `${xAxis.format(point.x)}, ${yAxis.format(point.y[stat])}`;
if (isHighLowDataPoint(point)) {
if (typeof stat !== "undefined") {
return `${xAxis.format(point.x)}, ${yAxis.format(point[stat])}`;
}
return `${xAxis.format(point.x)}, ${yAxis.format(point.high)} - ${yAxis.format(point.low)}`;
}
if (typeof point.y === "number") {
if (isSimpleDataPoint(point)) {
return `${xAxis.format(point.x)}, ${yAxis.format(point.y)}`;
}
else if (typeof point.y2 === "number") {
if (isAlternateAxisDataPoint(point)) {
return `${xAxis.format(point.x)}, ${yAxis.format(point.y2)}`;
}
else {
if ("high" in point.y && "low" in point.y) {
return `${xAxis.format(point.x)}, ${yAxis.format(point.y.high)} - ${yAxis.format(point.y.low)}`;
}
}
return "";

@@ -306,8 +358,155 @@ };

};
const uniqueArray = (arr) => {
return [...new Set(arr)];
const calculateMetadataByGroup = (data) => {
return data.map((row) => {
let yValues = [];
let availableStats = [];
if (isSimpleDataPoint(row[0])) {
yValues = row.map(({ y }) => y);
}
else if (isAlternateAxisDataPoint(row[0])) {
yValues = row.map(({ y2 }) => y2);
}
else if (isHighLowDataPoint(row[0])) {
availableStats = ["high", "low"];
}
const min = Math.min(...yValues);
const max = Math.max(...yValues);
const tenths = Math.round(row.length / 10);
return {
minimumPointIndex: yValues.indexOf(min),
maximumPointIndex: yValues.indexOf(max),
tenths,
availableStats,
statIndex: -1
};
});
};
const initializeAxis = (data, axisName, userAxis) => {
return {
minimum: userAxis?.minimum ?? calculateAxisMinimum(data, axisName),
maximum: userAxis?.maximum ?? calculateAxisMaximum(data, axisName),
label: userAxis?.label ?? "",
format: userAxis?.format ?? defaultFormat
};
};
var SUPPORTED_CHART_TYPES;
(function (SUPPORTED_CHART_TYPES) {
SUPPORTED_CHART_TYPES["LINE"] = "line";
SUPPORTED_CHART_TYPES["BAR"] = "bar";
SUPPORTED_CHART_TYPES["BAND"] = "band";
})(SUPPORTED_CHART_TYPES || (SUPPORTED_CHART_TYPES = {}));
const validateInput = (input) => {
const errors = [];
errors.push(validateInputType(input.type));
errors.push(validateInputElement(input.element));
errors.push(validateInputAxes(input.axes));
errors.push(validateInputDataHomogeneity(input.data));
return errors.filter((str) => str !== "").join("\n");
};
const validateInputType = (type) => {
if (typeof type === "undefined") {
return `Required parameter 'type' was left undefined. Supported types are: ${Object.values(SUPPORTED_CHART_TYPES).join(", ")}`;
}
if (Array.isArray(type)) {
const unsupported_types = type.filter((str) => !Object.values(SUPPORTED_CHART_TYPES).includes(str));
if (unsupported_types.length === 0) {
return "";
}
return `Invalid input types: ${unsupported_types.join(", ")}. Valid types are: ${Object.values(SUPPORTED_CHART_TYPES).join(", ")}`;
}
if (Object.values(SUPPORTED_CHART_TYPES).includes(type)) {
return "";
}
return `Invalid input type: ${type}. Valid types are: ${Object.values(SUPPORTED_CHART_TYPES).join(", ")}`;
};
const validateInputElement = (element) => {
if (typeof element === "undefined") {
return "Required parameter 'element' was left undefined. An HTMLElement must be provided for this parameter.";
}
if (element instanceof HTMLElement) {
return "";
}
return "Provided value for 'element' must be an instance of HTMLElement.";
};
const validateInputAxes = (axes) => {
if (typeof axes === "undefined") {
return "";
}
const supportedAxis = ["x", "y", "y2"];
const unsupportedAxes = Object.keys(axes).filter((axis) => !supportedAxis.includes(axis));
if (unsupportedAxes.length > 0) {
return `Unsupported axes were included: ${unsupportedAxes.join(", ")}. The only supported axes are: ${supportedAxis.join(", ")}.`;
}
return "";
};
const validateInputDataHomogeneity = (data) => {
if (Array.isArray(data)) {
return validateInputDataRowHomogeneity(data);
}
for (const key in data) {
const result = validateInputDataRowHomogeneity(data[key]);
if (result !== "") {
return `Error for data category ${key}: ${result}`;
}
}
return "";
};
const validateInputDataRowHomogeneity = (row) => {
const first = row[0];
if (typeof first === "number") {
const failure = row.findIndex((cell) => !(typeof cell === "number"));
if (failure === -1) {
return "";
}
return `The first item is a number, but item index ${failure} is not (value: ${JSON.stringify(row[failure])}). All items should be of the same type.`;
}
if (isSimpleDataPoint(first)) {
const failure = row.findIndex((cell) => !isSimpleDataPoint(cell));
if (failure === -1) {
return "";
}
return `The first item is a simple data point (x/y), but item index ${failure} is not (value: ${JSON.stringify(row[failure])}). All items should be of the same type.`;
}
if (isAlternateAxisDataPoint(first)) {
const failure = row.findIndex((cell) => !isAlternateAxisDataPoint(cell));
if (failure === -1) {
return "";
}
return `The first item is an alternate axis data point (x/y2), but item index ${failure} is not (value: ${JSON.stringify(row[failure])}). All items should be of the same type.`;
}
if (isHighLowDataPoint(first)) {
const failure = row.findIndex((cell) => !isHighLowDataPoint(cell));
if (failure === -1) {
return "";
}
return `The first item is a high low data point (x/high/low), but item index ${failure} is not (value: ${JSON.stringify(row[failure])}). All items should be of the same type.`;
}
return `The first item is of an unrecognized type (value: ${JSON.stringify(first)}). Supported types are: number, simple data point (x/y), alternative axis data point (x/y2), and high low data point (x/high/low).`;
};
let context = null;
class c2mChart {
const convertDataRow = (row) => {
return row.map((point, index) => {
if (typeof point === "number") {
return {
x: index,
y: point
};
}
return point;
});
};
const c2mChart = (input) => {
const validationErrorString = validateInput(input);
if (validationErrorString !== "") {
return { err: validationErrorString };
}
return {
err: null,
data: new c2m(input)
};
};
class c2m {
constructor(input) {

@@ -334,7 +533,7 @@ this._groupIndex = 0;

this._initializeData(input.data);
this._calculateMetadataByGroup();
this._xAxis = this._initializeAxis("x", input.axes?.x);
this._yAxis = this._initializeAxis("y", input.axes?.y);
this._metadataByGroup = calculateMetadataByGroup(this._data);
this._xAxis = initializeAxis(this._data, "x", input.axes?.x);
this._yAxis = initializeAxis(this._data, "y", input.axes?.y);
if (usesAxis(this._data, "y2")) {
this._y2Axis = this._initializeAxis("y2", input.axes?.y2);
this._y2Axis = initializeAxis(this._data, "y2", input.axes?.y2);
}

@@ -443,3 +642,3 @@ if (input?.options) {

{
title: "Go to previous group",
title: "Go to previous category",
key: "PageUp",

@@ -457,3 +656,3 @@ callback: () => {

{
title: "Go to next group",
title: "Go to next category",
key: "PageDown",

@@ -489,2 +688,18 @@ callback: () => {

{
title: "Play all categories left",
key: "Shift+Home",
callback: () => {
clearInterval(this._playListInterval);
this._playAlLCategoriesLeft();
}
},
{
title: "Play all categories right",
key: "Shift+End",
callback: () => {
clearInterval(this._playListInterval);
this._playAlLCategoriesRight();
}
},
{
title: "Replay",

@@ -572,46 +787,8 @@ key: " ",

this._groups = Object.keys(userData);
this._data = Object.values(userData);
this._data = Object.values(userData).map((row) => convertDataRow(row));
return;
}
const massagedData = userData.map((point, index) => {
if (typeof point === "number") {
return {
x: index,
y: point
};
}
return point;
});
this._groups = [""];
this._data = [massagedData];
this._data = [convertDataRow(userData)];
}
_calculateMetadataByGroup() {
this._metadataByGroup = this._data.map((row) => {
const yPoints = row.map(({ y, y2 }) => y ?? y2);
const yValues = yPoints.filter((value) => typeof value === "number");
const min = Math.min(...yValues);
const max = Math.max(...yValues);
const tenths = Math.round(row.length / 10);
const stats = uniqueArray(yPoints
.filter((value) => typeof value !== "number")
.map((value) => Object.keys(value))
.flat());
const availableStats = statReadOrder.filter((stat) => stats.indexOf(stat) >= 0);
return {
minimumPointIndex: yValues.indexOf(min),
maximumPointIndex: yValues.indexOf(max),
tenths,
availableStats,
statIndex: -1
};
});
}
_initializeAxis(axisName, userAxis) {
return {
minimum: userAxis?.minimum ?? calculateAxisMinimum(this._data, axisName),
maximum: userAxis?.maximum ?? calculateAxisMaximum(this._data, axisName),
label: userAxis?.label ?? "",
format: userAxis?.format ?? defaultFormat
};
}
_startListening() {

@@ -723,4 +900,45 @@ this._chartElement.addEventListener("focus", () => {

}
_playAlLCategoriesRight() {
const maxPoints = this._data[this._groupIndex].length - 1;
const maxGroups = this._data.length - 1;
this._playListInterval = setInterval(() => {
if (this._pointIndex >= maxPoints && this._groupIndex >= maxGroups) {
this._pointIndex = maxPoints;
clearInterval(this._playListInterval);
}
else if (this._groupIndex === maxGroups) {
this._groupIndex = 0;
this._pointIndex++;
this._playCurrent();
}
else {
this._groupIndex++;
this._playCurrent();
}
}, SPEEDS[this._speedRateIndex]);
this._playCurrent();
}
_playAlLCategoriesLeft() {
const min = 0;
const maxGroups = this._data.length - 1;
this._playListInterval = setInterval(() => {
if (this._pointIndex <= min && this._groupIndex <= min) {
this._pointIndex = min;
clearInterval(this._playListInterval);
}
else if (this._groupIndex === min) {
this._groupIndex = maxGroups;
this._pointIndex--;
this._playCurrent();
}
else {
this._groupIndex--;
this._playCurrent();
}
}, SPEEDS[this._speedRateIndex]);
this._playCurrent();
}
_playCurrent() {
if (!this._options.enableSound) {
this._onFocus();
return;

@@ -739,41 +957,33 @@ }

(this._xAxis.maximum - this._xAxis.minimum));
if (typeof current.y === "number") {
if (isSimpleDataPoint(current)) {
const yBin = interpolateBin(current.y, this._yAxis.minimum, this._yAxis.maximum, HERTZ.length - 1);
this._audioEngine.playDataPoint(HERTZ[yBin], xPan, NOTE_LENGTH);
console.log("on focus callback", this._options);
this._options?.onFocusCallback?.({
slice: this._groups[this._groupIndex],
index: this._pointIndex
});
this._onFocus();
return;
}
if (typeof current.y2 === "number") {
if (isAlternateAxisDataPoint(current)) {
const yBin = interpolateBin(current.y2, this._y2Axis.minimum, this._y2Axis.maximum, HERTZ.length - 1);
this._audioEngine.playDataPoint(HERTZ[yBin], xPan, NOTE_LENGTH);
console.log("on focus callback", this._options);
this._options?.onFocusCallback?.({
slice: this._groups[this._groupIndex],
index: this._pointIndex
});
this._onFocus();
return;
}
if (statIndex >= 0) {
const stat = availableStats[statIndex];
const yBin = interpolateBin(current.y[stat], this._yAxis.minimum, this._yAxis.maximum, HERTZ.length - 1);
this._audioEngine.playDataPoint(HERTZ[yBin], xPan, NOTE_LENGTH);
console.log("on focus callback", this._options);
this._options?.onFocusCallback?.({
slice: this._groups[this._groupIndex],
index: this._pointIndex
if (isHighLowDataPoint(current)) {
if (statIndex >= 0) {
const stat = availableStats[statIndex];
const yBin = interpolateBin(current[stat], this._yAxis.minimum, this._yAxis.maximum, HERTZ.length - 1);
this._audioEngine.playDataPoint(HERTZ[yBin], xPan, NOTE_LENGTH);
this._onFocus();
return;
}
const interval = 1 / (availableStats.length + 1);
availableStats.forEach((stat, index) => {
const yBin = interpolateBin(current[stat], this._yAxis.minimum, this._yAxis.maximum, HERTZ.length - 1);
setTimeout(() => {
this._audioEngine.playDataPoint(HERTZ[yBin], xPan, NOTE_LENGTH);
}, SPEEDS[this._speedRateIndex] * interval * index);
});
return;
this._onFocus();
}
const interval = 1 / (availableStats.length + 1);
availableStats.forEach((stat, index) => {
const yBin = interpolateBin(current.y[stat], this._yAxis.minimum, this._yAxis.maximum, HERTZ.length - 1);
setTimeout(() => {
this._audioEngine.playDataPoint(HERTZ[yBin], xPan, NOTE_LENGTH);
}, SPEEDS[this._speedRateIndex] * interval * index);
});
console.log("on focus callback", this._options);
}
_onFocus() {
this._options?.onFocusCallback?.({

@@ -796,3 +1006,3 @@ slice: this._groups[this._groupIndex],

const current = this._data[this._groupIndex][this._pointIndex];
const point = generatePointDescription(current, this._xAxis, "y" in current ? this._yAxis : this._y2Axis, availableStats[statIndex]);
const point = generatePointDescription(current, this._xAxis, isAlternateAxisDataPoint(current) ? this._y2Axis : this._yAxis, availableStats[statIndex]);
const text = (this._flagNewGroup ? `${this._groups[this._groupIndex]}, ` : "") +

@@ -809,2 +1019,3 @@ (this._flagNewStat

exports.c2m = c2m;
exports.c2mChart = c2mChart;

@@ -811,0 +1022,0 @@

@@ -1,3 +0,5 @@

import type { dataPoint, SonifyTypes, c2mOptions } from "./types";
export declare class c2mChart {
import type { SonifyTypes, c2mOptions, c2mGolangReturn } from "./types";
import type { SupportedDataPointType } from "./dataPoint";
export declare const c2mChart: (input: SonifyTypes) => c2mGolangReturn;
export declare class c2m {
private _chartElement;

@@ -28,3 +30,3 @@ private _ccElement;

group: string;
point: dataPoint;
point: SupportedDataPointType;
stat: string;

@@ -34,4 +36,2 @@ };

private _initializeData;
private _calculateMetadataByGroup;
private _initializeAxis;
private _startListening;

@@ -49,4 +49,7 @@ private _playAndSpeak;

private _playAllRight;
private _playAlLCategoriesRight;
private _playAlLCategoriesLeft;
private _playCurrent;
private _onFocus;
private _speakCurrent;
}
import type { AudioEngine } from "./audio/";
import type { c2m } from "./c2mChart";
import type { SupportedDataPointType } from "./dataPoint";
declare type SupportedInputType = SupportedDataPointType | number;
export declare type SonifyTypes = {
data: dataSet | dataPoint[] | number[];
type: SUPPORTED_CHART_TYPES | SUPPORTED_CHART_TYPES[];
data: dataSet | SupportedInputType[];
element: HTMLElement;

@@ -12,3 +16,2 @@ axes?: {

cc?: HTMLElement;
type?: SUPPORTED_CHART_TYPES;
audioEngine?: AudioEngine;

@@ -18,9 +21,4 @@ options?: c2mOptions;

export declare type dataSet = {
[groupName: string]: dataPoint[];
[groupName: string]: SupportedInputType[];
};
export declare type dataPoint = {
x: number;
y?: number | StatBundle;
y2?: number;
};
export declare type AxisData = {

@@ -33,3 +31,5 @@ minimum?: number;

export declare enum SUPPORTED_CHART_TYPES {
LINE = "line"
LINE = "line",
BAR = "bar",
BAND = "band"
}

@@ -57,1 +57,6 @@ export declare type StatBundle = {

};
export declare type c2mGolangReturn = {
err: null | string;
data?: c2m;
};
export {};

@@ -1,6 +0,7 @@

import type { AxisData, dataPoint, StatBundle, SUPPORTED_CHART_TYPES } from "./types";
import type { SupportedDataPointType } from "./dataPoint";
import type { AxisData, StatBundle, SUPPORTED_CHART_TYPES, validAxes } from "./types";
export declare const interpolateBin: (point: number, min: number, max: number, bins: number) => number;
export declare const calcPan: (pct: number) => number;
declare type SummaryTypes = {
type: SUPPORTED_CHART_TYPES;
type: SUPPORTED_CHART_TYPES | SUPPORTED_CHART_TYPES[];
title: string;

@@ -13,9 +14,16 @@ dataRows: number;

export declare const generateSummary: ({ type, title, dataRows, x, y, y2 }: SummaryTypes) => string;
export declare const calculateAxisMinimum: (data: dataPoint[][], prop: "x" | "y" | "y2") => number;
export declare const calculateAxisMaximum: (data: dataPoint[][], prop: "x" | "y" | "y2") => number;
export declare const calculateAxisMinimum: (data: SupportedDataPointType[][], prop: "x" | "y" | "y2") => number;
export declare const calculateAxisMaximum: (data: SupportedDataPointType[][], prop: "x" | "y" | "y2") => number;
export declare const defaultFormat: (value: number) => string;
export declare const sentenceCase: (str: string) => string;
export declare const generatePointDescription: (point: dataPoint, xAxis: AxisData, yAxis: AxisData, stat?: keyof StatBundle) => string;
export declare const usesAxis: (data: dataPoint[][], axisName: "x" | "y" | "y2") => boolean;
export declare const uniqueArray: <T>(arr: T[]) => T[];
export declare const generatePointDescription: (point: SupportedDataPointType, xAxis: AxisData, yAxis: AxisData, stat?: keyof StatBundle) => string;
export declare const usesAxis: (data: SupportedDataPointType[][], axisName: "x" | "y" | "y2") => boolean;
export declare const calculateMetadataByGroup: (data: SupportedDataPointType[][]) => {
minimumPointIndex: number;
maximumPointIndex: number;
tenths: number;
availableStats: any[];
statIndex: number;
}[];
export declare const initializeAxis: (data: SupportedDataPointType[][], axisName: validAxes, userAxis?: AxisData) => AxisData;
export {};
{
"name": "chart2music",
"version": "0.2.0",
"version": "0.3.0",
"main": "dist/index.js",

@@ -5,0 +5,0 @@ "module": "dist/index.mjs",

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc