たれぱんのびぼーろく

わたしの備忘録、生物学とプログラミングが多いかも

バイオ・ニューロのジャーナルたち

(ジャーナル)インパクト・ファクターと、各紙に受ける印象

  • neuron: 14.0; 憧れる。様々な実験系で文句なく立証する感じ。
  • nコミュ: 12.1; 案外見かけない。まとまった仕事が多い印象
  • PNAS: 9.7; 良い仕事が多い!ってイメージ。技術開発系とか、手堅い発見系とかの印象
  • Current Bio: 8.9; 良い仕事多い!イメージ。新規性のある発見な印象?
  • eLife: 7.7; オープンアクセス。最近見かけるようになったなぁ、なイメージ
  • JNS: 6.0; 渋い仕事が多い。少なめの実験系でぐぐっと堅く示してく印象?
  • SciRep: 4.3; 玉石混交。これはなぁ…って論文をちらほら見かける、うーんあんま好きくない
    1. Comp. Neuro: 3.3; その情報が欲しかった!!が頻発。Scienceしてる、好印象。
    1. Neurophys.: 2.4; 一本槍でざくっと、なイメージ。地味で良い仕事、的な。

d3.jsとデータの書き換え

入力値やインタラクションの結果をデータとグラフに反映する仕組みはd3.jsに備わっているのか否か

結論

d3.jsには双方向バインディングに該当する仕組みがない.
dataの取得・更新とrebinding、rebinding後の更新が必要. うーむ

There's no data-binding magic à la angular that's going to trigger a "redraw". Just call .data and then re-set the attributes
javascript - How to update bound data in d3.js? - Stack Overflow

SVGのtextをその場で書き換える

下のtext要素をクリックしてごらん、なんと編集できるよ!!
私はtext要素。でも編集できるよ! (クリックしてみ)

わかる人向け: 仕組みを一言でいうと

contentEditableなHTML要素の下にtext要素を配置し、このセットをforeignObjectへ入れてSVG要素下に吊るす.

仕組み

contentEditable

HTML5にはcontentEditableという属性がある。

<div contenteditable>編集可能</div>

のように属性を付与すると、

divが編集可能 (クリックしてみ)

になる.

SVGのcontentEditable

contentEditableがSVGで使えれば万々歳、なのだが、使えない...
(次のSVGに導入しようぜ、という提案はされてたりする Add `contenteditable` attribute for SVG text elements · Issue #332 · w3c/svgwg · GitHub)

\\動かない例
<svg>
 <text contenteditable>SVGは編集不可 (クリックしても無駄無駄、無駄ァ)</text>
</svg>

SVGは編集不可 (クリックしても無駄無駄、無駄ァ)

しかし嬉しいことに、contentEditableなHTML要素の下にSVG要素を配置すると, contentEditableが引き継がれる https://github.com/w3c/svgwg/issues/332 (標準化された動作じゃない...と思う)
なので

<div contenteditable>
  <text>divに入れるとSVGを編集可能</text> // SVGのtext要素
</div>

とすると、

divに入れるとSVGを編集可能 (クリックしてみ)

になる.
やったねたえちゃん、SVGが編集できるよ

foreignObject

ここで問題になるのが<svg>下のHTML要素.
おそらくこのページに来た人は、SVGで作りこんだ図に編集可能textを入れ込みたいのだと思う.
つまり、<svg>要素下にrectやらcircleやら置いてあることになる.
textを編集可能にするために、上記の<div contenteditable>を利用すればよいわけだが...
<svg>下にHTML要素(例えば<div>)を置くことはできない javascript - How to append div tag into a SVG rect element? - Stack Overflow
そこで登場するのがforeignObject.
この要素を配置するとあら不思議、HTML要素をforeignObject下に配置しても無問題!!
よって

<svg>
 <foreignObject>
   <div contenteditable>
     <text>私はtext要素。でも編集できるよ! (クリックしてみ)</text>
   </div>
 </foreignObject>
</svg>

のようにすれば、
私はtext要素。でも編集できるよ! (クリックしてみ)

となる。

問題点

  • contentEditableはあくまでHTML属性
    • SVGの仕様で定められた、互換性のあるものではない
  • foreignObject要素への対応
    • 一部のブラウザでforeignObject要素を適切に処理できない場合があるとかないとか

まとめ

  • foreignObject下にcontentEditable HTML要素、その下にtextを置けば編集できる
  • 互換性などの点でベストとはとても言い難いよ、でも便利だね

おまけ

d3.jsと組み合わせると

HTML, non-contentEditable
HTML contentEditable
HTML, non-contentEditable. But enabled by d3.js!!
<div id="divv2">HTML, non-contentEditable. But enabled by d3.js!!</div>
d3.select("#divv2").attr("contenteditable", true);

d3.select("#svgEdit")
  .append("foreignObject")
    .attr("width", 600)
    .attr("height", 50)
    .append("xhtml:div")
      .attr("contenteditable", true)
      .append("text")
        .text("dynamic editable text by d3.js!!!");

Javascriptの日時 (date & time)

Javascript標準で日時を扱うにはDateオブジェクトを使う.
使い方は割と簡単で、いくつか問題点はあるけどとりあえず使う分にはまぁ

概要

こんな風になっている
f:id:tarepan5884:20170910222214p:plain

inputはローカル時間 (日本時間とかアメリカ時間とか。時差のようなもの) の情報を持っているが、気にせずDateオブジェクトに入れてしまう.
Dateオブジェクトがローカル時間を良い感じに扱ってくれ、内部ではローカル時に影響されないUnix時間という時間表現で時間を保持している.
Dateオブジェクトから日時情報を取り出す際には様々な書式を設定でき、ISO8601表記や、月(month)のみの取り出しなどが出来る.ローカル時間に合わせた表記ももちろんできるよ、優秀!

  • input:
    • コンストラクタ: new Date(args)
    • setter: dateObj.setMonth()など
  • internal: Unix時間
  • output:
    • 全情報
      • Unix時間: Date.getTime()
        • => 1505049236671
      • 地域時間: Date.toLocaleString()
        • => "2017/9/10 22:48:41"
      • ISO8601-UTC: Date.toISOString()
        • => "2017-09-10T13:48:41.083Z"
      • ISO8601-localTime: なんと、無い!!
      • JSON用: Date.toJSON()
    • 個別の年、月、日など
      • dateObj.getMonth(): 月(month)のみ返してくる
      • etc.etc.

コンストラクタや各種setter, getterはググれば簡単にわかる。上記の全体像が大事.

良く上げられる問題点

  • getterの返り値が直感的ではない
    • 1月が"0"で返ってくる。ゆえに9月は8!! ミスリーディング!!
  • 実装依存の部分が非常に多い
    • 仕様書を見る限り、最近はかなり標準化されているみたい
    • 古いブラウザ使うなら機能豊富なライブラリを使うべし
  • ISO8601のローカル時間表記が出来ない
    • ローカルにかかわる情報もってんだろおんどれ、もうちとがんばれ!!

オブジェクト内部の時間表現

以下は興味のある人向け

Dateオブジェクト内ではUnix時間で日時が表現されている.

A Date object contains a Number indicating a particular instant in time to within a millisecond. Such a Number is called a time value. A time value may also be NaN, indicating that the Date object does not represent a specific instant of time.
Time is measured in ECMAScript in milliseconds since 01 January, 1970 UTC.
https://www.ecma-international.org/ecma-262/6.0/#sec-time-values-and-time-range
https://www.ecma-international.org/ecma-262/7.0/#sec-time-values-and-time-range
* ECMAScript 2015 ~ 2018-draft まで 20.3.1.1Time Values and Time Range に変更なし

ECMAScript仕様

(ECMAScript 2015, 2016, 2017, 2018-draft)
20.3 Date Objects (https://tc39.github.io/ecma262/#sec-date-objects)にて詳しく規定

変更履歴

language specification 20.3をdiff

2015 -> 2016

20.3.1.16 Date Time String Formatだけ変更点がありそう
ほかは表記上の変更のみにみえる

2016 -> 2017

20.3.3.4に変更点

2017 -> 2018-draft

20.3.4.41-42に大幅変更?

内部動作

DateValue internal slotが全ての肝.
DateValueはDateインスタンスの持つ内部時間表現。Unix時間(1970-01-01T00:00zからの経過ミリ秒)で表現されている.
コンストラクタもsetterも、いろいろな入力をUnix時間へ変更してDateValueに入れる仕事をしている.
getterはどれもUnix時間を適切な出力フォーマットへ変換する仕事をしている.

読み解くのに重要な内部関数

thisTimeValue(value)  
/*
 * @argument {Object} value - argument object
 * @return {?} - value.[[DateValue]] || Type Error exception
 */
// 20.3.4

"this time value"は thisTimeValue(this)の返り値 (20.3.4)
Date prototype objectはDateValue internal slotを持たない(20.3.4)
インスタンスが初期化されたとに DateValue == time valueになるもよう (20.3.4)

20.3.1.15 TimeClip (time): time => NaN || parseInt(time)

MakeDate() -> TimeClip(UTC(finalDate)) -> DateValue
ほとんどのsetterでは、setterコール時にUnix時間からYear等を再計算し、setterの引数と再計算値を用いて(internalな)MakeDate()を行ってUnix時間へ再変換してる.

DNAコンストラクトを入手する

\115 = $1とする

mermaid.jsでガントチャートを書く

mermaid.jsには様々な機能がある。その中でもガントチャート機能に着目した。

mermaid.jsガントチャートの特徴

  • 利点
  • 欠点
    • 拡張性なし (モジュールAPIなど)
    • タスクの依存先は1つのみ (and条件などは無理)
    • 公式docが整備不十分

そもそも論だが、ガントチャートは依存関係を書く機能を有するグラフなのか?

#

mermaid.js対応エディタがたくさんあるみたいで、彼らを使うのも手かも?

mermaid.jsのatomエディタ拡張、これはぐぅ神.
github.com

本家

レポジトリ
github.com

gitbook, readme代わり
mermaid · GitBook
特にgantt部分
Gantt diagram · GitBook

なんとlive editorが!
https://mermaidjs.github.io/mermaid-live-editor/#/edit/c2VxdWVuY2VEaWFncmFtCkEtPj4gQjogUXVlcnkKQi0+PiBDOiBGb3J3YXJkIHF1ZXJ5Ck5vdGUgcmlnaHQgb2YgQzogVGhpbmtpbmcuLi4KQy0+PiBCOiBSZXNwb25zZQpCLT4+IEE6IEZvcndhcmQgcmVzcG9uc2UK

関連記事

色設定の仕方
qiita.com

簡単な使い方
qiita.com

後で読む
作図系ツール・ライブラリまとめ · GitHub

ガントチャートjsライブラリ
magnet88jp.hateblo.jp
blog.htmlhifive.com

plantuml.com

google chart
Gantt Charts  |  Charts  |  Google Developers

内部解析

ガントチャートソース
mermaid/src/diagrams/gantt at master · knsv/mermaid · GitHub

Jisonとやらでparserを作製・js化している模様。

ganttRenderer.js
mermaid/ganttRenderer.js at master · knsv/mermaid · GitHub
こいつがガントチャート部の肝その1。
exportしてるオブジェクトは

  • setConf: configを渡すとganttRenderer内部のconfigを更新
  • draw: 描写

のみ。
draw()の中ではひたすら愚直にd3.jsで要素を作っている。健気だ…
draw()内では本当にrenderingしかしておらず、依存関係に基づいたstart-time計算などはされていない。parser側かな?
gantt.yy.getTasks()でtaskArrayを取得している。このgetTasks()があやしい

ganttDb.js内のgetStartDate()が鍵だった。
“after"を正規表現で検出し、依存タスクの時間関係をDateにコンパイルしている。こうすれば後は描写するだけ
mermaid/ganttDb.js at master · knsv/mermaid · GitHub

d3.jsのバージョンは3.5.17で固定 (package.jsonより mermaid/package.json at master · knsv/mermaid · GitHub )。やっぱり古くからのライブラリはv4に移行しづらいよな。

draw

annotation by myself

/**
 * Draw gantt chart
 * @param {string} text - gantt data, which will be parsed soon
 * @param {string} id - id of something HTML object
 * @returns {void}
 */
function draw(text, id){}

text引数は (“./parser/gantt”).parser.parse()で即座にパースして終わり。
id引数はgetElementByIdでelemを出すために即使用して終わり.

構造まとめ

parser => "after" compiler => draw (d3.js)