mkyyyyy777のブログ

対戦よろしくおねがいします!

D3.jsを使ってみたよ

棒グラフ

f:id:mkyyyyy777:20210822002141p:plain
棒グラフ

コード全体

function display(count1, count2) {
  // グラフのwidth, height
  const width = window.innerWidth / 3;
  const height = 400;
  const axisHeight = 20;
  const axisWidth = 25;

  const svg = d3
    .select('#count')
    .append('svg')
    .attr('width', width)
    .attr('height', height);

  const xScale = d3
    .scaleBand()
    .domain(count1.map((d) => d.date))
    .range([axisWidth, width - axisWidth]);

  const yScaleCoun1 = d3
    .scaleLinear()
    .domain([
      0,
      d3.max(count1, (d) => {
        return d.count;
      }),
    ])
    .range([height - axisHeight, axisHeight]);

  const yScaleCount2 = d3
    .scaleLinear()
    .domain([
      0,
      d3.max(count2, (d) => {
        return d.count;
      }),
    ])
    .range([height - axisHeight, axisHeight]);

  svg
    .append('g')
    .attr('transform', `translate(0,${height - axisHeight})`)
    .call(d3.axisBottom(xScale));

  svg
    .append('g')
    .attr('transform', 'translate(' + (width - axisWidth) + ',' + 0 + ')')
    .call(d3.axisRight(yScaleCount1));

  svg
    .append('g')
    .attr('transform', 'translate(' + axisHeight + ',' + 0 + ')')
    .call(d3.axisLeft(yScaleCount2));

  svg
    .selectAll('rect1')
    .data(count1)
    .enter()
    .append('rect')
    .attr('x', (d, i) => {
      return xScale(d.date) + xScale.bandwidth() / 3 + xScale.bandwidth() / 6;
    })
    .attr('y', (d) => {
      return yScaleCount1(d.count);
    })
    .attr('height', (d) => {
      return height - axisHeight - yScaleCount1(d.count);
    })
    .attr('width', xScale.bandwidth() / 3)
    .attr('fill', '#66FFFF');

  svg
    .selectAll('rect2')
    .data(count2)
    .enter()
    .append('rect')
    .attr('x', (d, i) => {
      return xScale(d.date) + xScale.bandwidth() + xScale.bandwidth() / 6;
    })
    .attr('y', (d) => {
      return yScaleCount2(d.count);
    })
    .attr('height', (d) => {
      return height - axisHeight - yScaleCount2(d.count);
    })
    .attr('width', xScale.bandwidth() / 3)
    .attr('fill', '#FFCC99');
}

引数

function display(count1, count2) {
count1 = [
    {date: 8月13日, count: 14},
    {date: 8月14日, count: 2},
    {date: 8月15日, count: 8},
                 .
                 .
                 .
]

count2も同じ

グラフの大きさの設定

  // グラフのwidth, height
  const width = window.innerWidth / 3; // グラフの幅(下記図の赤)
  const height = 400;                  // グラフの高さ(下記図の赤)
  const axisHeight = 20;               // x軸を表示する高さ (図の青)
  const axisWidth = 25;                // y軸を表示する幅   (図の黄色)

f:id:mkyyyyy777:20210822005113p:plain
図のwidthとheight

svgタグを指定したidに追加

  const svg = d3
    .select('#count') // id=count を持つタグを選択
    .append('svg')                          // 選択したタグにsvgタグを追加
    .attr('width', width)                   // 追加したsvgタグのwidthとheightを設定
    .attr('height', height);

scaleの設定(与えられた値に対して正規化とかをやってくれる)

  const xScale = d3
    .scaleBand()                                 // 軸の種類の選択(多分) 他にもscaleLinear()などがある 
    .domain(count1.map(d => d.date))           // arrayを渡すとうまく設定してくれ
    .range([axisWidth, width - axisWidth]);

     
=> わかりやすく   const scale = d3.scaleLinear().domain([100, 500]).range([10, 350]);   // 正規化をうまくしてくれる
ex 
scale(100);  // 10 が戻る
scale(300);  // 180 が戻る
scale(500);  // 350 が戻る

scale参照1
scale参照2

軸を設定する

  svg
    .append('g')                                                // gでgタグを追加
    .attr('transform', `translate(0,${height - axisHeight})`)   // 軸の場所を設定(0, height-axisHeight)に軸が現れる
    .call(d3.axisBottom(xScale));                               // 軸の下にラベルを付ける axisLeftなら軸の左にラベルを

図形を描写する

  svg
    .selectAll('rect1')   // rect1タグを選択 (rect1タグはないので何も選択されない) nullでもいい
    .data(count)      // データを設定
    .enter()              
    .append('rect')       // 長方形(Rectangle)タグを追加 -> rectタグを検索
    .attr('x', (d, i) => {
        return xScale(d.date) + xScale.bandwidth() / 3 + xScale.bandwidth() / 6; // rectタグのx軸を設定(xScale.bandwidth()はxScaleから計算された長方形の幅)
    })
    .attr('y', (d) => {
      return yScaleCount1(d.count);                       // x軸と同様にy軸を設定
    })
    .attr('height', (d) => {
      return height - axisHeight - yScaleCount1(d.count); // 長方形の高さを設定
    })
    .attr('width', xScale.bandwidth() / 3)              // 長方形の幅を設定
    .attr('fill', '#66FFFF');                           // 長方形の色を設定

円グラフ

大体は棒グラフとおなじ、内円とかの設定が円グラフでは必要

f:id:mkyyyyy777:20210822004110p:plain
円グラフ

コード全体

function display(majorRateCount) {
  const width = window.innerWidth / 3; // グラフラスの幅
  const height = 450; // グラフの高さ
  const radius = Math.min(width, height) / 2 - 10;

  // 割合計算
  const total = majorRateCount.reduce((result, d) => {
    console.log(d);
    return result + d.count;
  }, 0);
  majorRateCount.forEach((element) => {
    element.rate = element.count / total;
  });

  // SVG領域の設定
  const svg = d3
    .select('#circle')
    .append('svg')
    .attr('width', width)
    .attr('height', height);

  // chartを真ん中へ
  const g = svg
    .append('g')
    .attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')');

  // カラーの設定
  const color = d3
    .scaleOrdinal()
    .range(['#DC3912', '#3366CC', '#109618', '#FF9900', '#990099']);

  // pieチャートデータセット用関数の設定
  const pie = d3.pie().value(function (d) {
    return d.count;
  });

  // pieチャートSVG要素の設定
  const pieGroup = g
    .selectAll(null)
    .data(pie(majorRateCount))
    .enter()
    .append('g')
    .attr('class', 'pie');

  const arc = d3.arc().outerRadius(radius).innerRadius(0);

  pieGroup
    .append('path')
    .attr('d', arc)
    .attr('fill', (d) => {
      return color(d.index);
    })
    .attr('opacity', 0.5)
    .attr('stroke', 'white')
    .attr('stroke-width', '0.5px');

  // pieチャートテキストSVG要素の設定
  const text = d3
    .arc()
    .outerRadius(radius - 30)
    .innerRadius(radius - 30);

  pieGroup
    .append('text')
    .attr('fill', 'black')
    .attr('transform', (d) => {
      return `translate(${text.centroid(d)})`;
    })
    .attr('font-size', '12px')
    .attr('text-anchor', 'middle')
    .text((d) => {
      return d.data.major + ' ' + Math.round(d.data.rate * 100) + '%';
    });
}

引数

majorRateCount = [
    {
        "major": "Python",
        "count": 3,
    },
    {
        "major": "C++",
        "count": 1,
    },
    {
        "major": "Go",
        "count": 2,
    },
    {
        "major": "JavaScript",
        "count": 2,
    },
]