Findbugs PMD集計結果をグラフ描画したくなり、
d3.js ベースの何かでちょうど良いのがない探したところ、
django-nvd3いうライブラリがありましたので、
それを使用してデータを描画してみます。


目次


インストールと設定

Github README.rst従ってインストールします。
areski/django-nvd3: Django wrapper for nvd3 - It’s time for beautiful charts

1 . pip使用して install

  • commnad

    pip install django-nvd3
    

  • output

    Successfully installed Jinja2-2.8 Unidecode-0.4.19 django-nvd3-0.9.7 python-nvd3-0.14.2 python-slugify-1.1.4
    

2 . node.js install

django-bowerインストールする必要があり、
それが node.js依存しているため、そちらもインストールします。

3. bower install

  • グローバルオプション付きで install

    npm install -g bower
    

  • インストール先を確認

    which bower
    

  • output

    /usr/local/bin/bower
    


4. django-bower を install

  • command
    pip install django-bower
    

5. django-bowerの設定

  • 参考サイト 以下の手順で設定可能です。 https://github.com/nvbn/django-bower

  • settings.py に djangobower追加

    INSTALLED_APPS = [
        'djangobower',
        'django_extensions',
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
    ]
    

  • settings.py にdjango-bower の設定を追加

    ################################
    # Django-bower settings
    ################################
    STATICFILES_FINDERS = [
        'djangobower.finders.BowerFinder',
        'django.contrib.staticfiles.finders.FileSystemFinder',
        'django.contrib.staticfiles.finders.AppDirectoriesFinder',
    ]
    
    BOWER_COMPONENTS_ROOT = BASE_DIR + '/components/'
    
    BOWER_INSTALLED_APPS = (
        'nvd3',
    )
    

  • bower_install コマンドを実行

    python manage.py bower_install
    

  • collectstatic コマンドを実行

    python manage.py collectstatic
    

コマンドを実行したら、

  File "/v3.4.3/lib/python3.4/site-packages/django/contrib/staticfiles/storage.py", line 48, in path
    raise ImproperlyConfigured("You're using the staticfiles app "
django.core.exceptions.ImproperlyConfigured: You're using the staticfiles app without having set the STATIC_ROOT setting to a filesystem path.

STATIC_ROOTないといわれたので、settings.py に追加

STATIC_ROOT = BASE_DIR + '/sitestatic/'

6. django_nvd3をsettings.pyに追加

INSTALLED_APPS = [
    'libs',
    'analyze_pmd_rules',
    'analyze_findbugs_rules',
    'analyze_github_base',
    'analyze_metrics_view',
    'django_nvd3',
    'djangobower',


サンプルを実装

1. BOWER_INSTALLED_APPS の設定

README.rst記載がなかったので記載しておきます。

BOWER_INSTALLED_APPS = (
    'd3',
    'nvd3',
)

2. templatetagsの書き換え

django-nvd3まだ、最新のnvd3.jsに対応できていないようです。
少し修正すれば、動くかと思って、修正を試みましたが、
ちょっと簡単には直らなそうで修正はあきらめました。
(訂正) 2. templatetagsの書き換え

参考までに、うまくいかなかった方法も以下に記載したままにします。


Github README.rstサンプルを、実装しました。
サンプルの記述は README.rst使いましたが、以下のエラーが発生して、
動作しませんでした。

(index):33 Uncaught TypeError: chart.tooltipContent is not a function(anonymous function) @ (index):33c @ nv.d3.js:99

Github Issueして上がっていますが、
chart.tooltipContent chart.tooltip.contentGenerator読み替えないと
動作しないようです。

対象箇所をStackOverFlowの記載に従って修正しました。

  • content.html

       chart.tooltip.contentGenerator(function(key, y, e, graph) {
            var x = String(graph.point.x);
            var y = String(graph.point.y);
            {{ chart.tooltip_condition_string }}
    

  • piechart.html

        chart.tooltip.contentGenerator(function(key, y, e, graph) {
              var x = String(key);
                  {{ chart.tooltip_condition_string }}
                  tooltip_str = '<center><b>'+x+'</b></center>' + y;
                  return tooltip_str;
                  }); 
    


(訂正) 2. templatetagsの書き換え

上記の修正後に、動作確認したところ、Tooltipうまく表示されませんでした。
メソッド名だけでなく、引数も変わっていて、やすやすと修正できるものじゃなさそうだったので、
NVD3のVesrionを1.7にすることで対応しました。

  • 参考記事 javascript - nvd3 piechart.js - How to edit the tooltip? - Stack Overflow

  • NVD3 1.7.1 をインストールのためまずVersionを確認する。

    bower info nvd3 
    

  • output

    Available versions:
      - 1.8.4
      - 1.8.3
      - 1.8.2
      - 1.8.1
      - 1.7.1
      - 1.2.1
      - 1.2.0
    

  • BOWER_INSTALLED_APPS の変更

    BOWER_INSTALLED_APPS = (
        'd3',
        'nvd3#1.7.1',
    )
    

  • 再インストール

    python manage.py bower_install
    

  • 再起動後に動作確認したらJAVASCRIPTエラー
    1.7.1 にしても、JAVASCRIPTエラーが発生します。
    どうも、‘README.rst’ のサンプル記述に間違いがあるようで、
    chartdata に、 ‘extra1’ を追加することで、解消しました。

    extra_serie = {"tooltip": {"y_start": "", "y_end": ""}}
    charttype = "pieChart"
    chartdata = {'x': xdata, 'y1': ydata, 'extra1': extra_serie}

3. その他はまったところ

  • SVGcontaierID大文字が含まれるとグラフが描画されない。

Templagete側で、以下の記述のように、 containerID指定する必要がありますが、status_of_use.chartcontainer 記述のことです。

{% load_chart status_of_use.charttype status_of_use.chartdata status_of_use.chartcontainer status_of_use.extra %}
.....
<div class="col-lg-offset-3">{% include_container status_of_use.chartcontainer 400 600 %}</div>
python側で、大文字を含むID指定したところ、グラフが描画されなくなりました。
      xdata = ["Using", "Not using"]
      ydata = [findbugs_file_count, repository_count - findbugs_file_count]
      chartdata = {'x': xdata, 'y1': ydata, 'extra1': extra_serie}
      chartcontainer = 'status_of_use_findbugs_Piechart'
      data = {
          'charttype': charttype,
          'chartdata': chartdata,
          'chartcontainer': chartcontainer,
          'extra': {
              'x_is_date': False,
              'x_axis_format': '',
              'tag_script_js': True,
              'jquery_on_ready': True,
          }
      }

展開された HTML Javascript確認したところ、
javascript 側は小文字に変換されているのに対して、

    d3.select('#status_of_use_findbugs_piechart svg')
    .datum(datum)
    .transition().duration(500)
    .attr('height', 450)
    .call(chart);

HTML側は、変換される大文字のままで出力されていました。

<div class="col-lg-offset-3"><div id="status_of_use_findbugs_Piechart"><svg style="width:600px;height:400px;"></svg></div>


なんとかサンプルが動作するところまで、持っていけました。
pieChart 以外のexample実装もこちらあります。
直接 NVD3使用するよりも、バリエーションは少なくなるとは思いますが、
ラップしている言語をかければなんとかなるので直接グラフライブラリを使用するよりも、
良いのかもしれません。
Javaなんかのテンプレートエンジン使った こういったライブラリがあると仕事的には良いのですが。。

以上です。

コメント