LoginSignup
10
7

More than 5 years have passed since last update.

Gvizでマインドマップを作成してみた

Last updated at Posted at 2014-09-15

Gviz Gemのインストール

$ gem install gviz 

Graphvizのインストール(MacOSXの場合)

$ brew update
$ brew install graphviz

参考記事:

tbpgr様
「Ruby | Gvizでインデント構造のテキストをグラフに変換する」
http://qiita.com/tbpgr/items/770d56834103efe2b723
「Ruby | Gvizでインデント構造のテキストをマインドマップに変換する」
http://qiita.com/tbpgr/items/7ba662f77b110e9ad0be

ありがとうございます。

マインドマップの生成

mindmap.rb
# coding: utf-8

require 'familyable'   # https://github.com/tbpgr/tbpgr_utils
require 'gottani_core' # https://github.com/tbpgr/gottani
require "gviz"

text =<<-EOS
Rails
  レール
    DRY
      同じことを繰り返さない
    CoC
      設定より規約
  テスト
    TDD
      RSpec
        2.99
          factoryGirl
        3.00
          gemの依存に困っている
        spec_helper
      Cucumber
        RailsテストCucumber+Capybara+Poltergeist
          http://qiita.com/ryosy383/items/d4c10ffed3dd22e3153a
        カピバラ
          カピバラ属唯一の種
    CI/CA
      Jenkins
        青くなる・赤くなる
        カバレッジ
        豊富なプラグインを入れる
        デプロイ
  その他
    Rubocop
      リファクタリング
      コーディング規約調整係
      名前が気になる(ルボコップ?)
EOS

# 以下、ソースコードは、
# Author: tbpgr様
# Qiita記事: http://qiita.com/tbpgr/items/7ba662f77b110e9ad0be

sp2 = Gottani::Space2.new
indent_text = sp2.space2_to_common(text)

indexed_indent_text = indent_text.reverse.map.with_index { |e, i|e.merge({id: i}) }

module Familyable
  class Person
    attr_accessor :value, :level
  end
end

i = 0
persons = indexed_indent_text.reduce([]) do |persons, person|
  parent = indexed_indent_text[(i + 1)..-1]
  .find { |e|e[:level] == person[:level] - 1 }
  parent_ids = parent.nil? ? [] : [parent[:id]]
  person = Familyable::Person.new(id: i, parent_ids: parent_ids).tap do |e|
    e.value = person[:value]
    e.level = person[:level]
  end
  persons << person
  i += 1
  persons
end

sorted_persons = persons.reverse
family = Familyable::Family.new(family: persons)

Graph do
  global layout:'twopi', overlap:false, splines: :curved
  nodes fontname:'MS GOTHIC', shape: :none, style:'filled'
  edges dir: :none
  # ノードの定義
  sorted_persons.each { |person|node :"person#{person.id}",  { label: person.value } }

  # エッジの定義
  sorted_persons.each do |person|
    parents =  family.get_parents(person)
    next if parents.empty?
    parent = parents.first
    options  = {}
    options[:penwidth] = 6 if parent.level == 0
    edge :"person#{parent.id}_person#{person.id}", options

  end

  # *** 根のランク, スタイル定義 ***
  min_id = persons.find { |e|e.level == 0 }.id
  min_person_key = :"person#{min_id}"
  rank :min, [min_person_key]
  node min_person_key, { shape: 'pentagon', fontsize: 80, fillcolor: :red }

  # *** 根以外のノードのランク定義 ***
  ranked_persons = sorted_persons.group_by { |e|e.level }.select { |key, value|key.nonzero? }
  ranked_persons.each do |rank, each_rank_persons|
    each_rank_persons.map { |e|node :"person#{e.id}", { fontsize: 40 } } if rank == 1
    persons = each_rank_persons.map { |e|"person#{e.id}".to_sym }
    rank(:same, persons)
  end

  save :"givz_mindmap", :png
end

生成したマインドマップ

givz_mindmap.png

10
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
7