我创建了一个基于csv的d3.js单词云。
在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的world cloud的帮助下),它可以创建“云”这个词,但我不知道如何根据索引更改单词的颜色。
<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谢谢!
更新:
根据Dan的回答尝试了以下内容,但使用了索引:
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; });
}不幸的是,当我运行它时,没有显示任何内容(也没有错误消息)。
发布于 2017-04-12 00:01:37
对于上面的代码,即假设wordScale在10到100之间:
在绘制函数中,在代码的.append("text")部分,
编辑填充函数如下所示。由于尺寸高于/低于中点(55),这将变成绿色/灰色。可以随意使用比下面硬编码的颜色值更好的颜色值:
.style("fill", function(d) { return d.size >= 55 ? "green" : "grey";})要满足您的其他请求,请在fill下面添加以下样式。这将设置相对于大小的不透明度(介于0.1到1之间)。同样,您可以根据需要调整这些值。
.style("opacity", function(d) { return d.size / 100 })如果进行这些编辑,还可以将var fill放在代码的顶部。
更新答案:
注意,我无法让Jason在没有脚本错误的情况下远程加载,但没有时间进行调试。在他的脚本后面向下滚动以获得实际答案。我也没有添加任何旋转元素到这个。
/*
* 提示:该行代码过长,系统自动注释不进行高亮。一键复制会移除系统注释
* !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>
https://stackoverflow.com/questions/43356274
复制相似问题