カテゴリー
IT programming wordpress

TablePressのセルの値によって背景の色を動的に変える方法

wordpressのプラグインTablePressにて、セルの値に応じて、動的にセルの色を変える方法について考えます。

目的と背景

https://1-10000th.com/how-to-change-color-of-html-table/

上記の記事は、HTMLのテーブルのセルの値によって背景の色を動的に変える方法(特にセル内の順位付け)についてのものですが、当該記事にて下記のコメントをいただきましたので、実際にこのブログ(wordpress)内で試してみます。

はじめまして。

ワードプレスでTablePressというプラグインを使っているのですが、記事のようにセルの背景を動的に変えたいのですが、可能でしょうか?

具体的には入力した数字の範囲(40〜50は赤、51〜60は青といった具合です。)で、指定した色が自動で振り分けられるようにしたいです。

wordpressにおけるTablePressのCSSセレクタの確認

まずはTablePressをプラグインで検索してインストール。その後、TablePressで適当にテーブルを作って記事に張り付けたのが以下です。

ABCDE
23423431433234
234343-2
0432-33
132232242
233232424
44353344
gd3243242432
dfg434a
443454
434234d52

このテーブルをブラウザのデベロッパーツールで確認しますと、tableタグのIDは”tablepress-1“(ハイフン以降の数字はTablePressのテーブルIDだと思われます)、そして1列目に”column-1“、2列目に”column-2“などが入るようです。

セルの値の順位にで背景に色をつけるjavascriptの実装

それでは、このテーブルの情報がわかりましたので、Javascriptを適用します。

TablePressのすぐ下に「カスタムHTML」に下記のコードを入力して挿入します。以前の記事からの変更点は、最後の列のセレクタ名(#tablepress-1 .column-1の部分)だけです。

<script>
// tableに色を塗る
    function setcolor(classname) {
      var rank = $(classname);

      var arr = [];
      $.each(rank, function(_, v) {
        var num = parseFloat($(v).text());
        if (num) {
          arr.push(num);
        }
      });

      // 一番大きい
      var first = Math.max.apply(Math, arr);

      // 一番大きいのを配列から削除
      arr = arr.filter(function(x) {
        return x != first
      });

      // 2番目に大きい
      var second = Math.max.apply(Math, arr);

      // 2番大きいのを配列から削除
      arr = arr.filter(function(x) {
        return x != second
      });

      // 3番目に大きい
      var third = Math.max.apply(Math, arr);

      // 3番大きいのを配列から削除
      arr = arr.filter(function(x) {
        return x != third
      });

      // 4番目に大きい
      var fourth = Math.max.apply(Math, arr);

      // CSSをつける
      $.each(rank, function(_, v) {
        var num = parseFloat($(v).text());
        if (num == first) $(v).css('background-color', '#FFC0CB');
        if (num == second) $(v).css('background-color', '#FFCC99');
        if (num == third) $(v).css('background-color', '#C0F0FF');
        if (num == fourth) $(v).css('background-color', '#E6E6FA');
      });
    }

    setcolor("#tablepress-1 .column-1"); // テーブルの列のCSS(1列目)
    setcolor("#tablepress-1 .column-2"); // テーブルの列のCSS(2列目)
    setcolor("#tablepress-1 .column-3"); // テーブルの列のCSS(3列目)
    setcolor("#tablepress-1 .column-4"); // テーブルの列のCSS(4列目)
    setcolor("#tablepress-1 .column-5"); // テーブルの列のCSS(5列目)
</script>

そしてプレビューしますと下記のようになりきちんとCSSが反映されています。

ABCDE
23423431433234
234343-2
0432-33
132232242
233232424
44353344
gd3243242432
dfg434a
443454
434234d52

最近(?)のwordpressでは、カスタムHTML等でコードっぽいのを記入する際に、勝手に「&」や「<」みたいな特殊文字を「&lt;」や「&amp;」に変換してしまうようです。これではコードを正確に読み込んでくれませんので、なんとかする必要があります。今回も、なぜかnum = 50 は動くのに、num < 50にすると何故か動かなくなり、結構悩みました。

解決方法の詳細は私は詳しくはGoogle先生で「wordpress 特殊文字 変換させない」あたりで検索してください。

私は、テーマのfunctions.php(テーマエディターから)に

add_filter( "run_wptexturize", "__return_false" );

と書いたら無駄に変換されなくなりました。自己責任で。

セルの値によって背景に色をつけるjavascriptの実装

ご質問のような、ランクによる色付けでなく、単に値による色付けであればより簡単で、セルの値をループする際に、if文でCSSをつけてあげればOKです。

下記がサンプルコードです。関数名が上とかぶらないようにsetcolor2にしています。同じようにTablePressのすぐ下に「カスタムHTML」に下記のコードを入力して挿入。

<script>
// tableに色を塗る
    function setcolor2(classname) {
      var rank = $(classname);

      // CSSをつける
      $.each(rank, function(_, v) {
        var num = parseFloat($(v).text());
        if (40 <= num && num < 50) $(v).css('background-color', '#FFC0CB');
        if (50 <= num && num < 60) $(v).css('background-color', '#FFCC99');
      });
    }

    setcolor2("#tablepress-1 .column-1"); // テーブルの列のCSS(1列目)
    setcolor2("#tablepress-1 .column-2"); // テーブルの列のCSS(2列目)
    setcolor2("#tablepress-1 .column-3"); // テーブルの列のCSS(3列目)
    setcolor2("#tablepress-1 .column-4"); // テーブルの列のCSS(4列目)
    setcolor2("#tablepress-1 .column-5"); // テーブルの列のCSS(5列目)
</script>

結果以下のような感じ(40~50、50~60で分岐)。

ABCDE
23423431433234
234343-2
0432-33
132232242
233232424
44353344
gd3243242432
dfg434a
443454
434234d52

課題

今回の手法は、テーブルが静的である場合に限り有効です。何らかのタイミングでテーブルが更新される場合、javascriptの実行を再度行わないといけないことに注意です。

そういう意味も含めて、TablePressは今回初めて使いましたので、実は何か他のより良い方法があるかもしれません。特に、TablePressはdatatablesと連携が取れるようなプラグインっぽいので、例えばdatatablesのdrawcallbackのようなことが実装できれば、動的なテーブルにも応用できるかとは思います(でも https://datatables.net/forums/discussion/57707/use-datatables-in-tablepress-to-create-sports-cup-standings のコメントによればできないっぽいかな?)。

カテゴリー
IT programming

エックスサーバー上でPythonのCGIを使用したJSONの送受信(Ajax)を行う

前回の記事を参考に、エックスサーバー上でPythonのCGIに対して、JSONの送受信をテストしたいと思います。

前回の記事はこちら。

https://1-10000th.com/python-cgi-500error/

やりたいこと

PythonをCGIにして、WEBページ(Javascitpt+Ajax)からJSONを送信して、Pythonで受信して加工して、JSONを返して、WEBページで表示する。

具体的には、WEBページ(tashizan.html)から入力xと入ちょくyを、Python(response.py)にAJAXでPOST送信して、Python内で足し算して、その結果をWEBページに戻す。

WEBページのコード(tashizan.html)

bootstrap4とjQueryを使用しています。

<!doctype html>
<html lang="ja">

<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

    <title>Python + Ajax</title>
</head>

<body>
    <div class="container">
        <h1>PythonとAjaxで足し算するよ</h1>
        <form>
            <div class="form-group">
                <label for="x">x</label>
                <input type="number" class="form-control" id="x" placeholder="">
            </div>
            <div class="form-group">
                <label for="y">y</label>
                <input type="number" class="form-control" id="y" placeholder="">
            </div>
            <div class="form-group">
                <label for="answer">answer ( x + y )</label>
                <input type="number" class="form-control" id="answer" placeholder="" readonly>
            </div>
        </form>
    </div>

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
    <script>
        $(function() {

            //keyup()でキーを入力するたびに発動
            $('input[type="number"]').keyup(function() {

                //リクエスト
                let request = {
                    x: $("#x").val() ? $("#x").val() : "0",
                    y: $("#y").val() ? $("#y").val() : "0",
                };

                console.log(request);

                url = "response.py"

                $.ajax({
                    type: "POST",
                    url: url,
                    data: JSON.stringify(request),
                    dataType: "json",
                    success: function(data) {
                        $('#answer').val(data['answer']);
                    },
                    error: function(XMLHttpRequest, textStatus, errorThrown) {
                        console.log("ERROR:\n" + url + "\n" + textStatus + ":\n" + errorThrown);
                    }
                });
            });
        });
    </script>

</body>

</html>

Pythonのコード(response.py)

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import sys
import json

data = sys.stdin.read()
params = json.loads(data)

# 数字かどうかを判断する関数
def is_num(s):
    try:
        float(s)
    except ValueError:
        return False
    else:
        return True

# 数字以外のものが飛んできたらとりあえず弾く
if is_num(params['x']) and is_num(params['y']): 

    result = {'answer': float(params['x']) + float(params['y'])}

    print("Content-type: application/json")
    print("\n\n")
    print(json.JSONEncoder().encode(result))
    print('\n')


結果

https://1-10000th.com/python-cgi/tashizan.html

注意点

  • 改行コードをLFにする(超重要)。
  • pythonファイルは権限を705もしくは755にする。
  • .htaccessにAddHandler cgi-script .pyを書く。

補足

なお、WEBページを経由せずに、SSH等でpythonプログラムの動作を確認するには、下記のようにしてpythonプログラムに、パイプでJSONを渡すことができる模様(sys.stdin.read()を使用しているので)。

JSONのキーもバリューもダブルクオテーションで囲むこと。

$ echo '{"x": "-12.5", "y": "64.3"}' | ./response.py 

実行結果↓

Content-type: application/json



{"answer": 51.8}

カテゴリー
IT programming

Javascriptによる円と直線の交点の座標の計算(ベクトルの知識必要なしver)

中学生で習う範囲で、ベクトルを使わずに、円と直線の交点を算出するプログラムを書いてみます。

目的

Javascriptによる円と直線の交点の計算

円の中心座標 $(h,k)$ と半径 $r$ と直線の式 $y=mx+n$ が与えられている時、円と直線の交点(上記図の緑の点の座標)を求めたいと思います。

アルゴリズム

円の方程式は下記の通りとする。

$$(x-h)^{2}+(y-k)^{2}=r^{2}$$

直線の方程式は下記の通りとする。

$$y=mx+n$$

ここで、直線の式の $y$ を円の方程式に代入すると下記になり、

$$(x-h)^{2}+(mx+n-k)^{2}=r^{2}$$

カッコを展開すると下記になる。

$$x^{2}-2xh+h^{2}+m^{2}x^{2}+2mx(n-k)+(n-k)^{2}=r^{2}$$

この式を形を解の公式: $x=\frac{-b\pm\sqrt{b^2-4ac}}{2a}$ が使えるように、適当にカッコでくくり、 $r^{2}$ を左に持ってくると下記になる。

$$(1+m^{2})x^{2}+(-2h+2m(n-k))x+h^{2}+(n-k)^{2}-r^{2}=0$$

ここで下記のとおりにする。

$a=1+m^{2}$

$b=-2h+2m(n-k)$

$c=h^{2}+(n-k)^{2}-r^{2}$

上記を使うと、上記の式は下記になる。

$$ax^{2}+bx+c=0$$

よって、解の公式から答え $x$ が導き出せる。

$x$ が出れば $y=mx+n$ に代入して $y$ がでる。

なお、下記のように置くと

$$D=b^{2}-4ac$$

$D$ の値によって、下記のように答えが分かれる。

$D>0$ の場合は答えが2つでる(つまり2点で交わる)。

$D=0$ の場合は答えが1つでる(つまり1点で交わる。直線が円の接線となる)。

$D>0$ の場合は答えが2つでる(交わらない)。

以上。

プログラム(javascript)

これをJavascriptで記述すると下記のとおりになる(交点座標を返す関数)。

//////////////////////////////
// 円の方程式は (x - h)^2 + (y - k)^2 = r^2
// 線の方程式は y = m * x + n
// r: 円の半径
// h: 円の中心のx座標
// k: 円の中心のy座標
// m: 直線の傾き
// n: 直線の切片
//////////////////////////////
function kouten(r, h, k, m, n) {
  var a = 1 + Math.pow(m, 2);
  var b = -2 * h + 2 * m * (n - k);
  var c = Math.pow(h, 2) + Math.pow((n - k), 2) - Math.pow(r, 2);
  var D = Math.pow(b, 2) - 4 * a * c;

  var kouten = [];
  if (D >= 0) {
    var x1 = (-b + Math.sqrt(Math.pow(b, 2) - 4 * a * c)) / (2 * a);
    var x2 = (-b - Math.sqrt(Math.pow(b, 2) - 4 * a * c)) / (2 * a);
    if (D == 0) {
      //Dがゼロなら、1点だけが答え
      kouten.push({ x: x1, y: m * x1 + n});
    } else {
      //Dがゼロより上なら、2点が答え
      kouten.push({ x: x1, y: m * x1 + n});
      kouten.push({ x: x2, y: m * x2 + n});
    }
  }
  return kouten;
}

実行結果(jsfiddle)

適当にボタンを何回かクリックしてください。ランダムで円と直線が現れて、交差していれば、赤い文字で交点の座標が表示されます。

カテゴリー
IT programming

ベルトランのパラドックスがよく理解できるJavascriptシミュレーターの作成

2020/10/25更新
シミュレータに重大なバグが有りましたので修正いたしました。
表示される確率が、Case1とCase2で逆でした(致命的ミスで申し訳ございません)。

ベルトランのパラドクス(ベルトランの逆説)というものがあります。超簡潔に言えば「ランダム」ってなんだ?という「確率の定義」に関する話です。今回はJavascriptでシミュレータを作りました。

ベルトランのパラドックスとは

とある円とそれに内接する正三角形がある。この円のランダムに弦を引いたとき、弦が正三角形の1辺よりも、長くなる確率はいくらか。

   ベルトランの逆説

という問題がベルトランのパラドクス(ベルトランの逆説 / Bertrand paradox)です。

結論から言うと、答えは3つあり、「ランダムな弦の引き方」によって、1/21/31/4、というものです。

一体どの答えが正解なのか・・・ということです。

3つの答えについて

case:1 (答えが1/3になる考え方)

The “random endpoints” method:

円周上に、ランダムに位置する2点を定め、弦を引く場合。この場合に答えが1/3になる。

ベルトランの逆説

case:2 (答えが1/2になる考え方)

The “random radial point” method:

円の半径をランダムに選んで、その半径上にランダムで点(つまり極座標でいうところの、rθがランダム)を定め、その点を通り、半径に垂直な弦を引く場合。この場合に答えが1/2になる。

ベルトランの逆説

case:3 (答えが1/4になる考え方)

The “random midpoint” method:

円の内部にランダムに点を定め、その点が中点となるような弦を引く場合。この場合に答えが1/4になる。

ベルトランの逆説

理論的になぜそうなるのか

理論的な計算方法やその解説はベルトランの逆説 – Wikipedia等のわかりやすいサイトでご確認ください!

実際にそうなるのか

Javacriptシミュレーター

というわけで、実際に上記3パターンでプログラムを組んだ場合に、本当にそのとおりの確率になるのか調べるためにプログラムをJavascriptで作りました。

https://1-10000th.com/bertrand_paradox/

使い方・仕様

ランダムな弦の数、アニメーション速度、弦の太さ、弦の中点の点の半径、各種カラーを設定して、スタートを押します。スマホにも対応しています。

著作権とか

授業とかで自由に使っていただいて結構です(ただし、デバッグはあまりしていません)。コメントいただけると私が喜びます。

結果 | Case1: The “random endpoints” method

弦を2000本Case1の方法でランダムに引いた結果です。0.33350という数字が確率です。

左の円が弦を表示、右の円が弦の中点をプロットしたものです。

結果 | Case2: The “random radial point” method

弦を2000本Case2の方法でランダムに引いた結果です。0.50850という数字が確率です。

左の円が弦を表示、右の円が弦の中点をプロットしたものです。

結果 | Case3: The “random midpoint” method

弦を2000本Case3の方法でランダムに引いた結果です。0.24000という数字が確率です。

左の円が弦を表示、右の円が弦の中点をプロットしたものです。

結果の比較

全部一気に表示すると上記になりました。

学問的な考察は省略しますが、図に注目してもらうと、円に「ランダムに弦を引く」という目的に対し、それぞれ偏りがあることがあることがわかると思います。

ぜひ、シミュレータページで試してください。

まとめ

ものすごく大雑把に言うと、「ランダムに弦を引く」という問題は、実は問題として曖昧(学問的に言うと「確率空間の定義が曖昧」)で、場合によっては確率は変わってしまいますよ。ですから確率を見るときは、場合によってはちゃんと条件(確率空間)を確認してね!ということです。おそらく!

ちなみに、ベルトランの逆説 – Wikipediaにによれば、後にジェインズさんという頭の良い方が、「拡大縮小と移動の両方に関しての不変性を考えると、これの答えはCase2だよ!」という論文が出たそうです。ご興味があれば調べてみたら面白いかも。

Javascriptのソースコードの説明はまた機会があったら。

カテゴリー
IT programming

カーボンナノチューブにおけるカイラル指数(カイラルベクトル、カイラリティ)とは

カーボンナノチューブの構造を理解する上で、いちばん重要なのがカイラル指数だそうです。カイラル指数はカイラルベクトルとも、chirarily(カイラリティ:螺旋度)とも呼ばれます。

今回は、3D nanotube viewer(3D ナノチューブビューアー)を使って、実際にカイラル指数を入力し、そのCNTの構造を見ていきたいと思います。

3D nanotube viewerはこちら。ブラウザからアクセスできます。

https://1-10000th.com/nanotubeviewer/

3D nanotube viewerの説明はこちら。

https://1-10000th.com/3d-nanotube-viewer/

カイラル指数とは

カイラル指数とは、いわゆるカーボンナノチューブの構造を決定するパラメーター(≒ 巻き方)のことで、2つの数字の組み合わせ(Cn, Cm)によって、カーボンナノチューブの性質が変わるらしいのです(3種類:アームチェア型ジグザグ型カイラル型)。 ただ、詳しいことは、Google先生に聞いてください。下の図は3種類のカーボンナノチューブを並べたものです。

3D nanotube viewer

 

なお、超簡単に言いいますと、カイラル指数とは、カーボンナノチューブを展開したときの六員環の縦横比的なもの (角度的なもの?) で、この数値がカーボンナノチューブの螺旋具合に関与します(より重要な話では、カイラル指数によって見た目の螺旋具合だけでなく電気的特性が変わるのですが、その話はまた今度)。詳しいことは、Google先生に聞いてください。下の図は、グラフェン上にカイラル指数の概念を乗せたものです。矢印の方向にカーボンナノチューブを巻いていくという理解でほぼあっていると思います。

カイラルベクトル

 

とりあえず重要なことはカーボンナノチューブの見た目は、このカイラル指数のみによって決定するということです。

具体的に3D Nanotube Viewerにアクセスして見ていきましょう。

三種類のカーボンナノチューブ

アームチェア型(armchar)

下記画像は、カイラル指数(5,5)のカーボンナノチューブです。下記わかりやすいようにFOG(霧)エフェクトをかけて、奥行きをなんとなく表現しています。

カイラルベクトル
カイラル指数(5,5)

 

下図は見る角度を変えたときのアームチェア型の図。わかりやすいように原子に色を付けています。

カイラル指数(9,0)

このように、カイラル指数CnとCmが等しい場合、アームチェア型のカーボンナノチューブと呼ばれます。なぜアームチェア型と呼ばれるのかはよくわかりませんが、見た目が椅子っぽいのでしょうかね。 六員環の配置が横にまっすぐ直線ですね。

ジグザグ型(zigzag)

また、下記画像は、カイラル指数(9,0)のカーボンナノチューブです。

カイラル指数
カイラル指数(9,0)

 

下図は見る角度を変えたときのジグザグ型の図。わかりやすいように原子に色を付けています。

カイラル指数(9,0)

このように、カイラル指数Cmがゼロの場合、ジグザグ型カーボンナノチューブと呼ばれます。確かに画像を見るに、横から見たら六員環の配置がジグザグですね。

カイラル型(chiral)

また、下記画像は、カイラル指数(7,3)のカーボンナノチューブです。

カイラリティ
カイラル指数(7,3)

 

下図は見る角度を変えたときのカイラル型の図。わかりやすいように原子に色を付けています。

カイラル指数(7,3)

このように、カイラル指数CnとCmが等しくなく、Cmがゼロでない場合、カイラル型カーボンナノチューブと呼ばれます。確かに横からの画像を見るに、六員環の配置が斜めってますね。

 

以上、3Dナノチューブビューアを使用した3つのカーボンナノチューブの紹介でした。

https://1-10000th.com/nanotubeviewer/

カテゴリー
IT programming

ブラウザで表示できるカーボンナノチューブ用の3Dビューアーの作成(WebGL・Javascript)

なにかと世間で話題のカーボンナノチューブ(通称:CNTs)ですが、論文、ポスター発表、授業等で、カーボンナノチューブの構造やイメージを説明したいとき、丁度いいカーボンナノチューブのイメージ図・画像がなくて困っていませんでしょうか?

困っています。少なくとも私は。

ということで、カーボンナノチューブの構造を3Dでそれっぽく表示するWEBページを作りました。

WEBページ自体はこちら。

https://1-10000th.com/nanotubeviewer/

自分好みのカーボンナノチューブの絵が欲しかった

自由に使えて、自分の都合の良い形・向きのカーボンナノチューブの絵なんてなかなか手に入らないです。人の論文から勝手に持ってきては怒られてしまいますし。。。

例えばこのようなもの(カーボンナノチューブ – Wikipediaより)


User Mstroeck on en.wikipedia – Originally from en.wikipedia; description page is (was) here 23:30, 1 February 2006 Mstroeck 2024×1846 (2,043,648 bytes) (A diagram showing the types of carbon nanotubes. (Created by Michael Ströck (mstroeck) on February 1, 2006. Released under the GFDL). The (n,m) nanotube naming scheme can be thought of as a vector (Ch) in an infinite graphene sheet that describes how to) 22:49, 1 February 2006 Mstroeck 1986×1756 (2,027,400 bytes) (A diagram showing the types of [[:en:carbon nanotubes]]. (Created by Michael Ströck (mstroeck) on February 1, 2006. Released under the GFDL). The (n,m) nanotube naming scheme can be thought of as a vector (Ch) in an infinite graphene sheet that describes ho) 22:40, 1 February 2006 Mstroeck 1986×1756 (1,989,910 bytes) (A diagram showing the types of carbon nanotubes. (Created by Michael Ströck (mstroeck) on February 1, 2006. Released under the GFDL). The (n,m) nanotube naming scheme can be thought of as a vector (Ch) in an infinite graphene sheet that describes how to) Version of 22:51, 1 July 2007 uploaded on behalf of en:User:Ma Baker. Lucasbfr 22:56, 1 July 2007 (UTC), CC 表示-継承 3.0, リンクによる

 

上記はCNTの立体構造を説明するのに非常にわかりやすい画像ですが、これと同じような画像を、パっと簡単に描くのは難しいものです。一度、真面目に考えてみればわかるのですが、構造を理解して、カーボンナノチューブの絵を描くのは案外難しいのです。しかもカーボンナノチューブにいくら詳しくても、3Dグラフィックス技術に詳しいとは限りません。むしろそんな人は激レアなわけです。

ということで、そんな「カーボンナノチューブの絵がほしい!」と思ったときのために、ブラウザ上で自分の好きな角度、好きなカイラル指数でカーボンナノチューブの三次元画像を作ることのできる「3D Nanotube Viewer」を試作しましたということです。

仕様

3D Carbon Nanotube

できること

  • カイラル指数を指定したのち、そのカイラル指数によって構成されるカーボンナノチューブを三次元ブラフィックで表示します。
  • 背景の色や、炭素(sphere)や炭素をつなぐ棒(cylinder)の色、材質、大きさなど、ある程度変えることができます。
  • フラーレンもある程度表示できます。
  • グラフェンもある程度表示できます。
  • 複数のカーボンナノチューブ、フラーレン、グラフェンも理論上表示できます(重いですが)。
  • 画像に出力できます。

注意点

PCの性能、およびプログラムの稚拙な仕様のために、原子数によっては、かなり負荷がPCにかかります。おおよそ、画面に表示される原子数が1000を超えると厳しいんではないかと思います。もし画面がフリーズしたら、CTRL+ALT+DELETEからブラウザを落としてください。

プログラム言語など

WebGLという技術を用いて、すべてJavascriptで記述しています。

3D Carbon Nanotube

作られた画像の著作権について

もちろん作られた画像の著作権は完全フリーです!ポスターでもプレゼンでも授業でも書籍でも、特別な著作権表記なしで自由に使っていただければとおもいます。ただ、このブログにコメントいただけると私が喜びます。

3D Carbon Nanotube

使い方

スマートホンでも対応していますが、できればPCでのアクセスを推奨します。

  1. 3D Nanotube Viewerにアクセスして「Start」を押します。。
  2. カイラル指数(Cn, Cm)を入力します。
  3. 「Add CNT」を押します。

あとは適当に画面のインターフェースから使い方を感じながら操作します。

3D Carbon Nanotube

というわけで、カイラル指数とその構造の関係を説明するときなど、簡単な授業やイベントぐらいには使えるはずですので、ぜひ使ってみてください!

カテゴリー
IT programming

HTMLのテーブルのセルの値によって背景の色を動的に変える方法(最大値、第2位、第3位など)

いろいろ探しても案外なかったので作成。あんまり需要がないんですかね?DataTables | Table plug-in for jQueryに標準であればうれしかったんですけども。

目的

HTMLのテーブル(tableタグ)において、特定の列について値の順位(最大値、2番めに大きな値、3番めに大きな値・・・)によって、セルの背景の色を動的に変える方法を考える。

つまりは、下記画像のような、セルの値によって、1位(一番大きい値)は赤、2位はオレンジ、3位はブルー、4位はパープルという色を自動でつけたいということ。

HTML TABLE CHANGE COLOR

なお、セルに数字以外の値が入っていても対応することを目指す。165.4cmのように単位が入っていてもOKにする。「不明」などの文字列や空白は無視するものとする。

Javascriptのアルゴリズム

  1. 対象となる列のtdに特定のclassをつける。
  2. classオブジェクトを取得。
  3. javascriptの配列に入れる
  4. 配列内の最大値を取得(第1位の値)
  5. 配列内から最大値を削除して配列を更新
  6. 配列内の最大値を取得(第2位の値)
  7. 配列内から最大値を削除して配列を更新
  8. 配列内の最大値を取得(第3位の値)
  9. 配列内から最大値を削除して配列を更新
  10. 配列内の最大値を取得(第4位の値)
  11. classオブジェクトをループして、各値と一致していたらそのオブジェクトにCSS(色)を追加

ソースコードと使い方

Javascriptの関数は以下の通り。jQuery使用。使い方は、対象のtdにclassを付けて、setcolor(class名)する。

    function setcolor(classname) {
      var rank = $(classname);

      var arr = [];
      $.each(rank, function(_, v) {
        var num = parseFloat($(v).text());
        if (num) {
          arr.push(num);
        }
      });

      // 一番大きい
      var first = Math.max.apply(Math, arr);

      // 一番大きいのを配列から削除
      arr = arr.filter(function(x) {
        return x != first
      });

      // 2番目に大きい
      var second = Math.max.apply(Math, arr);

      // 2番大きいのを配列から削除
      arr = arr.filter(function(x) {
        return x != second
      });

      // 3番目に大きい
      var third = Math.max.apply(Math, arr);

      // 3番大きいのを配列から削除
      arr = arr.filter(function(x) {
        return x != third
      });

      // 4番目に大きい
      var fourth = Math.max.apply(Math, arr);

      // CSSをつける
      $.each(rank, function(_, v) {
        var num = parseFloat($(v).text());
        if (num == first) $(v).css('background-color', '#FFC0CB');
        if (num == second) $(v).css('background-color', '#FFCC99');
        if (num == third) $(v).css('background-color', '#C0F0FF');
        if (num == fourth) $(v).css('background-color', '#E6E6FA');
      });
    }

parseFloatで、例えば156.4cmとかあっても、156.4というfloat型になる。parseFloatで数字にならなければ、配列に入れないものとする。

書く人が書けば、もっときれいでスッキリしたコードになるのだと思いますが、とりあえずわかりやすさを大事に。

実際の動きを確認(jsfiddle)

下記のとおりです。同順位、空白、数字以外、数字+文字を確認してください。