BETA

ポ〇モン風のツールチップを作ってみた(d3.js)

投稿日:2019-06-11
最終更新:2019-06-12

はじめに

突然ポケモン風のツールチップを作ってみようと思ったので作ってみました。
d3のバージョンはv4です。バージョンによって書き方が違うのでご注意ください。
グラフのデータはこちらを使用させていただきました。参考にしたデザインは「ポケットモンスターブラック2・ホワイト2」の体力ゲージです。こちらのサイトを参考にしました。

完成品

qtyは数量(quantity)、Rateは割合です。

コード

ツールチップの全コードは以下になります。

var width = 300,  
    height = 60;  


var tooltip = d3.select("body")  
    .append("svg")  
    .attr("class", "tooltip_pokemon")  
    .style("position", "absolute")  
    .style("z-index", 10)  
    .attr("width", width)  
    .attr("height", height*1.2)  
    .style("background","rgba(0,0,0,0.5)")  
    .style("border","2px")  
    .style("border-radius","8px")  
    .style("opacity",0);  


// 土台  
const base_size = { "width": width, "height": height * 3 / 5 };  
var base = tooltip.append("polygon")  
    .attr("transform", function () {  
        return "translate(" + 0 + ", " + (height * 2 / 5) + ")";  
    })  
    .attr("points", (base_size.height * 2 / 7 + "," + 0 + " " +  
        0 + "," + base_size.height * 3 / 7 + " " +  
        base_size.height * 4 / 7 + "," + base_size.height + " " +  
        (base_size.width - base_size.height * 2 / 7) + "," + base_size.height + " " +  
        base_size.width + "," + base_size.height * 2 / 7 + " " +  
        (base_size.width - base_size.height * 2 / 7) + "," + 0 + " ")  
    )  
    .attr("stroke", "#000")  
    .attr("fill", "#303030");  


// バー  
const bar_size = {"width": width/2 , "height": base_size.height/3};  
var bars = tooltip.append("g")  
    .attr("transform", function () {  
        return "translate(" + (width*2/5) + ", " + (height*2/5) + ")";  
    });  

bars.append("rect")  
    .attr("x", 0).attr("y", 0)  
    .attr("width", bar_size.width)  
    .attr("height", bar_size.height)  
    .attr("fill","#000")  
    .attr("rx",2);  

var bar_scale = d3.scaleLinear().domain([0, 100]).rangeRound([0, bar_size.width]);  
var tooltip_bar = bars.append("rect")  
    .attr("x", 0).attr("y", bar_size.height*1/6)  
    .attr("width", bar_scale(90))  
    .attr("height", bar_size.height*2/3)  
    .attr("fill","#00ff22")  
    .attr("stroke","rgba(40,40,40,0.8)")  
    .style("stroke-width",3)  
    .attr("rx",2);  


// テキストを追加する  
//Rate  
tooltip.append("text")  
    .attr("transform", function () {  
        return "translate(" + (width*2/5 - 5) + ", " + (height*2/5 + bar_size.height) + ")";  
    })  
    .attr("font-weight","bold")  
    .attr("font-size",bar_size.height*1.4)  
    .attr("font-family","arial black")  
    .style("text-anchor","end")  
    .attr("font-style","oblique")  
    .attr("fill","white")  
    .attr("stroke-width",1)  
    .attr("stroke","#000")  
    .text("Rate");  
//qty  
tooltip.append("text")  
    .attr("transform", function () {  
        return "translate(" + (width*4/5) + ", " + (height*2/5-5) + ")";  
    })  
    .attr("font-weight","bold")  
    .attr("font-size",height/3)  
    .attr("font-family","arial black")  
    .style("text-anchor","end")  
    .attr("fill","#fdd040")  
    .attr("stroke-width",1)  
    .attr("stroke","#000")  
    .text("qty");  

var tooltip_quantity = tooltip.append("text")  
    .attr("transform", function () {  
        return "translate(" + (width*4/5+3) + ", " + (height*2/5-5) + ")";  
    })  
    .attr("font-weight","bold")  
    .attr("font-size",height*2/5)  
    .attr("font-family","arial black")  
    .style("text-anchor","start")  
    .attr("fill","white")  
    .attr("stroke-width",1)  
    .attr("stroke","#000")  
    .text("qty");  

var tooltip_name = tooltip.append("text")  
    .attr("transform", function () {  
        return "translate(" + (height*3/7) + ", " + (height*2/5-5) + ")";  
    })  
    .attr("font-weight","bold")  
    .attr("font-size",height*2/5-5)  
    .attr("font-family","arial black")  
    .style("text-anchor","start")  
    .attr("fill","white")  
    .attr("stroke-width",1)  
    .attr("stroke","#000")  
    .text("Name");  

var tooltip_rate = tooltip.append("text")  
    .attr("transform", function () {  
        return "translate(" + (width*9/10) + ", " + (height*8/9) + ")";  
    })  
    .attr("font-weight","bold")  
    .attr("font-size", (base_size.height-bar_size.height)*0.9)  
    .attr("font-family","arial black")  
    .style("text-anchor","end")  
    .attr("fill","white")  
    .attr("font-style","oblique")  
    .attr("stroke-width",1)  
    .attr("stroke","#000")  
    .attr("letter-spacing",5)  
    .text("rate / 100");  


function bar_set(name, qty, rate){  
    tooltip_name.text(name);  
    tooltip_quantity.text(qty);  
    tooltip_rate.text(Math.round(rate) +"/ 100");  

    tooltip_bar.attr("width", bar_scale(rate))  
        .attr("fill", function(){  
            if(rate>=50){  
                return "#00ff22";  
            }else if(rate>=20){  
                return "#cda040";  
            }else{  
                return "#cc2222";  
            }  
        });  
}  

使い方

呼び出したいときに以下の処理をおこなってください。

//データの名前,データの個数,割合  
bar_set(name, quantity, rate);  
tooltip.style("opacity", "1");  

非表示にしたい場合は上のopacity0にするだけで大丈夫です。

コードの解説

記事が長くなるため割愛しますが、簡単な説明はhatenaにてログで残しています(こちら)。

ちなみに



値によって色が変わるようになっています。アニメーションの処理はいれていないですが、入れるとゲージの動きがそれっぽくなると思います。

さいごに

作ったくせに変ですが、文字の表示が安定せずツールチップのサイズにかなり依存すると思うので実用性には全然向かないと思います(少なくとも今のところは)。

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

@syakooのブログ

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう