2017-04-11 2 views
1

私はcsvに基づいてd3.jsという単語の雲を作成しました。 - d3.js条件付き単語の色をwordcloudに入力してください

  • (単語がテキストで思い付いた回数)のカウント
  • 指数(これはどのように価値ある

    • ワード(ユニークワード):私は3つの列を持っているcsvファイルで

      多くのカウントが、それは以下の通りですどのくらいの平均対)を上回っている

    words.csv:

    word count index 
    word1 457  239 
    word2 373  155 
    word3 76  -142 
    word4 345  127 
    word5 12  -206 
    word6 46  -172 
    

    私はyoutubeとjason daviesのワールドクラウドパッケージの助けを借りて次のコードを書いており、それは単語クラウドを作成するために動作しますが、インデックスに基づいて単語の色を変更する方法はわかりません。

    <script> 
    
        var width = 1500, 
         height =400; 
    
        var wordScale = d3.scale.linear().range([10,100]); 
    
        var fill = d3.scale.category20c(); 
        d3.csv("words.csv", function(data) { 
         var subjects = data 
          .map(function(d) {return {text: d.word, size: +d.count} }) 
          .sort(function(a,b) {return d3.descending (a.size, b.size); }) 
          .slice(0,100); 
    
         wordScale.domain([ 
          d3.min(subjects, function(d) {return d.size; }), 
          d3.max(subjects, function(d) {return d.size; }), 
         ]);  
    
        // var layout = cloud() 
         d3.layout.cloud().size([width, height]) 
         .words(subjects) 
         .padding(1) 
         .rotate(function() { return ~~(Math.random() * 2) * 0; }) 
         .font("Impact") 
         .fontSize(function(d) { return wordScale(d.size); }) 
         .on("end", draw) 
         .start(); 
    
        }); 
    
         function draw(words) { 
          d3.select("#word-cloud").append("svg") 
           .attr("width",width) 
           .attr("height",height) 
          .append("g") 
           .attr("transform", "translate("+(width /2)+","+(height /2)+")") 
           //where the center is 
          .selectAll("text") 
           .data(words) 
          .enter().append("text") 
           .style("font-size", function(d) { return d.size + "px"; }) 
           .style("font-family", "Impact") 
           .style("fill", function(d, i) { return fill(i); }) 
           .attr("text-anchor", "middle") 
           .attr("transform", function(d) { 
           return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")"; 
           }) 
           .text(function(d) { return d.text; }); 
        } 
    
    
         </script> 
    
    
    I need to change this line in the code `var fill = d3.scale.category20c();` 
    
    The goal would be that all words above the average (so positive index) are green and all words below the average (negative index) are grey. If the transparency of the color/fill could be dependent on how much above or below the average the count is that would be amazing - but not necessary. 
    
        word count index color 
        word1 457  239 green 
        word2 373  155 green 
        word3 76  -142 grey 
        word4 345  127 green 
        word5 12  -206 grey 
        word6 46  -172 grey 
    

    ありがとうございます!

    UPDATE:

    はダンの答えではなく、インデックスに基づいて、次のことをしようとしました:私は(もエラーメッセージなし)を実行したときに

    mycolor = d3.rgb("#00cc66"); 
    
    var width = 1500, 
        height =400; 
    
    var wordScale = d3.scale.linear().range([10,90]); 
    var colorScale = d3.scale.linear().range([10,90]); 
    
    // var fill = d3.scale.category20c(); 
    d3.csv("words.csv", function(data) { 
        var subjects = data 
         .map(function(d) {return {text: d.word, size: +d.count, clr: d.index } }) 
         .sort(function(a,b) {return d3.descending (a.size, b.size); }) 
         .slice(0,100); 
    
        wordScale.domain([ 
         d3.min(subjects, function(d) {return d.size; }), 
         d3.max(subjects, function(d) {return d.size; }), 
        ]); 
    
        colorScale.domain([ 
         d3.min(subjects, function(d) {return d.clr; }), 
         d3.max(subjects, function(d) {return d.clr; }), 
        ]); 
    
    // var layout = cloud() 
        d3.layout.cloud().size([width, height]) 
        .words(subjects) 
        .padding(1) 
        .rotate(function() { return ~~(Math.random() * 2) * 0; }) 
        .font("Impact") 
        .fontSize(function(d) { return wordScale(d.size); }) 
        .on("end", draw) 
        .start(); 
    
    }); 
    
        function draw(words) { 
         d3.select("#word-cloud").append("svg") 
          .attr("width",width) 
          .attr("height",height) 
         .append("g") 
          .attr("transform", "translate("+(width /2)+","+(height /2)+")") 
          //where the center is 
         .selectAll("text") 
          .data(words) 
         .enter().append("text") 
          .style("fill", function(d) { return d.clr >= 50 ? mycolor : "grey";}) 
          .style("opacity", function(d) { return d.clr/100 }) 
          .style("font-size", function(d) { return d.size + "px"; }) 
          .style("font-family", "Impact") 
          // .style("fill", function(d, i) { return fill(i); }) 
          .attr("text-anchor", "middle") 
          .attr("transform", function(d) { 
          return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")"; 
          }) 
          .text(function(d) { return d.text; }); 
    } 
    

    残念ながら、何も表示されません。

  • 答えて

    2

    上記のコードでは、充填関数は次のようにコードの.append("text")セクションの延伸機能で

    編集:10〜100と仮定wordScaleです。これは、サイズが中間点(55)より高い/低いことに基づいて緑色/灰色に変わります。すぐfill下に次のスタイルを追加し、あなたの他の要求を満たすために

    .style("fill", function(d) { return d.size >= 55 ? "green" : "grey";}) 
    

    :以下、ハードコードのものよりも優れた色の値を使用して自由に感じます。これは、サイズに対して不透明度を設定します(0.1〜1の間)。ここでも、必要に応じてこれらの値を調整することができます。

    .style("opacity", function(d) { return d.size/100 }) 
    

    あなたはこれらの編集を行う場合は、あなたのコードの先頭にvar fillをドロップすることができます。

    UPDATED ANSWER:

    注、私はジェイソン・デイビスがスクリプトエラーなしでリモートでロードするために取得しませんが、デバッグする時間ができませんでした。彼のスクリプトの後に実際の解答のためにスクロールします。私はこれにローテーション要素を追加していません。

    !function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b=b.d3||(b.d3={}),b=b.layout||(b.layout={}),b.cloud=a()}}(function(){var a;return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c||a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(a,b,c){function h(a){return a.text}function i(){return"serif"}function j(){return"normal"}function k(a){return Math.sqrt(a.value)}function l(){return 30*(~~(6*Math.random())-3)}function m(){return 1}function n(a,b,c,d){if(!b.sprite){var h=a.context,i=a.ratio;h.clearRect(0,0,(f<<5)/i,g/i);var j=0,k=0,l=0,m=c.length;for(--d;++d<m;){b=c[d],h.save(),h.font=b.style+" "+b.weight+" "+~~((b.size+1)/i)+"px "+b.font;var n=h.measureText(b.text+"m").width*i,o=b.size<<1;if(b.rotate){var p=Math.sin(b.rotate*e),q=Math.cos(b.rotate*e),r=n*q,s=n*p,t=o*q,u=o*p;n=Math.max(Math.abs(r+u),Math.abs(r-u))+31>>5<<5,o=~~Math.max(Math.abs(s+t),Math.abs(s-t))}else n=n+31>>5<<5;if(o>l&&(l=o),j+n>=f<<5&&(j=0,k+=l,l=0),k+o>=g)break;h.translate((j+(n>>1))/i,(k+(o>>1))/i),b.rotate&&h.rotate(b.rotate*e),h.fillText(b.text,0,0),b.padding&&(h.lineWidth=2*b.padding,h.strokeText(b.text,0,0)),h.restore(),b.width=n,b.height=o,b.xoff=j,b.yoff=k,b.x1=n>>1,b.y1=o>>1,b.x0=-b.x1,b.y0=-b.y1,b.hasText=!0,j+=n}for(var v=h.getImageData(0,0,(f<<5)/i,g/i).data,w=[];--d>=0;)if(b=c[d],b.hasText){for(var n=b.width,x=n>>5,o=b.y1-b.y0,y=0;y<o*x;y++)w[y]=0;if(null==(j=b.xoff))return;k=b.yoff;for(var z=0,A=-1,B=0;B<o;B++){for(var y=0;y<n;y++){var C=x*B+(y>>5),D=v[(k+B)*(f<<5)+(j+y)<<2]?1<<31-y%32:0;w[C]|=D,z|=D}z?A=B:(b.y0++,o--,B--,k++)}b.y1=b.y0+A,b.sprite=w.slice(0,(b.y1-b.y0)*x)}}}function o(a,b,c){c>>=5;for(var k,d=a.sprite,e=a.width>>5,f=a.x-(e<<4),g=127&f,h=32-g,i=a.y1-a.y0,j=(a.y+a.y0)*c+(f>>5),l=0;l<i;l++){k=0;for(var m=0;m<=e;m++)if((k<<h|(m<e?(k=d[l*e+m])>>>g:0))&b[j+m])return!0;j+=c}return!1}function p(a,b){var c=a[0],d=a[1];b.x+b.x0<c.x&&(c.x=b.x+b.x0),b.y+b.y0<c.y&&(c.y=b.y+b.y0),b.x+b.x1>d.x&&(d.x=b.x+b.x1),b.y+b.y1>d.y&&(d.y=b.y+b.y1)}function q(a,b){return a.x+a.x1>b[0].x&&a.x+a.x0<b[1].x&&a.y+a.y1>b[0].y&&a.y+a.y0<b[1].y}function r(a){var b=a[0]/a[1];return function(a){return[b*(a*=.1)*Math.cos(a),a*Math.sin(a)]}}function s(a){var b=4,c=b*a[0]/a[1],d=0,e=0;return function(a){var f=a<0?-1:1;switch(Math.sqrt(1+4*f*a)-f&3){case 0:d+=c;break;case 1:e+=b;break;case 2:d-=c;break;default:e-=b}return[d,e]}}function t(a){for(var b=[],c=-1;++c<a;)b[c]=0;return b}function u(){return document.createElement("canvas")}function v(a){return"function"==typeof a?a:function(){return a}}var d=a("d3-dispatch").dispatch,e=Math.PI/180,f=64,g=2048;b.exports=function(){function I(a){a.width=a.height=1;var b=Math.sqrt(a.getContext("2d").getImageData(0,0,1,1).data.length>>2);a.width=(f<<5)/b,a.height=g/b;var c=a.getContext("2d");return c.fillStyle=c.strokeStyle="red",c.textAlign="center",{context:c,ratio:b}}function J(b,c,d){for(var l,m,n,f=(a[0],a[1],c.x),g=c.y,h=Math.sqrt(a[0]*a[0]+a[1]*a[1]),i=A(a),j=F()<.5?1:-1,k=-j;(l=i(k+=j))&&(m=~~l[0],n=~~l[1],!(Math.min(Math.abs(m),Math.abs(n))>=h));)if(c.x=f+m,c.y=g+n,!(c.x+c.x0<0||c.y+c.y0<0||c.x+c.x1>a[0]||c.y+c.y1>a[1])&&(!d||!o(c,b,a[0]))&&(!d||q(c,d))){for(var y,p=c.sprite,r=c.width>>5,s=a[0]>>5,t=c.x-(r<<4),u=127&t,v=32-u,w=c.y1-c.y0,x=(c.y+c.y0)*s+(t>>5),z=0;z<w;z++){y=0;for(var B=0;B<=r;B++)b[x+B]|=y<<v|(B<r?(y=p[z*r+B])>>>u:0);x+=s}return delete c.sprite,!0}return!1}var a=[256,256],b=h,c=i,e=k,s=j,x=j,y=l,z=m,A=r,B=[],C=1/0,D=d("word","end"),E=null,F=Math.random,G={},H=u;return G.canvas=function(a){return arguments.length?(H=v(a),G):H},G.start=function(){function l(){for(var b=Date.now();Date.now()-b<C&&++i<h&&E;){var c=k[i];c.x=a[0]*(F()+.5)>>1,c.y=a[1]*(F()+.5)>>1,n(d,c,k,i),c.hasText&&J(f,c,g)&&(j.push(c),D.call("word",G,c),g?p(g,c):g=[{x:c.x+c.x0,y:c.y+c.y0},{x:c.x+c.x1,y:c.y+c.y1}],c.x-=a[0]>>1,c.y-=a[1]>>1)}i>=h&&(G.stop(),D.call("end",G,j,g))}var d=I(H()),f=t((a[0]>>5)*a[1]),g=null,h=B.length,i=-1,j=[],k=B.map(function(a,d){return a.text=b.call(this,a,d),a.font=c.call(this,a,d),a.style=s.call(this,a,d),a.weight=x.call(this,a,d),a.rotate=y.call(this,a,d),a.size=~~e.call(this,a,d),a.padding=z.call(this,a,d),a}).sort(function(a,b){return b.size-a.size});return E&&clearInterval(E),E=setInterval(l,0),l(),G},G.stop=function(){return E&&(clearInterval(E),E=null),G},G.timeInterval=function(a){return arguments.length?(C=null==a?1/0:a,G):C},G.words=function(a){return arguments.length?(B=a,G):B},G.size=function(b){return arguments.length?(a=[+b[0],+b[1]],G):a},G.font=function(a){return arguments.length?(c=v(a),G):c},G.fontStyle=function(a){return arguments.length?(s=v(a),G):s},G.fontWeight=function(a){return arguments.length?(x=v(a),G):x},G.rotate=function(a){return arguments.length?(y=v(a),G):y},G.text=function(a){return arguments.length?(b=v(a),G):b},G.spiral=function(a){return arguments.length?(A=w[a]||a,G):A},G.fontSize=function(a){return arguments.length?(e=v(a),G):e},G.padding=function(a){return arguments.length?(z=v(a),G):z},G.random=function(a){return arguments.length?(F=a,G):F},G.on=function(){var a=D.on.apply(D,arguments);return a===D?G:a},G};var w={archimedean:r,rectangular:s}},{"d3-dispatch":2}],2:[function(b,c,d){!function(b,e){"object"==typeof d&&void 0!==c?e(d):"function"==typeof a&&a.amd?a(["exports"],e):e(b.d3=b.d3||{})}(this,function(a){"use strict";function c(){for(var e,a=0,b=arguments.length,c={};a<b;++a){if(!(e=arguments[a]+"")||e in c)throw new Error("illegal type: "+e);c[e]=[]}return new d(c)}function d(a){this._=a}function e(a,b){return a.trim().split(/^|\s+/).map(function(a){var c="",d=a.indexOf(".");if(d>=0&&(c=a.slice(d+1),a=a.slice(0,d)),a&&!b.hasOwnProperty(a))throw new Error("unknown type: "+a);return{type:a,name:c}})}function f(a,b){for(var e,c=0,d=a.length;c<d;++c)if((e=a[c]).name===b)return e.value}function g(a,c,d){for(var e=0,f=a.length;e<f;++e)if(a[e].name===c){a[e]=b,a=a.slice(0,e).concat(a.slice(e+1));break}return null!=d&&a.push({name:c,value:d}),a}var b={value:function(){}};d.prototype=c.prototype={constructor:d,on:function(a,b){var h,c=this._,d=e(a+"",c),i=-1,j=d.length;{if(!(arguments.length<2)){if(null!=b&&"function"!=typeof b)throw new Error("invalid callback: "+b);for(;++i<j;)if(h=(a=d[i]).type)c[h]=g(c[h],a.name,b);else if(null==b)for(h in c)c[h]=g(c[h],a.name,null);return this}for(;++i<j;)if((h=(a=d[i]).type)&&(h=f(c[h],a.name)))return h}},copy:function(){var a={},b=this._;for(var c in b)a[c]=b[c].slice();return new d(a)},call:function(a,b){if((e=arguments.length-2)>0)for(var e,f,c=new Array(e),d=0;d<e;++d)c[d]=arguments[d+2];if(!this._.hasOwnProperty(a))throw new Error("unknown type: "+a);for(f=this._[a],d=0,e=f.length;d<e;++d)f[d].value.apply(b,c)},apply:function(a,b,c){if(!this._.hasOwnProperty(a))throw new Error("unknown type: "+a);for(var d=this._[a],e=0,f=d.length;e<f;++e)d[e].value.apply(b,c)}},a.dispatch=c,Object.defineProperty(a,"__esModule",{value:!0})})},{}]},{},[1])(1)}); 
     
    
     
    /// ACTUAL START OF ANSWER /// 
     
    
     
    // fake JSON data in place of CSV file. 
     
    
     
    data = [{ 
     
        word: "word1", 
     
        count: 457, 
     
        index: 239 
     
        }, 
     
        { 
     
        word: "word2", 
     
        count: 373, 
     
        index: 155 
     
        }, 
     
        { 
     
        word: "word3", 
     
        count: 76, 
     
        index: -142 
     
        }, 
     
        { 
     
        word: "word4", 
     
        count: 345, 
     
        index: 127 
     
        }, 
     
        { 
     
        word: "word5", 
     
        count: 12, 
     
        index: -206 
     
        }, 
     
        { 
     
        word: "word6", 
     
        count: 46, 
     
        index: -172 
     
        } 
     
    ] 
     
    
     
    // the script 
     
    
     
    
     
        var width = 700, // amended to make result easier to see 
     
         height =400; 
     
    
     
        var wordScale = d3.scale.linear().range([10,100]); 
     
    
     
    // d3.csv("words.csv", function(data) { // uncomment when using CSV 
     
         var subjects = data 
     
          .map(function(d) {return {text: d.word, size: +d.count, in: +d.index} }) // note use of +d.index, to ensure it's held as a number when read from csv, same as +d.count 
     
          .sort(function(a,b) {return d3.descending (a.size, b.size); }) 
     
          .slice(0,100); 
     
    
     
         wordScale.domain([ 
     
          d3.min(subjects, function(d) {return d.size; }), 
     
          d3.max(subjects, function(d) {return d.size; }), 
     
         ]);  
     
    
     
        // var layout = cloud() 
     
         d3.layout.cloud().size([width, height]) 
     
         .words(subjects) 
     
         .padding(1) 
     
         .rotate(function() { return ~~(Math.random() * 2) * 0; }) 
     
         .font("Impact") 
     
         .fontSize(function(d) { return wordScale(d.size); }) 
     
         .on("end", draw) 
     
         .start(); 
     
    
     
    // }); uncomment when using csv 
     
    
     
         function draw(words) { 
     
          d3.select("#word-cloud").append("svg") 
     
           .attr("width",width) 
     
           .attr("height",height) 
     
          .append("g") 
     
           .attr("transform", "translate("+(width /2)+","+(height /2)+")") 
     
           //where the center is 
     
          .selectAll("text") 
     
           .data(words) 
     
          .enter().append("text") 
     
           .style("font-size", function(d) { return d.size + "px"; }) 
     
           .style("font-family", "Impact") 
     
           .style("fill", function(d, i) { return d.in > 0 ? "#00cc66" : "grey" }) 
     
           .style("opacity", function(d) { return d.in > 0 ? d.size/100 : (50 - d.size)/100 }) // bit of a hack to get furthest from index to become darker 
     
           .attr("text-anchor", "middle") 
     
           .attr("transform", function(d) { 
     
           return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")"; 
     
           }) 
     
           .text(function(d) { return d.text; }); 
     
        }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 
     
    <!-- 
     
    word count index 
     
    word1 457  239 
     
    word2 373  155 
     
    word3 76  -142 
     
    word4 345  127 
     
    word5 12  -206 
     
    word6 46  -172 
     
    --> 
     
    <div id="word-cloud"></div>

    +0

    答えてくれてありがとう。 10〜100のスケールで55が0に等しいか?それは平均ではないからです。正しい?上記のコードは単語数で色分けしていますが、インデックスで色を付ける必要があります。もし私がインデックスでそれをやりたいのであれば、次の.map(function(d){return {text:d.word、size:+ d.rate、color:d.index}})を実行してから.append (「テキスト」)。 .style( "opacity"、function(d){return d.color/100})スタイル( "fill"、function(d){return d.color> = 0? "green": "gray";} – jeangelj

    +0

    私はコードを試しましたが、それは平均以上のすべての言葉を(そう正のインデックス)緑にしません。唯一の部分 – jeangelj

    +0

    あなたに戻って時間を取るために謝罪、私は仕事で沼地にされている!あなたが実行できるはずの上記の答えが更新されました。上記の編集と似ています。 –

    関連する問題