Changes to code & gulp WIP

This commit is contained in:
Ruben van de Ven 2019-11-21 19:59:38 +01:00
parent 95a35c1f06
commit 1d92fea37a
4 changed files with 250 additions and 55 deletions

1
.gitattributes vendored Normal file
View file

@ -0,0 +1 @@
*.jpg filter=lfs diff=lfs merge=lfs -text

View file

@ -53,6 +53,7 @@ gulp.task('scripts', function() {
.pipe(uglify()) .pipe(uglify())
.pipe(rename({ extname: '.min.js' })) .pipe(rename({ extname: '.min.js' }))
// .pipe(sourcemaps.write('maps')) // .pipe(sourcemaps.write('maps'))
.pipe(sourcemaps.write(''))
.pipe(gulp.dest(paths.scripts.d3destDir)) // save .min.js .pipe(gulp.dest(paths.scripts.d3destDir)) // save .min.js
}); });

View file

@ -8,7 +8,7 @@
"s:seeAlso": [ "https://rubenvandeven.com/rubenvandeven.jsonld", "https://rubenvandeven.com/foaf.rdf#me"], "s:seeAlso": [ "https://rubenvandeven.com/rubenvandeven.jsonld", "https://rubenvandeven.com/foaf.rdf#me"],
"author": "author":
{ {
"@id": "https://rubenvandeven.com/ruben", "@id": "https://rubenvandeven.com/#me",
"@type": "Person", "@type": "Person",
"name": "Ruben van de Ven", "name": "Ruben van de Ven",
"jobTitle": "digital artist / researcher of software culture", "jobTitle": "digital artist / researcher of software culture",
@ -17,14 +17,14 @@
"@reverse": { "@reverse": {
"member": [ "member": [
{ {
"@id": "http://plottingd.at/a#id", "@id": "https://rubenvandeven.com/member/plottingdata",
"@type": "PerformingGroup", "@type": "PerformingGroup",
"name": "Plotting Data: dramatisation as tactic", "name": "Plotting Data: dramatisation as tactic",
"url": "http://plottingd.at/a", "url": "http://plottingd.at/a",
"foundingDate": "2018", "foundingDate": "2018",
"description": "A research into <em>Data Dramatisation</em> as a tactic to make data visualisations more transparent in their underlying procedures of data collection. We advocate a form of data literacy that is not so much focussed on programming skill, but rather one that brings an understanding of data infrastructures: allowing for restistance against data driven governance.", "description": "A research into <em>Data Dramatisation</em> as a tactic to make data visualisations more transparent in their underlying procedures of data collection. We advocate a form of data literacy that is not so much focussed on programming skill, but rather one that brings an understanding of data infrastructures: allowing for restistance against data driven governance.",
"member": [ "member": [
{"@id": "http://randomizer.info#person"} {"@id": "https://rubenvandeven.com/person/cristina-cochior"}
], ],
"@reverse": { "@reverse": {
"about": [ "about": [
@ -102,6 +102,59 @@
} }
], ],
"author": [ "author": [
{
"@type": "MediaObject",
"name": "Ghost Worker",
"dateCreated": "2019",
"description": "Nowadays, we are not only increasingly delegating and automating tasks and processes, there also new forms of work that are being created for people. With the emergence of services such as Amazon's Mechanical Turk, specific parts of automatic processes are being outsourced to human workers. These Human Intelligence Tasks are tasks that a machine cannot execute, for example retyping a scanned receipt or entering a Captcha code. In this way machines selectively delegate tasks to humans, creating a human working class that remains largely invisible.Merijn van Moll and Ruben van de Ven want to make this feedback loop between man and machine visible. This creates a new ritual in which the spirit of the worker is invoked again and again.\n\nThis project was developed in light of <em>Future scenarios for AI and the job market</em> by Setup and the NSvP (Dutch Foundation for Psycho technology)",
"image": [
{
"@type": "ImageObject",
"contentUrl": "assets\/image\/ghost_worker01.jpg",
"thumbnailUrl": "assets\/thumb\/ghost_worker01.jpg"
},
{
"@type": "ImageObject",
"contentUrl": "assets\/image\/ghost_worker02.jpg",
"thumbnailUrl": "assets\/thumb\/ghost_worker02.jpg"
},
{
"@type": "ImageObject",
"contentUrl": "assets\/image\/ghost_worker03.jpg",
"thumbnailUrl": "assets\/thumb\/ghost_worker03.jpg"
},
{
"@type": "ImageObject",
"contentUrl": "assets\/image\/ghost_worker04.jpg",
"thumbnailUrl": "assets\/thumb\/ghost_worker04.jpg"
}
],
"author": {
"@id": "https://rubenvandeven.com/person/merijn-van-moll",
"@type": "Person",
"name": "Merijn van Moll",
"url": "https://merijnvanmoll.nl/"
}
},
{
"@type": "MediaObject",
"name": "Writing lesson",
"dateCreated": "2019",
"description": "I taught a computer how to write the name of my son. This machine learning processes is visualised with a pen plotter.",
"s:seeAlso": [ "https://gitlab.com/rubenvandeven/diede"],
"image": [
{
"@type": "ImageObject",
"contentUrl": "assets\/image\/diede-2.jpg",
"thumbnailUrl": "assets\/thumb\/diede-2.jpg"
},
{
"@type": "ImageObject",
"contentUrl": "assets\/image\/diede-1.jpg",
"thumbnailUrl": "assets\/thumb\/diede-1.jpg"
}
]
},
{ {
"@type": "MediaObject", "@type": "MediaObject",
"name": "Sustaining Gazes", "name": "Sustaining Gazes",
@ -347,6 +400,22 @@
"endDate": "2018-11-15", "endDate": "2018-11-15",
"workFeatured": [] "workFeatured": []
}, },
{
"@type": "ExhibitionEvent",
"name": "Free Panorama - Shenzen MAF",
"url": "http://shenzhenmaf.cn/Portal/en-US/Exhibition/Detail/10f64524-be11-1985-bbfa-7dd7d27868de",
"location": "Pingshan Cultural Center Exhibition Gallery, Shenzen",
"startDate": "2019-04-20",
"endDate": "2019-05",
"workFeatured": [],
"image": [
{
"@type": "ImageObject",
"contentUrl": "assets\/image\/eh-shenzen.jpg",
"thumbnailUrl": "assets\/thumb\/eh-shenzen.jpg"
}
]
},
{ {
"@id": "https://rubenvandeven.com/exhibition/mood_swings", "@id": "https://rubenvandeven.com/exhibition/mood_swings",
"@type": "ExhibitionEvent", "@type": "ExhibitionEvent",
@ -550,7 +619,7 @@
"duration": "11:32 (∞ loop)", "duration": "11:32 (∞ loop)",
"description": "Whether the video frames are ordered by time or by emotion will not make a difference to a computer. For it, both orderings are just as logical. However, for the human spectator the reordered display of frames becomes a disruptive process. The human is positioned as a required agent for meaning making in an algorithmic procedure.\n\nIn collaboration with Cristina Cochior I went manually through the Eye's public collection, and catalogued faces by surrendering them to an emotion detection algorithm. Cutting from one face to another,its uncritical selection produced a new portrait of emotional gradients moving in-between anger and happiness.", "description": "Whether the video frames are ordered by time or by emotion will not make a difference to a computer. For it, both orderings are just as logical. However, for the human spectator the reordered display of frames becomes a disruptive process. The human is positioned as a required agent for meaning making in an algorithmic procedure.\n\nIn collaboration with Cristina Cochior I went manually through the Eye's public collection, and catalogued faces by surrendering them to an emotion detection algorithm. Cutting from one face to another,its uncritical selection produced a new portrait of emotional gradients moving in-between anger and happiness.",
"author": { "author": {
"@id": "http://randomizer.info#person", "@id": "https://rubenvandeven.com/person/cristina-cochior",
"@type": "Person", "@type": "Person",
"name": "Cristina Cochior", "name": "Cristina Cochior",
"url": "http://randomizer.info" "url": "http://randomizer.info"
@ -636,6 +705,23 @@
}, },
"@reverse": { "@reverse": {
"about": [ "about": [
{
"@type": "Event",
"name": "Presentation @ Act Natural 04",
"startDate": "2019-06-08",
"endDate": "2019-06-08",
"organizer": "Jeisson Drenth",
"location": "Doornroosje, Rotterdam"
},
{
"@type": "Event",
"name": "Presentation @ BARTALK #12: Coded Gestures",
"startDate": "2018-10-26",
"endDate": "2018-10-26",
"organizer": ["Yun Ingrid Lee", "Rae Parnell"],
"location": "Doornroosje, Rotterdam",
"url": "https://bartalkdh.wordpress.com/bartalk-12-coded-gestures/"
},
{ {
"@type": "Event", "@type": "Event",
"name": "Presentation @ Media Lab UFRJ", "name": "Presentation @ Media Lab UFRJ",
@ -852,7 +938,7 @@
] ]
}, },
{ {
"@type": "MediaObject", "@type": "Movie",
"name": "Waterdagen", "name": "Waterdagen",
"dateCreated": "2013", "dateCreated": "2013",
"description": "Adam is security guard at a nursing home with comatose patients. During his night shifts he has unsettling visions of someone drowning. He seeks his comfort in the company of his pregnant girlfriend. Days of Water is a story on guilt and shame; and on a longing for hope.\nI wrote and directed this film for my graduation as film director for fiction at the Utrecht School of the Arts.\nIt was accompanied by my MA research on spectatorial emotion and the influence emotions on the spectator's sympathy for the protagonist.", "description": "Adam is security guard at a nursing home with comatose patients. During his night shifts he has unsettling visions of someone drowning. He seeks his comfort in the company of his pregnant girlfriend. Days of Water is a story on guilt and shame; and on a longing for hope.\nI wrote and directed this film for my graduation as film director for fiction at the Utrecht School of the Arts.\nIt was accompanied by my MA research on spectatorial emotion and the influence emotions on the spectator's sympathy for the protagonist.",
@ -965,6 +1051,82 @@
} }
], ],
"contributor": [ "contributor": [
{
"@type": "MediaObject",
"name": "Pillow Talk",
"dateCreated": "2019",
"description": "The voice is surely an uncanny phenomenon. In the digital age it leaves us constantly in doubt, if a person or a non-person is speaking. In this immersive performance, doubt and conviction change roles in the blink of an eye. Spread out on a hilly landscape, audience engages in a conversation with something that is there and not there at the same time. An artificial voice functions as a mediator, a partner and a mirror to one's own.\n\nWhile conversations are constructed word-by-word, impressions are shared, naps are taken, and time is passed, Pillow Talk is an invitation to suspend eye-to-eye relations and to reposition yourself in direct relation to the non-human.\n\nI developed the interface for the participants, as well as a custom story flow editor for the director/writer Begüm Erciyas.",
"url": "https://www.begumerciyas.com/work/pillow-talk-2019/",
"@reverse": {
"author": [
{
"@type": "Person",
"name": "Begüm Erciyas",
"url":"https://www.begumerciyas.com"
}
],
"workFeatured": [
{
"@type": "TheaterEvent",
"name": "Kunstenfestivaldesarts",
"url": "https://www.kfda.be/en/program/pillow-talk",
"location": "KVS, Brussels",
"startDate": "2019-05-15",
"endDate": "2019-05-20",
"workFeatured": []
},
{
"@type": "TheaterEvent",
"name": "Festival Politics of Algorithms",
"location": "Münchner Kammerspiele",
"startDate": "2019-06-14",
"endDate": "2019-06-16",
"workFeatured": []
},
{
"@type": "TheaterEvent",
"name": "New Empathies Program Series",
"location": "Radialsystem, Berlin",
"startDate": "2019-08-29",
"endDate": "2019-08-31",
"workFeatured": []
},
{
"@type": "TheaterEvent",
"name": "New Settings/Fondation d'Enterprise Hermés",
"location": "Theatre Nanterre-Amandiers, Paris",
"startDate": "2019-11-13",
"endDate": "2019-11-16",
"workFeatured": []
},
{
"@type": "TheaterEvent",
"name": "NEXT Festival",
"location": "Kortrijk",
"startDate": "2019-11-29",
"endDate": "2019-11-31",
"workFeatured": []
}
]
},
"image": [
{
"@type": "ImageObject",
"contentUrl": "assets\/image\/pillow_talk01.jpg",
"thumbnailUrl": "assets\/thumb\/pillow_talk01.jpg"
},
{
"@type": "ImageObject",
"contentUrl": "assets\/image\/pillow_talk02.jpg",
"thumbnailUrl": "assets\/thumb\/pillow_talk02.jpg"
},
{
"@type": "ImageObject",
"contentUrl": "assets\/image\/pillow_talk03.jpg",
"thumbnailUrl": "assets\/thumb\/pillow_talk03.jpg"
}
]
},
{ {
"@type": "MediaObject", "@type": "MediaObject",
"name": "The Specta­cular Times", "name": "The Specta­cular Times",

View file

@ -148,6 +148,7 @@ function createLinkMap(graph) {
if(typeof linkMap[link['target']] == 'undefined') { if(typeof linkMap[link['target']] == 'undefined') {
linkMap[link['target']] = []; linkMap[link['target']] = [];
} }
linkMap[link['target']][linkMap[link['target']].length] = {'id': link['source'], 'name': link['name']}; linkMap[link['target']][linkMap[link['target']].length] = {'id': link['source'], 'name': link['name']};
} }
return linkMap; return linkMap;
@ -191,7 +192,7 @@ function startGraph(graph){
// config // config
var nodeSize = 40; var nodeSize = 40;
var selectedNodeSize = 140; var selectedNodeSize = 140;
var firstNodeId = "https://rubenvandeven.com/ruben"; var firstNodeId = "https://rubenvandeven.com/#me";
// set some vars // set some vars
var currentNodeIdx = 0; var currentNodeIdx = 0;
@ -359,7 +360,7 @@ var positionNodesInCenter = function(idxs) {
forceCx, forceCx,
forceCy forceCy
]; ];
console.log("singleNode", idxs, nodePositions); // console.log("singleNode", idxs, nodePositions);
} }
node.each(function(d,nIdx,nodeEls){ node.each(function(d,nIdx,nodeEls){
@ -404,7 +405,10 @@ var positionNodesInCircle = function(idxs, r) {
simulation.alpha(1); simulation.alpha(1);
simulation.restart(); simulation.restart();
} }
var centerByType = function(types) { var centerByType = function(types, updateHistory) {
if(typeof updateHistory == 'undefined') {
updateHistory = true;
}
if(!Array.isArray(types)) { if(!Array.isArray(types)) {
types = [types]; types = [types];
} }
@ -415,6 +419,11 @@ var centerByType = function(types) {
} }
} }
deselectNode(); deselectNode();
if(updateHistory) {
// TODO: working
console.log(types[0], getDisplayAttr(types[0]),types.map(getDisplayAttr));
history.pushState({types: types}, "", "/@type/"+(types.map(getDisplayAttr).join("+")));
}
positionNodesInCenter(idxs.length ? idxs : null); positionNodesInCenter(idxs.length ? idxs : null);
} }
@ -645,9 +654,14 @@ var closeDetails = function() {
* @param Element|null nodeEl Optional, provide node element, so loop doesn't have to be used to change the Element * @param Element|null nodeEl Optional, provide node element, so loop doesn't have to be used to change the Element
* @return void * @return void
*/ */
var selectNode = function(idx){ var selectNode = function(idx, updateHistory){
if(typeof updateHistory == 'undefined') {
updateHistory = true;
}
let nodeEl = null; let nodeEl = null;
let nodeDatum = null; let nodeDatum = null;
node.each(function(d,nIdx,nodeEls){ node.each(function(d,nIdx,nodeEls){
if(nIdx == idx) { if(nIdx == idx) {
nodeEl = nodeEls[idx]; nodeEl = nodeEls[idx];
@ -658,6 +672,11 @@ var selectNode = function(idx){
return; return;
} }
if(updateHistory) {
history.pushState({node: idx}, getNodeLabel(nodeDatum), "/"+nodeDatum['@id']);
}
// set global var // set global var
positionNodesInCenter(idx); positionNodesInCenter(idx);
@ -713,6 +732,18 @@ var deselectNode = function() {
closeDetails(); closeDetails();
} }
window.addEventListener('popstate', function(event) {
if(event.state.hasOwnProperty('node')) {
selectNode(event.state['node'], false);
}
else {
// if not sure what to do, fall back to first node (also used to return to opening page)
let firstNode = graph['nodes'].find(n => n['@id'] === firstNodeId);
selectNode(graph['nodes'].indexOf(firstNode), false);
}
});
var forceCx, forceCy; var forceCx, forceCy;
var setViewboxForceCenter = function() { var setViewboxForceCenter = function() {
let viewBox = getViewbox(); let viewBox = getViewbox();
@ -897,14 +928,14 @@ let splitText = function(text){
tmid = text.indexOf(char); tmid = text.indexOf(char);
} }
tmid += 1; // we want to cut _after_ the character tmid += 1; // we want to cut _after_ the character
console.log("Char", char, tmid); // console.log("Char", char, tmid);
if(splitPos === false || Math.abs(tmid-mid) < Math.abs(splitPos - mid)){ if(splitPos === false || Math.abs(tmid-mid) < Math.abs(splitPos - mid)){
console.log("least!"); // console.log("least!");
splitPos = tmid; splitPos = tmid;
splitPosChar = char; splitPosChar = char;
} }
} }
console.log("pos",splitPos) // console.log("pos",splitPos)
if(splitPos === false) { if(splitPos === false) {
@ -1114,8 +1145,8 @@ function moveViewboxPx(dx, dy){
// start by selecting the first node :-) // start by selecting the first node :-)
// selectNode(currentNodeIdx+1); // selectNode(currentNodeIdx+1);
// positionNodesInCenter(currentNodeIdx); // positionNodesInCenter(currentNodeIdx);
var firstNode = graph['nodes'].find(n => n['@id'] === "https://rubenvandeven.com/ruben"); var firstNode = graph['nodes'].find(n => n['@id'] === firstNodeId);
selectNode(graph['nodes'].indexOf(firstNode)); selectNode(graph['nodes'].indexOf(firstNode), false);
// closeDetails(); // hide details at first // closeDetails(); // hide details at first
// positionNodesInCenter(currentNodeIdx+1); // positionNodesInCenter(currentNodeIdx+1);