基于D3.js實現(xiàn)分類多標(biāo)簽的Tree型結(jié)構(gòu)可視化


關(guān)鍵詞: 可視化,D3.js,python,前端,代碼

0.Why

今天新來的實習(xí)生需要對部分分類文本進(jìn)行多標(biāo)簽的檢測份名,即根據(jù)已構(gòu)建好的一舞蔽、二級標(biāo)簽Excel文檔芥驳,對眾包平臺人工標(biāo)注的數(shù)據(jù)以及機(jī)器標(biāo)注的數(shù)據(jù)進(jìn)行評測。
此情此景谭期,讓我想起了曾經(jīng)在實驗做的文本多標(biāo)簽分類的工作堵第,所以就想用Echart 或D3.js實現(xiàn)層級標(biāo)簽可視化為一個Tree的結(jié)構(gòu),方便實習(xí)生們查閱隧出,提高工作效率踏志。
說干就干!

1.How

1.1 處理數(shù)據(jù)

首先胀瞪,找一個標(biāo)準(zhǔn)的基于D3.js實例程序针余,明確一下我們的工作目標(biāo)以及步驟[數(shù)據(jù)的格式+前端代碼]。
看一下需要將我們目前的結(jié)構(gòu)化數(shù)據(jù):

體育,籃球,NBA
體育,籃球,CNA
體育,籃球,CUBA
體育,足球,中超
體育,足球,歐冠
體育,羽毛球
體育,羽毛球,湯姆斯杯
數(shù)碼,手機(jī),iPhone
數(shù)碼,手機(jī),小米
數(shù)碼,電腦,MacPro
數(shù)碼,電腦,Dell
數(shù)碼,電腦,小米
數(shù)碼,照相機(jī),索尼
數(shù)碼,照相機(jī),尼康
教育,大學(xué),高數(shù)
教育,大學(xué),英語
教育,高中,物理
教育,高中,化學(xué)
教育,高中,生物
教育,小學(xué)
教育,幼兒

標(biāo)準(zhǔn)的可以被D3.js加載的數(shù)據(jù)格式:

加載之后的Tree型結(jié)構(gòu)效果圖:


以上的Tree型圖就是我們想要達(dá)到的目標(biāo)凄诞。

我們需要將我們的數(shù)據(jù)圆雁,轉(zhuǎn)換為D3.js可以加載的標(biāo)準(zhǔn)數(shù)據(jù)。

我決定使用python編寫處理的腳本:

編寫的邏輯完全是自己瞎想的帆谍,如果各位有什么更好伪朽、更標(biāo)準(zhǔn)的方法,歡迎指出汛蝙。

# coding:utf-8
import sys
reload(sys)
sys.setdefaultencoding( "utf-8" )

dic={}

with open("testtag.txt") as f:
    for i in f:
        # print i
        i=i.split(",")
        k=str(i[0]).strip()
        if k not in dic:
            dic[k]=[".".join(i[1:]).strip()]
            # 是為了預(yù)防存在二級標(biāo)簽的缺失
            dic[k].append(str(i[1]).strip())
            # 又不能存在重復(fù)烈涮,使用set去重
            dic[k]=list(set(dic[k]))
        else:
            dic[k].append(str(i[1]).strip())
            dic[k].append(".".join(i[1:]).strip())
            dic[k]=list(set(dic[k]))

with open("3tag.csv","w") as w:
    w.writelines("id,value"+'\n')
    w.writelines("3Tag"+'\n')
    for i in dic.keys():
        w.writelines("3Tag."+i+'\n')
        for j in dic[i]:
            w.writelines("3Tag."+str(i)+"."+str(j).strip()+'\n')

處理之后的結(jié)果存儲到本地的文件3tag.csv中:

一定要完全按照標(biāo)準(zhǔn)的D3.js的格式處理的。

id,value
3Tag
3Tag.體育
3Tag.體育.籃球.CNA
3Tag.體育.足球.中超
3Tag.體育.籃球.CUBA
3Tag.體育.籃球
3Tag.體育.羽毛球
3Tag.體育.足球
3Tag.體育.羽毛球.湯姆斯杯
3Tag.體育.籃球.NBA
3Tag.體育.足球.歐冠
3Tag.教育
3Tag.教育.大學(xué).高數(shù)
3Tag.教育.高中
3Tag.教育.幼兒
3Tag.教育.高中.生物
3Tag.教育.大學(xué)
3Tag.教育.大學(xué).英語
3Tag.教育.高中.物理
3Tag.教育.小學(xué)
3Tag.教育.高中.化學(xué)
3Tag.數(shù)碼
3Tag.數(shù)碼.電腦.MacPro
3Tag.數(shù)碼.手機(jī).小米
3Tag.數(shù)碼.照相機(jī).索尼
3Tag.數(shù)碼.電腦.Dell
3Tag.數(shù)碼.手機(jī).iPhone
3Tag.數(shù)碼.電腦.小米
3Tag.數(shù)碼.手機(jī)
3Tag.數(shù)碼.電腦
3Tag.數(shù)碼.照相機(jī).尼康
3Tag.數(shù)碼.照相機(jī)

注意事項:
正確的數(shù)據(jù):
'''
id,value
3Tag
3Tag.體育
3Tag.體育.籃球
3Tag.體育.籃球.CNA
3Tag.體育.足球.中超
3Tag.體育.足球
'''
1.處理數(shù)據(jù)的過程中要注意窖剑,不允許存在隔級的情況:
eg:
'''
id,value
3Tag
3Tag.體育
3Tag.體育.籃球.CNA
'''
*是錯誤坚洽,必須存在“3Tag.體育.籃球”這一級才可以,否則數(shù)據(jù)加載失斘魍痢讶舰!
2.不允許存在重復(fù)的行數(shù)據(jù),否則加載失敗绘雁!
'''
id,value
3Tag
3Tag.體育
3Tag.體育
3Tag.體育.籃球.CNA
'''

所以橡疼,整個處理的過程中,其實最麻煩的就是數(shù)據(jù)的處理了庐舟。

1.2 前端的Web界面

標(biāo)準(zhǔn)數(shù)據(jù)有了欣除,剩下的就是需要一個前端的web界面,這個代碼在上面的示例頁面中已經(jīng)有了挪略,只需要我們自己替換為我們的數(shù)據(jù)源就可以了历帚,我還是貼出自己的代碼吧。

<!DOCTYPE html>
<meta charset="utf-8">
<style>

.node circle {
  fill: #999;
}

.node text {
  font: 10px sans-serif;
}

.node--internal circle {
  fill: #555;
}

.node--internal text {
  text-shadow: 0 1px 0 #fff, 0 -1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff;
}

.link {
  fill: none;
  stroke: #555;
  stroke-opacity: 0.4;
  stroke-width: 1.5px;
}

form {
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  position: absolute;
  left: 10px;
  top: 10px;
}

label {
  display: block;
}

</style>
<form>
  <label><input type="radio" name="mode" value="cluster" checked> Dendrogram</label>
  <label><input type="radio" name="mode" value="tree"> Tree</label>
</form>

<!-- <iframe   src="http://10.73.20.41/mblog_info_test/library3_quality_mbblog_line_tag_distrib/" width="1300" height="1900"   frameborder="0"  name=""     scrolling="yes">   
</iframe> -->
<svg width="560" height="800"></svg>
<!-- <script src="d3.js"></script> -->
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>

var svg = d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height"),
    g = svg.append("g").attr("transform", "translate(40,0)");

var tree = d3.tree()
    .size([height - 400, width - 160]);

var cluster = d3.cluster()
    .size([height, width - 160]);

var stratify = d3.stratify()
    .parentId(function(d) { return d.id.substring(0, d.id.lastIndexOf(".")); });

d3.csv("3tag.csv", function(error, data) {
  if (error) throw error;

  var root = stratify(data)
      .sort(function(a, b) { return (a.height - b.height) || a.id.localeCompare(b.id); });

  cluster(root);

  var link = g.selectAll(".link")
      .data(root.descendants().slice(1))
    .enter().append("path")
      .attr("class", "link")
      .attr("d", diagonal);

  var node = g.selectAll(".node")
      .data(root.descendants())
    .enter().append("g")
      .attr("class", function(d) { return "node" + (d.children ? " node--internal" : " node--leaf"); })
      .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });

  node.append("circle")
      .attr("r", 5);

  node.append("text")
      .attr("dy", 3)
      .attr("x", function(d) { return d.children ? -8 : 8; })
      .style("text-anchor", function(d) { return d.children ? "end" : "start"; })
      .text(function(d) { return d.id.substring(d.id.lastIndexOf(".") + 1); });

  d3.selectAll("input")
      .on("change", changed);

  var timeout = setTimeout(function() {
    d3.select("input[value=\"tree\"]")
        .property("checked", true)
        .dispatch("change");
  }, 1000);

  function changed() {
    timeout = clearTimeout(timeout);
    (this.value === "tree" ? tree : cluster)(root);
    var t = d3.transition().duration(750);
    node.transition(t).attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });
    link.transition(t).attr("d", diagonal);
  }
});

function diagonal(d) {
  return "M" + d.y + "," + d.x
      + "C" + (d.parent.y + 100) + "," + d.x
      + " " + (d.parent.y + 100) + "," + d.parent.x
      + " " + d.parent.y + "," + d.parent.x;
}
</script>
</body>

2.RESULT

最后杠娱,展示一下我們的成果:


以上就是本次層級標(biāo)簽可視化的實踐挽牢,以后大家工作中再遇到多標(biāo)簽的問題,可以使用該方法快速的實現(xiàn)Tree型結(jié)構(gòu)的可視化了摊求,方便閱讀與理解禽拔。


我的博客即將搬運同步至騰訊云+社區(qū),邀請大家一同入駐:https://cloud.tencent.com/developer/support-plan?invite_code=3mtmis547ccgw

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末室叉,一起剝皮案震驚了整個濱河市睹栖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌茧痕,老刑警劉巖野来,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異踪旷,居然都是意外死亡曼氛,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進(jìn)店門令野,熙熙樓的掌柜王于貴愁眉苦臉地迎上來舀患,“玉大人,你說我怎么就攤上這事彩掐」怪郏” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵堵幽,是天一觀的道長。 經(jīng)常有香客問我弹澎,道長朴下,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任苦蒿,我火速辦了婚禮殴胧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己团滥,他們只是感情好竿屹,可當(dāng)我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著灸姊,像睡著了一般拱燃。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上力惯,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天碗誉,我揣著相機(jī)與錄音,去河邊找鬼父晶。 笑死哮缺,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的甲喝。 我是一名探鬼主播尝苇,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼埠胖!你這毒婦竟也來了茎匠?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤押袍,失蹤者是張志新(化名)和其女友劉穎诵冒,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谊惭,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡汽馋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了圈盔。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片豹芯。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖驱敲,靈堂內(nèi)的尸體忽然破棺而出铁蹈,到底是詐尸還是另有隱情,我是刑警寧澤众眨,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布握牧,位于F島的核電站,受9級特大地震影響娩梨,放射性物質(zhì)發(fā)生泄漏沿腰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一狈定、第九天 我趴在偏房一處隱蔽的房頂上張望颂龙。 院中可真熱鬧习蓬,春花似錦、人聲如沸措嵌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽企巢。三九已至枫慷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間包斑,已是汗流浹背流礁。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留罗丰,地道東北人神帅。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像萌抵,于是被迫代替她去往敵國和親找御。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容