drawData = function(svg) {
svg.append("text")
.join("tspan")
.attr("x", margin.left)
.attr("y", (height * 3 / 5) + 30)
.text("Researchers")
.style('font-family', '"Open Sans", sans-serif');
var simulation = d3.forceSimulation(data.object)
.force('x', d3.forceX((d) => xScale(parseTime(d.date))))
.force('y', d3.forceY((d) => y(d.domain)))
.force('collide', d3.forceCollide(d => d.radius))
.on("tick", tick);
console.log(data)
var simulation1 = d3.forceSimulation(data.person)
.force('forceX', d3.forceX(width / 2).strength(3))
.force('forceY', d3.forceY(height2 + 250).strength(10))
.force('collide', d3.forceCollide(30).strength(1))
.on('tick', ticked)
function tick() {
svg.selectAll('#circle1')
.attr('class', 'dataPoint')
.data(data.object)
.attr('cx', d => d.x)
.attr('cy', d => d.y);
}
function ticked() {
svg.selectAll('#circle2')
.data(data.person)
.attr('cx', d => d.x)
.attr('cy', d => d.y);
}
const g = svg.append("g");
let links = [];
let links_object_list = [];
for (let i = 0; i < data.object.length; i++) {
for (let p = 0; p < data.person.length; p++) {
for (let j = 0; j < data.links.length; j++) {
if (data.object[i].id == data.links[j].target && data.person[p].id == data.links[j].source) {
const coor = d3.linkVertical()({
source: [data.person[p].x, data.person[p].y],
target: [data.object[i].x, data.object[i].y]
}),
link_object = {
color: data.object[i].Color,
coord: coor,
source_x: data.person[p].x,
source_y: data.person[p].y,
target_x: data.object[i].x,
target_y: data.object[i].y,
source: [data.person[p].x, data.person[p].y],
target: [data.object[i].x, data.object[i].y],
id_source: data.person[p].id,
id_target: data.object[i].id
};
links.push(coor)
links_object_list.push(link_object)
}
}
}
}
var link = d3.linkVertical()
.source(function (d) {
return [d.source[0], d.source[1]];
})
.target(function (d) {
return [d.target[0], d.target[1]];
});
const gradient1 = g.append("g")
.selectAll('linearGradient')
.data(links_object_list)
.enter().append('linearGradient')
.attr("id", d => "gradient1" + d.color)
.attr("spreadMethod", "reflect")
.attr('cx', width / 2)
.attr('cy', height / 2)
.attr('r', 600)
gradient1
.append("stop")
.attr("offset", "30%")
.attr("stop-color", "#ee2681")
gradient1
.append("stop")
.attr("offset", "70%")
.attr("stop-color", d => d.color);
gradient1.append("animate")
.attr("attributeName", "x1")
.attr("values", "0%;-200%")
.attr("dur", "7s")
.attr("repeatCount", "indefinite");
gradient1.append("animate")
.attr("attributeName", "x2")
.attr("values", "-100%;-300%")
.attr("dur", "7s")
.attr("repeatCount", "indefinite")
g.selectAll("path")
.data(links_object_list)
.join('path')
.attr("d", link)
.attr('stroke-opacity', '0')
.attr('stroke', d => `url(#gradient1${d.color})`)
.attr('id', d => "path" + d.id_source)
.attr('class', d => "path" + d.id_target)
.attr('fill', 'none');
svg.selectAll('.line-decade')
.data(xScale.ticks())
.join('line')
.attr('class', 'line-decade')
.attr('x1', d => xScale(d))
.attr('x2', d => xScale(d))
.attr('y1', 100)
.attr('y2', height * 3 / 5 - margin.top)
.attr('stroke-width', 1)
.attr('stroke', 'lightgray').select(".domain").style('stroke-opacity', '0');
const node = g.append("g")
.selectAll("g")
.data(data.person)
.enter().append("g")
node.append('pattern')
.attr("id", d => "image"+ d.id)
.attr("width", 1)
.attr("height", 1)
.append("svg:image")
.attr("xlink:href", d => d.url)
.attr("width", 40)
.attr("height", 40);
svg.selectAll("circle")
.data(data.object)
.join("circle")
.attr('class', d => "circle2" + d.year + "+" + d.id)
.attr("id", "circle1")
.attr("r", d => d.radius)
.attr("fill", d => d.Color)
.on('click', function (d) {})
.on("mouseover", function (d, data) {
tooltipcircle
.html("<link rel=preconnect href=https://fonts.gstatic.com> <link href=https://fonts.googleapis.com/css2?family=Montserrat&display=swap rel=stylesheet><div class=full-width><h1 class=h1full-width>" + plus + "Score: 0.0</h1></div><h1 class=h1tooltipcircle>Date</h1><hr><p>" + data.date + "</p><h1 class=h1tooltipcircle>Title</h1><hr><p>" + data.name + "</p><h1 class=h1tooltipcircle>DOI</h1><hr><p>" + data.DOI + "</p><h1 class=h1tooltipcircle>Knowlage Domain</h1><p>" + data.domain + "</p><h1 class=h1tooltipcircle>Keywords</h1><p>" + data.keywords + "</p><h1 class=h1tooltipcircle>Authors</h1><p>" + data.authors + "</p>")
.style('visibility', 'visible');
})
.on('mousemove', function (d) {
if (d.clientX > width / 2) {
tooltipcircle
.style('top', d.clientY + 10 + 'px')
.style('left', d.clientX - 425 + 'px')
.style("display", "inline-block");
} else {
tooltipcircle
.style('top', d.clientY + 10 + 'px')
.style('left', d.clientX + 20 + 'px')
.style("display", "inline-block");
}
})
.on('mouseout', function () {
tooltipcircle.style('visibility', 'hidden');
});
console.log(data)
var most_recent = ''
const datalinks = data
node.append("circle")
.attr('r', 20)
.attr("id", "circle2")
.attr('class', d => "circle" + d.profile)
.attr("fill", d => `url(#image${d.id})`)
.on('click', function (d, data) {
if (most_recent == data.profile) {
d3.selectAll('circle').style("opacity", 1);
d3.selectAll('#circle2').style("opacity", 0.6);
d3.select(this).attr("stroke", "black").style("opacity", 1)
d3.selectAll('#circle2').on('mouseout', function (d, data) {
tooltip.style('visibility', 'hidden');
d3.selectAll("path").style('stroke-opacity', '0')
d3.selectAll("circle")
.attr("stroke", "white")
.style("opacity", 1)
});
d3.selectAll('#circle2').on('mouseover', function (d, data) {
let links3 = [];
const links_object_list3 = [];
for (let i = 0; i < datalinks.object.length; i++) {
for (let p = 0; p < datalinks.person.length; p++) {
for (let j = 0; j < datalinks.links.length; j++) {
if (datalinks.object[i].id == datalinks.links[j].target && datalinks.person[p].id == datalinks.links[j].source) {
const coor3 = d3.linkVertical()({
source: [datalinks.person[p].x, datalinks.person[p].y],
target: [datalinks.object[i].x, datalinks.object[i].y]
}),
link_object3 = {
color: datalinks.object[i].Color,
coord: coor3,
source_x: datalinks.person[p].x,
source_y: datalinks.person[p].y,
target_x: datalinks.object[i].x,
target_y: datalinks.object[i].y,
source: [datalinks.person[p].x, datalinks.person[p].y],
target: [datalinks.object[i].x, datalinks.object[i].y],
id_source: datalinks.person[p].id,
id_target: datalinks.object[i].id
};
links3.push(coor3)
links_object_list3.push(link_object3)
}
}
}
}
var link3 = d3.linkVertical()
.source(function (d) {
return [d.source[0], d.source[1]];
})
.target(function (d) {
return [d.target[0], d.target[1]];
});
g.selectAll("path")
.data(links_object_list3)
.join('path')
.attr("d", link3)
.attr('stroke-opacity', '0')
.attr('stroke', d => `url(#gradient1${d.color})`)
.attr('id', d => "path" + d.id_source)
.attr('class', d => "path" + d.id_target)
.attr('fill', 'none');
var image = "<img src=" + data.url + "/>"
tooltip
.html("<h1>" + facebook + twitter + chat + person + "Score: 0.0 </h1><hr>" + image + "<br/><h1>" + data.name + "</h1><h2>Ph.D.</h2><h1>ORCID</h1><p>" + data.profile + "</p>")
.style('visibility', 'visible')
filterOver("circle" + data.profile, data.id)
d3.select(this).attr("stroke", "black").style("opacity", 1)
d3.select(this).style("cursor", "pointer");
})
most_recent = ""
} else {
most_recent = data.profile
d3.selectAll('circle')
.style("opacity", 0)
d3.select(this)
.style("opacity", 1)
d3.selectAll('#circle1')
.style("opacity", 1)
d3.selectAll('#path' + data.profile)
.style("opacity", 1)
d3.selectAll('#circle2')
.on('mouseout', null)
d3.selectAll('#circle2')
.on('mouseover', null)
most_recent = data.profile
tooltip.html(``)
.style('visibility', 'hidden')
d3.select(this)
.style("cursor", "pointer")
d3.select(this).attr("stroke", "black").style("opacity", 1)
};
})
.on('mouseover', function (d, c) {
let links3 = [];
const links_object_list3 = [];
for (let i = 0; i < datalinks.object.length; i++) {
for (let p = 0; p < datalinks.person.length; p++) {
for (let j = 0; j < datalinks.links.length; j++) {
if (datalinks.object[i].id == datalinks.links[j].target && datalinks.person[p].id == datalinks.links[j].source) {
const coor3 = d3.linkVertical()({
source: [datalinks.person[p].x, datalinks.person[p].y],
target: [datalinks.object[i].x, datalinks.object[i].y]
}),
link_object3 = {
color: datalinks.object[i].Color,
coord: coor3,
source_x: datalinks.person[p].x,
source_y: datalinks.person[p].y,
target_x: datalinks.object[i].x,
target_y: datalinks.object[i].y,
source: [datalinks.person[p].x, datalinks.person[p].y],
target: [datalinks.object[i].x, datalinks.object[i].y],
id_source: datalinks.person[p].id,
id_target: datalinks.object[i].id
};
links3.push(coor3)
links_object_list3.push(link_object3)
}
}
}
}
var link3 = d3.linkVertical()
.source(function (d) {
return [d.source[0], d.source[1]];
})
.target(function (d) {
return [d.target[0], d.target[1]];
});
g.selectAll("path")
.data(links_object_list3)
.join('path')
.attr("d", link3)
.attr('stroke-opacity', '0')
.attr('stroke', d => `url(#gradient1${d.color})`)
.attr('id', d => "path" + d.id_source)
.attr('class', d => "path" + d.id_target)
.attr('fill', 'none');
var image = "<img src=" + c.url + "/>"
tooltip
.html("<h1>" + facebook + twitter + chat + person + "Score: 0.0 </h1><hr>" + image + "<br/><h1>" + c.name + "</h1><h2>Ph.D.</h2><h1>ORCID</h1><p>" + c.profile + "</p>")
.style('visibility', 'visible')
filterOver("circle" + c.profile, c.id)
d3.select(this).attr("stroke", "black").style("opacity", 1)
d3.select(this).style("cursor", "pointer");
})
.on('mouseout', function (d, data) {
d3.selectAll("#path" + data.id).style('stroke-opacity', '0')
filterOut("circle" + data.profile)
d3.select(this).attr("stroke", "white").style("opacity", 1)
tooltip.style('visibility', 'hidden');
})
.on('mousemove', function (d, data) {
if (d.clientX > width / 2) {
tooltip
.style('top', d.clientY + 10 + 'px')
.style('left', d.clientX - 375 + 'px')
.style("display", "inline-block");
} else {
tooltip
.style('top', d.clientY + 10 + 'px')
.style('left', d.clientX + 20 + 'px')
.style("display", "inline-block");
}
});
d3.select('#clusterButton').on('click', () => {
d3.selectAll("path").style('stroke-opacity', '0')
d3.selectAll("#circle2").attr("pointer-events", "all");
simulation = d3.forceSimulation(data.object)
.force('forceX', d3.forceX((d) => xScale(parseTime(d.date))).strength(1))
.force('forceY', d3.forceY((d) => y(d.domain)))
.force('collide', d3.forceCollide(d => d.radius))
.restart()
.on("tick", tick);
document.getElementById("AllButton").disabled = false;
});
d3.select('#groupButton').on('click', () => {
d3.selectAll("#cicle2").attr("pointer-events", "none");
d3.selectAll("path").style('stroke-opacity', '0')
simulation = d3.forceSimulation(data.object)
.force('forceX', d3.forceX((d) => xScale(parseTime(d.date))).strength(6))
.force('forceY', d3.forceY(height / 4).strength(1))
.force('collide', d3.forceCollide(d => d.radius))
.on("tick", tick);
});
d3.select('#NoOneButton').on('click', () => {
d3.selectAll('path')
.style("stroke-opacity", 0);
});
d3.select('#AllButton').on('click', () => {
d3.selectAll('path')
.style("stroke-opacity", 1);
d3.select(".domain").style('stroke-opacity', '0')
let links2 = [];
const links_object_list2 = [];
for (let i = 0; i < data.object.length; i++) {
for (let p = 0; p < data.person.length; p++) {
for (let j = 0; j < data.links.length; j++) {
if (data.object[i].id == data.links[j].target && data.person[p].id == data.links[j].source) {
const coor2 = d3.linkVertical()({
source: [data.person[p].x, data.person[p].y],
target: [data.object[i].x, data.object[i].y]
}),
link_object2 = {
color: data.object[i].Color,
coord: coor2,
source_x: data.person[p].x,
source_y: data.person[p].y,
target_x: data.object[i].x,
target_y: data.object[i].y,
source: [data.person[p].x, data.person[p].y],
target: [data.object[i].x, data.object[i].y],
id_source: data.person[p].id,
id_target: data.object[i].id
};
links2.push(coor2)
links_object_list2.push(link_object2)
}
}
}
}
var link2 = d3.linkVertical()
.source(function (d) {
return [d.source[0], d.source[1]];
})
.target(function (d) {
return [d.target[0], d.target[1]];
});
g.selectAll("path")
.data(links_object_list2)
.join('path')
.attr("d", link2)
.attr('stroke-opacity', '0')
.attr('stroke', d => `url(#gradient1${d.color})`)
.attr('id', d => "path" + d.id_source)
.attr('class', d => "path" + d.id_target)
.attr('fill', 'none');
});
}