|
|
@ -3,10 +3,10 @@ |
|
|
|
* a designated parent element |
|
|
|
* |
|
|
|
* @param audioFeature: the name of the audio feature (string) |
|
|
|
* @param intervalEndPoints: a sorted array of 5 real numbers defining the intervals (categories) of values, |
|
|
|
* @param intervalEndPoints: a object defining the intervals (categories) of values, |
|
|
|
* for example: |
|
|
|
* [0, 0.25, 0.5, 0.75, 1.0] for instrumentalness would define ranges |
|
|
|
* (0-0.25), (0.25-0.5), (0.5-0.75), (0.75-1.0) |
|
|
|
* {begin: 0, end: 1.0, step: 0.25} for instrumentalness would define ranges |
|
|
|
* [0-0.25), [0.25-0.5), [0.5-0.75), [0.75-1.0] |
|
|
|
* @param parentElem: the DOM element to append the graph to (a selector string) |
|
|
|
* @param userSecret: the user secret string for identification |
|
|
|
* @return None |
|
|
@ -18,11 +18,20 @@ function drawAudioFeatGraph(audioFeature, intervalEndPoints, parentElem, userSec |
|
|
|
height = 270 - margin.top - margin.bottom; |
|
|
|
|
|
|
|
let featureData = {}; |
|
|
|
let currentEndPoint = intervalEndPoints.begin; // start at beginning
|
|
|
|
// Create the keys first in order
|
|
|
|
for (let index = 0; index < intervalEndPoints.length - 1; index++) { |
|
|
|
let key = `${intervalEndPoints[index]} ~ ${intervalEndPoints[index + 1]}`; |
|
|
|
while (currentEndPoint < intervalEndPoints.end) { |
|
|
|
let startOfRange = currentEndPoint; |
|
|
|
let endOfRange = precise(startOfRange + intervalEndPoints.step); |
|
|
|
|
|
|
|
let key = `${startOfRange} ~ ${endOfRange}`; |
|
|
|
featureData[key] = 0; |
|
|
|
currentEndPoint = endOfRange; |
|
|
|
} |
|
|
|
// for (let index = 0; index < intervalEndPoints.length - 1; index++) {
|
|
|
|
// let key = `${intervalEndPoints[index]} ~ ${intervalEndPoints[index + 1]}`;
|
|
|
|
// featureData[key] = 0;
|
|
|
|
// }
|
|
|
|
// define the vertical scaling function
|
|
|
|
let vScale = d3.scaleLinear().range([height, 0]); |
|
|
|
|
|
|
@ -31,12 +40,15 @@ function drawAudioFeatGraph(audioFeature, intervalEndPoints, parentElem, userSec |
|
|
|
// categorize the data points
|
|
|
|
for (let dataPoint of response.data_points) { |
|
|
|
dataPoint = parseFloat(dataPoint); |
|
|
|
let index = intervalEndPoints.length - 2; |
|
|
|
let currLowerBound = precise(intervalEndPoints.end - intervalEndPoints.step); |
|
|
|
let stepSize = intervalEndPoints.step; |
|
|
|
// find the index of the first element greater than dataPoint
|
|
|
|
while (dataPoint < intervalEndPoints[index]) { |
|
|
|
index -= 1; |
|
|
|
while (dataPoint < currLowerBound && currLowerBound >= intervalEndPoints.begin) { |
|
|
|
currLowerBound = precise(currLowerBound - stepSize); |
|
|
|
} |
|
|
|
let key = `${intervalEndPoints[index]} ~ ${intervalEndPoints[index + 1]}`; |
|
|
|
let upperBound = precise(currLowerBound + stepSize); |
|
|
|
currLowerBound = precise(currLowerBound); |
|
|
|
let key = `${currLowerBound} ~ ${upperBound}`; |
|
|
|
featureData[key] += 1; |
|
|
|
} |
|
|
|
|
|
|
@ -103,3 +115,12 @@ function drawAudioFeatGraph(audioFeature, intervalEndPoints, parentElem, userSec |
|
|
|
function capFeatureStr(audioFeature) { |
|
|
|
return audioFeature.charAt(0).toUpperCase() + audioFeature.slice(1); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Converts a number to a floating point value with 2 significant figures |
|
|
|
* @param number: the number to be converted |
|
|
|
* @returns the input converted to two significant digits |
|
|
|
*/ |
|
|
|
function precise(number) { |
|
|
|
return Number.parseFloat(number.toPrecision(2)); |
|
|
|
} |