Published
Edited
Sep 21, 2021
1 fork
Insert cell
Insert cell
Insert cell
<div style="background-color:#C0F1B0">
## Todo:
*the list is in order **Tenetene (also tara) vagina Body parts** is not read by the narrator. I guess it's a cultural thing.*


Having issues with embedding, I think it's because the waveSurfer isn't working well with the iframe.

there are issues with formatting in firefox, which I will ignore for now.

---


I need to refactor the code as I could do it using a loop or d3's .data()

Long lines of text are truncated, I think there is some svg text attribute to wrap text

errors **Kai is twice in the audio sample.**

Kai (65)

67 Mania isn't there.

### other thoughts

**It might be better to write this using html?**

Would like to look at breaking words into their sounds, so the parts of the words show the letters that make the sounds.

Look at making a word cloud based of the 100 words contect. When the words there are clicked they play the sound and also show the english description.

<br>
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
regionsJSON = { // for saving region data

let regs = []
for (let index = 0; index < regies.length; index++) {
regs.push({
start: wavesurfer.regions.list[regies[index]].start,
end: wavesurfer.regions.list[regies[index]].end,
loop: false,
drag: false,
resize: false
})
}
return regs
}
Insert cell
regies = Object.keys(wavesurfer.regions.list) // should not start playing.. I have to stop playing and then return regies to fix bug
// it plays the first region in the list. I could add an empty region or do the above.
Insert cell
playSpeed_function = // update volume level
wavesurfer.setPlaybackRate(playSpeed)
Insert cell
zoom_function = // update zoom level
wavesurfer.zoom(zoom)
Insert cell
wavesurfer.on('region-click', function(region, e) {
e.stopPropagation();
region.loop = false; // set region to not loop by default

// if ctrl key pressed delete region
// Play on click and Play_loop on shift click
e.ctrlKey ? region.remove() : e.shiftKey ? region.playLoop() : region.play();
});
Insert cell
wavesurfer.on('region-created', function(region, e) {
region.color = 'rgba(0, 200, 0, 0.1)'
});
Insert cell
// wavesurfer.un('region-created', function(region, e) { // remove event
// region.color = 'rgba(0, 200, 0, 0.1)'
// });
Insert cell
wavesurfer.regions.list
Insert cell
wavesurfer.regions.list[regies[0]].play()
Insert cell
// wavesurfer.clearRegions()

Insert cell
controlButtons = {
d3.select('#playb').on('click',() => wavesurfer.playPause())
d3.select('#pauseb').on('click',() => wavesurfer.pause())
d3.select('#stopb').on('click',() => wavesurfer.stop())
}
Insert cell
wavesurfer = {
d3.select('#wavDiv > wave').remove() // delete the wave displayed in the div to prevent doubleup on reload after changes
let ws = WaveSurfer.create({
container: '#wavDiv',
waveColor: '#048BA8',
progressColor: '#F2CE4C',
cursorColor: '#A4036F',
cursorWidth: 1,
height: 300,
scrollParent: true,
plugins: [
cursor.create({
showTime: true,
opacity: 1,
customShowTimeStyle: {
'background-color': '#004', // can't use alpha channel rgba(0, 0, 4, 0.2) as the text doesn't get complely cleared
color: '#ffa',
padding: '2px',
'font-size': '12px'
}
}),
regions.create({
regionsMinLength: 0.5,
regions: teRegions
//
,
dragSelection: {
slop: 5
}
})
]
});
ws.load(audioURL)
return ws}
Insert cell
Insert cell
audioURL = await FileAttachment("words.mp3").url()
Insert cell
FileAttachment("mania.mp3")
Insert cell
teRegions = FileAttachment("regionsJSON (1).json").json()
Insert cell
reo = FileAttachment("100 Māori words@4.tsv").tsv()
Insert cell
viewof table = Inputs.table(reo, {})
Insert cell
WaveSurfer = require("https://unpkg.com/wavesurfer.js/dist/wavesurfer.js")
Insert cell
regions = require("https://unpkg.com/wavesurfer.js/dist/plugin/wavesurfer.regions.js")
Insert cell
cursor = require("https://unpkg.com/wavesurfer.js/dist/plugin/wavesurfer.cursor.js")
Insert cell
Insert cell
svg_w = width
Insert cell
svg_h = Math.ceil(width/2)
Insert cell
// number of rows we can fit on a screen

row = {
let r = [];
let s = (textSize('M').height*1.5) // font height in pixels + padding
for (let y = 0; y < ~~(svg_h / s); ++y) {
r.push(~~(y*s))
}
return r
}

Insert cell
rowSize = (textSize('M').height)
Insert cell
wordSizes = { // maybe I don't need the height
svg_w // run if screen size changes
let ws = []
for (let i = 0; i < reo.length; ++i) {
ws.push(textSize(reo[i].Māori,'words'))
}
return ws
}
Insert cell
// returns a random word and and array for 5 random words including the test word
mutable word = pickWords()
Insert cell
function pickWords()
{

let w = randomWord() // our random word
let otherWords = []
otherWords.push(w)
for (let i = 0; i < 4; ++i) {
otherWords.push(pick(otherWords))
}

d3.shuffle(otherWords)
return {word:w, otherWords}
}
Insert cell
function pick(numbers){
let p = randomWord()
return (numbers.includes(p))? pick(numbers) : p
}
Insert cell
nextWord = textSize('Next Word')
Insert cell
randomWord = d3.randomInt(0, reo.length)
Insert cell
Insert cell
// https://developer.mozilla.org/en-US/docs/Web/API/SVGTextContentElement
// .getRotationOfChar(1)
// .getExtentOfChar(0) // returns a SVG rect object fo the charaters dimentions { height: ,width: ,x: ,y: }
// .getSubStringLength(0,4) // get the length of sub string
// .getEndPositionOfChar(4)
// .getStartPositionOfChar(4)
// .getNumberOfChars()
// .getExtentOfChar(0)

function textSize(text) {
let testIt = d3.select('body').append('svg');
testIt.append('text')
.style('font-family','sans-serif')
.style('font-size', '42px')
.text(text);

let sel = testIt.selectAll('text').node()
let width = sel.getComputedTextLength()
let height = sel.getExtentOfChar(0).height
testIt.remove()
return {width, height}
}
// based on: https://gist.github.com/huytd/327e453c95ca3edadb32d0c867e2561b
Insert cell
textSize('Marae','words')
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more