3D Scatter Plot mit verschiedenen Symbolen und Audio-Ausgabe

Um einen 3D Scatter Plot mit Audio-Ausgabe und mit verschiedenen Symbolen für z.B. bewegende und kaltlassende Musik zu erstellen, geht man, nachdem man alle Daten in uebung2022.js als Arrays definiert hat und die dazugehörenden Audiodateien in einem Ordner (z.B. "klang") gesammelt hat, folgendermaßen vor:

 

1.  Im Header das Plotly-Script (plotly-latest.min.js) und die Array-Definitionen (uebung2022.js) einbinden:

<script src="header/plotly-latest.min.js"></script>
<script src="header/uebung2022.js"></script>

2. Im Header eine Funktion für das Starten und Stoppen von Audio-Dateien einfügen:

<script>
function playAudio(id) {
audioPath = "klang/"+id+".mp3";
myPlayer = document.getElementById('myaudio');
myPlayer.src = audioPath;
myPlayer.play();
}
function stopAudio() {
myPlayer = document.getElementById('myaudio');
myPlayer.pause();
}
</script>

3. Im Body einen Audioplayer (myaudio) anlegen, der mit der obigen Funktion angesprochen werden soll:

<audio id="myaudio"></audio>

4. Im Body einen Bereich festlegen, in dem die Daten visualisiert werden sollen:

<div id="AnzeigeDiv" style="width:800,height:800"></div>

5. Im Body einen Bereich festlegen, in dem bei einem Mouse-Over zusätzliche Informationen erscheinen sollen:

<div style="position:absolute;top: 100px; left: 10px;width:400;z-index:100;"><font size="2" face="Verdana, Arial, Helvetica, sans-serif"><span id="hoverinfo"> </span></font></div>

6. Im Header Arrays für die bewegenden ("heiss") und kaltlassenden ("kalt") Musikstücke und deren Eigenschaften erstellen und in einer Schleife in der Länge der Arrays die Klangmerkmale nach "heiss" = bewegend und "kalt" = kaltlassend aufteilen. Dabei den bewegendsten Klangbeispielen in der Darstellung ein Kreuz ("cross") zuordnen und allen anderen ein Rechteck ("square"):

<script>
//leere Arrays für die bewegenden Musikmerkmale anlegen
var mfcc7_array_heiss=[];
var other_timbral_roughness_array_heiss=[];
var mfcc3_array_heiss=[];
var audiobeispiel_array_heiss=[];
var filename_array_heiss=[];
var auswahl_array_heiss=[];
//leere Arrays für die kaltlassenden Musikmerkmale anlegen
var mfcc7_array_kalt=[];
var other_timbral_roughness_array_kalt=[];
var mfcc3_array_kalt=[];
var audiobeispiel_array_kalt=[];
var filename_array_kalt=[];
var auswahl_array_kalt=[];

//in einer Schleife in der Länge der Arrays die Klangmerkmale nach
//"heiss" = bewegend und "kalt" = kaltlassend aufteilen. Dabei den
//bewegendsten Klangbeispielen in der Darstellung ein Kreuz zuordnen
//und allen anderen ein Rechteck.

for(i=0; i<filename_array.length; i++){
if (emotional_array[i]=="heiss"){
mfcc7_array_heiss.push(mfcc7_array[i]);
other_timbral_roughness_array_heiss.push(other_timbral_roughness_array[i]);
mfcc3_array_heiss.push(mfcc3_array[i]);
audiobeispiel_array_heiss.push(audiobeispiel_array[i]);
filename_array_heiss.push(filename_array[i]);
if (auswahl_array[i]==1){auswahl_array_heiss.push('cross');} else {auswahl_array_heiss.push('square');}
} else {
mfcc7_array_kalt.push(mfcc7_array[i]);
other_timbral_roughness_array_kalt.push(other_timbral_roughness_array[i]);
mfcc3_array_kalt.push(mfcc3_array[i]);
audiobeispiel_array_kalt.push(audiobeispiel_array[i]);
filename_array_kalt.push(filename_array[i]);
if (auswahl_array[i]==1){auswahl_array_kalt.push('cross');} else {auswahl_array_kalt.push('square');}
}
}
</script>

7. Script-Teil starten, in dem die Traces mit den Datenwerten zusammengestellt werden:

<script>
var trace1 = {
x: mfcc7_array_heiss,
y: other_timbral_roughness_array_heiss,
z: mfcc3_array_heiss,
mode: 'markers',
type: 'scatter3d',
name: 'Emotional bewegende Musik',
marker: {symbol: auswahl_array_heiss, color: '#990000', opacity: 0.8,
line: {width: 1}},
text: audiobeispiel_array_heiss,
};

var trace2 = {
x: mfcc7_array_kalt,
y: other_timbral_roughness_array_kalt,
z: mfcc3_array_kalt,
mode: 'markers',
type: 'scatter3d',
name: 'Emotional nicht bewegende Musik',
marker: {symbol: auswahl_array_kalt, color: '#009999', opacity: 0.8,
line: {width: 1}},
text: audiobeispiel_array_kalt,
};

8. Alle Traces im Array data zusammenführen:

var data = [ trace1, trace2 ];

9. Layout bestimmen:

var layout = {
height: 800,
showlegend: true,
scene: {
xaxis: {
type: 'linear',
zeroline: true,
title: 'MFCC7',
},
yaxis: {
type: 'linear',
zeroline: true,
title: 'Roughness (others)',
},
zaxis: {
zeroline: true,
title: 'MFCC3',
},
},
title: 'Emotional bewegende und nicht bewegende Musik',
};

10. Daten und Layout zusammenführen, im oben definierten Bereich ausplotten und dabei das Plotly-Menü ausblenden:

Plotly.newPlot('AnzeigeDiv', data, layout, {displayModeBar: false});

11. Zusätzliche Informationen und Audio ausgeben:

11.1 Die Bereiche, in denen das Mouse-Over erfasst werden soll (myPlot) und in denen die zusätzlichen Informationen angezeigt werden sollen (hoverInfo) als Variablen erhalten:

myPlot = document.getElementById('AnzeigeDiv');
hoverInfo = document.getElementById('hoverinfo');

11.2 Bei einem Mouse-Over die dazugehörige Kurve (indexTrace) und den zur Kurve gehörenden Datenpunkt (indexNumber) ermitteln. Beides wird von 0 an aufwärts gezählt (function(data) Anfang und function(d) Anfang):

myPlot.on('plotly_hover', function(data){
var infotext = data.points.map(function(d){
indexTrace = d.curveNumber;
indexNummer = d.pointNumber;

11.3 Je nach Kurvennummer entweder die Arrays für die bewegenden Musikstücke ansprechen ("heiss") oder für die kaltlassenden Musikstücke ("kalt"). Als Rückgabewert (return) die entsprechenden x-, y- und z-Koordinaten zurückgeben als d.x, d.y und d.z (function(data) Ende):

if (indexTrace==0){
file=filename_array_heiss[indexNummer];beispiel=audiobeispiel_array_heiss[indexNummer];
}
if (indexTrace==1){
file=filename_array_kalt[indexNummer]; beispiel=audiobeispiel_array_kalt[indexNummer];
}
return ( beispiel+': <br>MFCC3: <b>'+d.x+'</b><br>Roughness (other): <b>'+d.y+'</b><br>MFCC7: <b>'+ d.z +'</b>');
});

11.4 Den zurückgegebenen Text (return, s.o.) auf der Webseite am Ort "hoverinfo" ausgeben und das zu dem Datenpunkt ermittelte Audiofile (file) an die Funktion playAudio() im Header der Seite übergeben ( function(d) Ende). Dann für den Mouse-Out den Text für den Ort "hoverInfo" wieder leeren und die Funktion stopAudio() im Header der Seite aufrufen, um das Audiobeispiel zu stoppen, und schließlich das Script wieder abschließen:

hoverInfo.innerHTML = infotext.join('<br/>');
playAudio(file);
})
.on('plotly_unhover', function(data){
hoverInfo.innerHTML = ' ';
stopAudio();
});
</script>