From 137282fefbb30d8d0dd729f6bc8ff819e77ff0c9 Mon Sep 17 00:00:00 2001 From: daiiz Date: Sun, 3 Jan 2016 11:21:58 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=E8=AB=96=E7=90=86=E5=89=8A=E9=99=A4?= =?UTF-8?q?=E3=81=AE=E3=83=87=E3=83=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- layout.force.js | 25 ++++++++++++++++++++++--- layout.force.miil.js | 26 +++++++++++++++++++++++--- src/LayoutForce.js | 25 +++++++++++++++++++++++-- src/MiilGraph.js | 21 +++++++++++++++++++-- 4 files changed, 87 insertions(+), 10 deletions(-) diff --git a/layout.force.js b/layout.force.js index a35049c..51a38c0 100644 --- a/layout.force.js +++ b/layout.force.js @@ -56,17 +56,36 @@ var LayoutForce = (function () { var self = this; var svg = d3.select('#' + this.stageId); + // 論理削除されているノードを非表示にする + for (var i = 0; i < this.nodes.length; i++) { + var node = this.nodes[i]; + var id = node.id; + if (document.getElementById('node-' + id) !== null) { + if (node.type === 'photo' && node.visible === false) { + document.getElementById('node-' + id).style.visibility = 'hidden'; + document.getElementById('link-to-' + id).style.visibility = 'hidden'; + } else if (node.type === 'photo' && node.visible === true) { + document.getElementById('node-' + id).style.visibility = 'visible'; + document.getElementById('link-to-' + id).style.visibility = 'visible'; + } + } + } + // Linksを反映 - var edge = svg.selectAll('.link').data(this.links).enter().append('line').attr('class', 'link').style('stroke', function (d) { + var edge = svg.selectAll('.link').data(this.links).enter().append('line').attr('class', 'link').attr('id', function (d) { + return 'link-to-' + d.target.id; + }).style('stroke', function (d) { return _this.getEdgeColorByTargetNodeType(d.target.type); }).style('stroke-width', function (d) { if (d.value !== undefined) return d.value; return 1; }); - svg.selectAll('link').data(this.links).exit().remove(); + svg.selectAll('.link').data(this.links).exit().remove(); // Nodesを反映 - var node = svg.selectAll('.node').data(this.nodes).enter().append('g').attr('class', 'node').call(this.force.drag); + var node = svg.selectAll('.node').data(this.nodes).enter().append('g').attr('id', function (d) { + return 'node-' + d.id; + }).attr('class', 'node').call(this.force.drag); svg.selectAll('.node').data(this.nodes).exit().remove(); // Node.Circlesを反映 diff --git a/layout.force.miil.js b/layout.force.miil.js index 874d07e..f3a0566 100644 --- a/layout.force.miil.js +++ b/layout.force.miil.js @@ -105,12 +105,14 @@ var MiilGraph = (function (_LayoutForce) { photos.forEach(function (photo_json) { var parentNodeId = photo_json[pid]; var me = { + pid: parentNodeId, id: photo_json.id, title: photo_json.title, type: 'photo', photo_url: photo_json.url, page_url: photo_json.page_url, - group: parentNodeId + group: parentNodeId, + visible: true }; self.addNode(me); var parent = self.getNodeById(parentNodeId); @@ -131,6 +133,21 @@ var MiilGraph = (function (_LayoutForce) { // TODO: `m`を使わない場合どうすれば良いのかわからない m.parseMiilPhotos(callback_res, 'subcategory', m); } + }, { + key: 'closeNodeExceptNodeId', + value: function closeNodeExceptNodeId(id) { + var _this3 = this; + + var nodes = this.getNodesAll(); + nodes.forEach(function (node) { + if (node.type === 'photo' && node.pid != id) { + console.info(node.pid); + _this3.updateNodeValuesById(node.id, { visible: false }); + } else if (node.type === 'photo' && node.pid == id) { + _this3.updateNodeValuesById(node.id, { visible: true }); + } + }); + } // @Override }, { @@ -145,11 +162,11 @@ var MiilGraph = (function (_LayoutForce) { }, { key: 'appLoad', value: function appLoad() { - var _this3 = this; + var _this4 = this; miil_categories.forEach(function (cate) { if (cate.category_id !== 588 && cate.category_id !== 589) { - _this3.parseMiilCategories(cate, [_this3.getNodeIdxById('miilroot')]); + _this4.parseMiilCategories(cate, [_this4.getNodeIdxById('miilroot')]); } }); this.drawGraph(); @@ -169,11 +186,14 @@ var MiilGraph = (function (_LayoutForce) { this.parseMiilSubCategories(id); console.info(node); } else if (type === 'subcategory') { + // 自身以外のサブカテゴリに属するコンテンツを非表示にする + this.closeNodeExceptNodeId(id); // サブカテゴリに属するコンテンツを展開する var baseApi = 'https://api.miil.me/api/photos/recent/categories/' + node.id; var api = this.getMiilApiUrl(baseApi, node.nextUrl, 'callback=ps'); d3.jsonp(api, null); } else if (type === 'user') { + this.closeNodeExceptNodeId(id); var userName = node.title; var baseApi = 'https://api.miil.me/api/users/' + userName + '/photos/public'; var api = this.getMiilApiUrl(baseApi, node.nextUrl, 'callback=pu'); diff --git a/src/LayoutForce.js b/src/LayoutForce.js index 877d4ff..d99cfa9 100644 --- a/src/LayoutForce.js +++ b/src/LayoutForce.js @@ -40,13 +40,31 @@ class LayoutForce { } drawGraph () { - var self =this; + var self = this; var svg = d3.select('#' + this.stageId); + // 論理削除されているノードを非表示にする + for (var i = 0; i < this.nodes.length; i++) { + var node = this.nodes[i]; + var id = node.id; + if (document.getElementById('node-' + id) !== null) { + if (node.type === 'photo' && node.visible === false) { + document.getElementById('node-' + id).style.visibility = 'hidden'; + document.getElementById('link-to-' + id).style.visibility = 'hidden'; + }else if (node.type === 'photo' && node.visible === true) { + document.getElementById('node-' + id).style.visibility = 'visible'; + document.getElementById('link-to-' + id).style.visibility = 'visible'; + } + } + } + // Linksを反映 var edge = svg.selectAll('.link').data(this.links).enter() .append('line') .attr('class', 'link') + .attr('id', d => { + return 'link-to-' + (d.target.id); + }) .style('stroke', d => { return this.getEdgeColorByTargetNodeType(d.target.type); }) @@ -54,11 +72,14 @@ class LayoutForce { if (d.value !== undefined) return d.value; return 1; }); - svg.selectAll('link').data(this.links).exit().remove(); + svg.selectAll('.link').data(this.links).exit().remove(); // Nodesを反映 var node = svg.selectAll('.node').data(this.nodes).enter() .append('g') + .attr('id', d => { + return 'node-' + d.id; + }) .attr('class', 'node') .call(this.force.drag); svg.selectAll('.node').data(this.nodes).exit().remove(); diff --git a/src/MiilGraph.js b/src/MiilGraph.js index 7a02255..5e7690d 100644 --- a/src/MiilGraph.js +++ b/src/MiilGraph.js @@ -73,13 +73,15 @@ class MiilGraph extends LayoutForce { photos.forEach(photo_json => { var parentNodeId = photo_json[pid]; var me = { + pid: parentNodeId, id: photo_json.id, title: photo_json.title, type: 'photo', photo_url: photo_json.url, page_url: photo_json.page_url, - group: parentNodeId - } + group: parentNodeId, + visible: true + }; self.addNode(me); var parent = self.getNodeById(parentNodeId); parent.nextUrl = nextUrl; @@ -98,6 +100,18 @@ class MiilGraph extends LayoutForce { m.parseMiilPhotos(callback_res, 'subcategory', m); } + closeNodeExceptNodeId (id) { + var nodes = this.getNodesAll(); + nodes.forEach(node => { + if (node.type === 'photo' && node.pid != id) { + console.info(node.pid); + this.updateNodeValuesById(node.id, {visible: false}); + }else if (node.type === 'photo' && node.pid == id) { + this.updateNodeValuesById(node.id, {visible: true}); + } + }); + } + // @Override getFillColorByNodeType (type) { if (type === 'user' || type === 'root') return '#F4433C'; @@ -127,11 +141,14 @@ class MiilGraph extends LayoutForce { this.parseMiilSubCategories(id); console.info(node); }else if (type === 'subcategory') { + // 自身以外のサブカテゴリに属するコンテンツを非表示にする + this.closeNodeExceptNodeId(id); // サブカテゴリに属するコンテンツを展開する var baseApi = 'https://api.miil.me/api/photos/recent/categories/' + node.id; var api = this.getMiilApiUrl(baseApi, node.nextUrl, 'callback=ps'); d3.jsonp(api, null); }else if (type === 'user') { + this.closeNodeExceptNodeId(id); var userName = node.title; var baseApi = 'https://api.miil.me/api/users/'+ userName +'/photos/public'; var api = this.getMiilApiUrl(baseApi, node.nextUrl, 'callback=pu'); From dfe7c4617aec71200b4a5abf61653fcd1b98bb54 Mon Sep 17 00:00:00 2001 From: daiiz Date: Sun, 3 Jan 2016 13:00:06 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=E3=83=87=E3=83=BC=E3=82=BF=E3=82=92?= =?UTF-8?q?=E7=89=A9=E7=90=86=E5=89=8A=E9=99=A4=E3=81=99=E3=82=8B=E3=83=87?= =?UTF-8?q?=E3=83=A2=E3=81=AB=E6=8C=91=E6=88=A6=20=E3=81=86=E3=81=BE?= =?UTF-8?q?=E3=81=8F=E5=8B=95=E3=81=8B=E3=81=AA=E3=81=84=EF=BC=88=E5=8E=9F?= =?UTF-8?q?=E5=9B=A0=E8=AA=BF=E6=9F=BB=E4=B8=AD=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- layout.force.js | 38 +++++++++++++++++++------------------- layout.force.miil.js | 10 ++++++---- src/LayoutForce.js | 36 +++++++++++++++++------------------- src/MiilGraph.js | 10 ++++++---- 4 files changed, 48 insertions(+), 46 deletions(-) diff --git a/layout.force.js b/layout.force.js index 51a38c0..adf71fd 100644 --- a/layout.force.js +++ b/layout.force.js @@ -56,23 +56,9 @@ var LayoutForce = (function () { var self = this; var svg = d3.select('#' + this.stageId); - // 論理削除されているノードを非表示にする - for (var i = 0; i < this.nodes.length; i++) { - var node = this.nodes[i]; - var id = node.id; - if (document.getElementById('node-' + id) !== null) { - if (node.type === 'photo' && node.visible === false) { - document.getElementById('node-' + id).style.visibility = 'hidden'; - document.getElementById('link-to-' + id).style.visibility = 'hidden'; - } else if (node.type === 'photo' && node.visible === true) { - document.getElementById('node-' + id).style.visibility = 'visible'; - document.getElementById('link-to-' + id).style.visibility = 'visible'; - } - } - } - // Linksを反映 - var edge = svg.selectAll('.link').data(this.links).enter().append('line').attr('class', 'link').attr('id', function (d) { + var e = svg.selectAll('.link').data(this.links); + var edge = e.enter().append('line').attr('class', 'link').attr('id', function (d) { return 'link-to-' + d.target.id; }).style('stroke', function (d) { return _this.getEdgeColorByTargetNodeType(d.target.type); @@ -80,13 +66,14 @@ var LayoutForce = (function () { if (d.value !== undefined) return d.value; return 1; }); - svg.selectAll('.link').data(this.links).exit().remove(); + e.exit().remove(); // Nodesを反映 - var node = svg.selectAll('.node').data(this.nodes).enter().append('g').attr('id', function (d) { + var n = svg.selectAll('.node').data(this.nodes); + var node = n.enter().append('g').attr('id', function (d) { return 'node-' + d.id; }).attr('class', 'node').call(this.force.drag); - svg.selectAll('.node').data(this.nodes).exit().remove(); + n.exit().remove(); // Node.Circlesを反映 var circle = node.append('circle').attr('r', function (d) { @@ -182,6 +169,19 @@ var LayoutForce = (function () { key: 'removeLinkById', value: function removeLinkById(id, redraw) {} + // ノードとリンクのペアを削除する + }, { + key: 'removeNode', + value: function removeNode(nodeId, redraw) { + this.nodes = this.nodes.filter(function (node) { + return node.id == nodeId ? null : node; + }); + this.links = this.links.filter(function (link) { + return link.target.id == nodeId ? null : link; + }); + this.drawGraph(); + } + // canvasサイズを設定する }, { key: 'setGraphSize', diff --git a/layout.force.miil.js b/layout.force.miil.js index f3a0566..2e4fa17 100644 --- a/layout.force.miil.js +++ b/layout.force.miil.js @@ -139,14 +139,16 @@ var MiilGraph = (function (_LayoutForce) { var _this3 = this; var nodes = this.getNodesAll(); + var del_nodeIds = []; nodes.forEach(function (node) { if (node.type === 'photo' && node.pid != id) { - console.info(node.pid); - _this3.updateNodeValuesById(node.id, { visible: false }); - } else if (node.type === 'photo' && node.pid == id) { - _this3.updateNodeValuesById(node.id, { visible: true }); + del_nodeIds.push(node.id); } }); + + del_nodeIds.forEach(function (nid) { + _this3.removeNode(nid, true); + }); } // @Override diff --git a/src/LayoutForce.js b/src/LayoutForce.js index d99cfa9..08c2e3f 100644 --- a/src/LayoutForce.js +++ b/src/LayoutForce.js @@ -43,23 +43,9 @@ class LayoutForce { var self = this; var svg = d3.select('#' + this.stageId); - // 論理削除されているノードを非表示にする - for (var i = 0; i < this.nodes.length; i++) { - var node = this.nodes[i]; - var id = node.id; - if (document.getElementById('node-' + id) !== null) { - if (node.type === 'photo' && node.visible === false) { - document.getElementById('node-' + id).style.visibility = 'hidden'; - document.getElementById('link-to-' + id).style.visibility = 'hidden'; - }else if (node.type === 'photo' && node.visible === true) { - document.getElementById('node-' + id).style.visibility = 'visible'; - document.getElementById('link-to-' + id).style.visibility = 'visible'; - } - } - } - // Linksを反映 - var edge = svg.selectAll('.link').data(this.links).enter() + var e = svg.selectAll('.link').data(this.links); + var edge = e.enter() .append('line') .attr('class', 'link') .attr('id', d => { @@ -72,17 +58,18 @@ class LayoutForce { if (d.value !== undefined) return d.value; return 1; }); - svg.selectAll('.link').data(this.links).exit().remove(); + e.exit().remove(); // Nodesを反映 - var node = svg.selectAll('.node').data(this.nodes).enter() + var n = svg.selectAll('.node').data(this.nodes); + var node = n.enter() .append('g') .attr('id', d => { return 'node-' + d.id; }) .attr('class', 'node') .call(this.force.drag); - svg.selectAll('.node').data(this.nodes).exit().remove(); + n.exit().remove(); // Node.Circlesを反映 var circle = node.append('circle') @@ -178,6 +165,17 @@ class LayoutForce { } + // ノードとリンクのペアを削除する + removeNode (nodeId, redraw) { + this.nodes = this.nodes.filter(node => { + return (node.id == nodeId) ? null : node; + }); + this.links = this.links.filter(link => { + return (link.target.id == nodeId) ? null : link; + }); + this.drawGraph(); + } + // canvasサイズを設定する setGraphSize () { var width = window.innerWidth - this.widthPhotoGallery; diff --git a/src/MiilGraph.js b/src/MiilGraph.js index 5e7690d..604e3d6 100644 --- a/src/MiilGraph.js +++ b/src/MiilGraph.js @@ -102,14 +102,16 @@ class MiilGraph extends LayoutForce { closeNodeExceptNodeId (id) { var nodes = this.getNodesAll(); + var del_nodeIds = []; nodes.forEach(node => { if (node.type === 'photo' && node.pid != id) { - console.info(node.pid); - this.updateNodeValuesById(node.id, {visible: false}); - }else if (node.type === 'photo' && node.pid == id) { - this.updateNodeValuesById(node.id, {visible: true}); + del_nodeIds.push(node.id); } }); + + del_nodeIds.forEach(nid => { + this.removeNode(nid, true); + }); } // @Override