4

次のデータがあります。

my %col1 = ( 'foo' => 1,
             'bar' => 1 );

my %col2  = ('foo' => ['cat1','cat1','cat2'],
             'bar' => ['cat3','cat2','cat3'] );

my %col3  = ('foo' => [2.3,1.2,1.0],
             'bar' => [7.4,4.3,2.2]);

私がやりたいのは、このようなHTMLテーブルを作成することですが、4番目の列にはグラデーションカラーの形状が含まれています. 色の濃さは のスコアで与えられcol3ます。形状は単純な箇条書きにすることもできます (• HTML: •)

foo cat1,cat1,cat2 2.3,1.2,1    
bar cat3,cat2,cat3 7.4,4.3,2.2

下の図は、私がやろうとしていることを示しています。 ここに画像の説明を入力

各色カテゴリ (列 3) の強度は 1 ~ 10 の範囲です。

それについて行く最善の方法は何ですか?

私が問題を抱えている重要な点は、HTML テーブルを作成することではなく、それを行うことができるということです。しかし、グラデーション カラーを使用して HTML ベースの形状を作成する方法については、さらに詳しく説明します。

私は次のコードで立ち往生しています:

foreach my $nm (keys %col1) {
   my @cats = @{$col2{$nm}};
   my @vals = @{$col3{$nm}};

   print $nm, " ", join(",",@cats), " " ,join(",",@vals), "\n";
}
4

1 に答える 1

4

私があなたの質問を正しく理解していれば、色のグラデーションのある形は本当に必要ありません。本当に必要なのは、次の 2 つのパラメーターによって色が決定される無地のオブジェクトです。

  • カテゴリ (この例では cat1、cat2、cat3)
  • 着色の程度 (列 3 の重み)

さらに、あなたの例の色は、小さい数字が白に近く、大きい数字が黒に近く、中央の数字が飽和色であるモデルに従っているようです。色空間に関しては、これは、ウィキペディアのこの写真に示されているように、色相、彩度、明度の色空間のようなものを示唆しています。

HSL 色空間の描写

これを上記の例に戻すと、0.0 に近い重みは二重円錐の上部近くにあり、10.0 に近い重みは二重円錐の下部近くにあり、カテゴリによって表される色は色相が固定されていると思われます。これらの重みによって調整される彩度(概念的にはダブルコーンの赤道付近)。

次の perl コードは、HSL カラーを RGB に変換します。これは、この StackOverflow answer から改作されました。これは、上でリンクしたウィキペディアのページから改作されました。これは、必要なソリューションの一部にすぎません。

##  
##  Converts an HSL color value to RGB. Conversion formula
##  adapted from http://en.wikipedia.org/wiki/HSL_color_space.
##  Assumes h, s, and l are contained in the set [0, 1] and
##  returns r, g, and b in the set [0, 255].
##  
##  @param   Number  h       The hue
##  @param   Number  s       The saturation
##  @param   Number  l       The lightness
##  @return  Array           The RGB representation
##  
sub hsl_to_rgb
{
    my ($h, $s, $l) = @_;
    my ($r, $g, $b);

    if ($s == 0)
    {
        $r = $g = $b = $l; ## achromatic
    } else
    {
        sub hue2rgb
        {
            my ($p, $q, $t) = @_;

            while ($t < 0) { $t += 1;                                   }
            while ($t > 1) { $t -= 1;                                   }
            if ($t < 1/6)  { return $p + ($q - $p) * 6 * $t;            }
            if ($t < 1/2)  { return $q;                                 }
            if ($t < 2/3)  { return $p + ($q - $p) * (2/3 - $t) * 6;    }
            return $p;
        }

        my $q = $l < 0.5 ? $l * (1 + $s) : $l + $s - $l * $s;
        my $p = 2 * $l - $q;
        $r = hue2rgb($p, $q, $h + 1/3);
        $g = hue2rgb($p, $q, $h);
        $b = hue2rgb($p, $q, $h - 1/3);
    }

    return [ int($r * 255), int($g * 255), int($b * 255) ];
}

この関数は、(0, 1.0, 0.5)純粋な赤などの形式で HSL カラーを取得し、形式の RGB トリプレットを返します[ 255, 0, 0 ]。これで、パズルの 1 ピースが得られます。

問題の説明からわかることに基づいて、カテゴリ別にソートされた、色相と彩度の観点からおそらく表現できる基本色のセットがあります。このようなもの:

my %cat_colors = 
(           #   Hue   Saturation
    cat1 => [ 0.00000, 1.00000 ],   # Red
    cat2 => [ 0.16667, 1.00000 ],   # Yellow
    cat3 => [ 0.33333, 1.00000 ],   # Green
);

OPによる更新:これは素晴らしいです。より多くのカテゴリに色を追加する場合、「色相」の値は次の Web サイトで確認できます: http://www.color-hex.com/。たとえば、この Web サイトでは、赤の HSL が : であると述べていることに注意してください0.00 1.00 0.50

注: これらの色を試してみたいと思うことは間違いありません。Photoshop や、さまざまな色空間で色を表示できるその他のツールを使用している場合は、各カテゴリの「ベース」カラーを正確に選択するのに役立ちます。上記のhsl_to_rgbコードでは、色相と彩度の値を [0, 1] の範囲にスケーリングする必要があります。

これを上で指定した重みパラメーターにどのように適用しますか? 上で述べたように、HSL の明度パラメータに直接マッピングされているように見えます。ウェイト 0.0 は白にマッピングされ、ウェイト 10.0 は黒にマッピングされます。(少なくとも、あなたのスケッチを考えると、それは良い出発点のように思えます。) ただし、HSL では、1.0 は白で、0.0 は黒です。したがって、重量を明度にマッピングするには、次のような式が必要です。

$lightness = 1 - ($weight / 10);

これを関数でラップできます:

sub weight_to_light
{
    return 1 - ($_[0] / 10);
}

hsl_to_rgb式の最後の部分は、 によって返された RGBを HTML が処理できるものにマッピングすることです。それは実際には非常に簡単です。次の短い関数は、R、G、B 値の配列をhsl_to_rgbHTML 対応の 16 進数文字列に変換します。

sub rgb_to_html_hex
{
    return sprintf "#%.2X%.2X%.2X", @{ $_[0] };
}

つまり、すべてをまとめると、上記のカラーリング モデルに従ってオブジェクトに色を付けるために HTML で必要な文字列を含む、%col4詳細を指定して名前を付け%col2たハッシュを生成する場合は、上記の 2 つの関数、マッピング、そして、次のようないくつかのコード:%col3%cat_colors

my %col4;

foreach my $key (keys %col2)
{
    foreach my $i ( 0 .. scalar( @{ $col2{$key} } ) - 1 )
    {
        my $base_color = $cat_colors{ $col2{$key}->[$i] };
        my $rgb_color  = hsl_to_rgb( @$base_color,
                                     weight_to_light( $col3{$key}->[$i] ) );

        my $html_color = rgb_to_html_hex( $rgb_color );

        $col4{$key}->[$i] = $html_color;
    }
}

を生成したら、生成さ%col4れた HTML 文字列を使用して個々のエンティティに色を付けることができます。私の最近の HTML は少し錆びていますが、 などの構成要素が一度は<FONT COLOR="#xxxxxx">機能していたこと、そしてまだ機能している可能性があることはわかっています。計算された値から、構文的に有効で十分に最新の HTML を構築するのはあなたに任せます。

さて、あなたが解決しようとしている問題と、それをどのように解決する必要があるかについて、私はいくつかの大胆な仮定を立てたことを認めなければなりません。でも、私は一般的な球場にいると思います。ご不明な点がございましたら、お気軽にコメントを残してください。

そして...カットアンドペーストの便宜のために、サンプルデータセットとともに、上記のすべてのビットをスタンドアロンのテスト可能なperlプログラムにコピーした簡単なテストプログラムを次に示します。楽しみ!最後の 2 行では、YAML::XS を使用して計算された値をダンプする%col4ので、それらが妥当かどうかを確認できます。

#!/usr/bin/perl -w

use Modern::Perl;

##  
##  Converts an HSL color value to RGB. Conversion formula
##  adapted from http://en.wikipedia.org/wiki/HSL_color_space.
##  Assumes h, s, and l are contained in the set [0, 1] and
##  returns r, g, and b in the set [0, 255].
##  
##  @param   Number  h       The hue
##  @param   Number  s       The saturation
##  @param   Number  l       The lightness
##  @return  Array           The RGB representation
##  
sub hsl_to_rgb
{
    my ($h, $s, $l) = @_;
    my ($r, $g, $b);

    if ($s == 0)
    {
        $r = $g = $b = $l; ## achromatic
    } else
    {
        sub hue2rgb
        {
            my ($p, $q, $t) = @_;

            while ($t < 0) { $t += 1;                                   }
            while ($t > 1) { $t -= 1;                                   }
            if ($t < 1/6)  { return $p + ($q - $p) * 6 * $t;            }
            if ($t < 1/2)  { return $q;                                 }
            if ($t < 2/3)  { return $p + ($q - $p) * (2/3 - $t) * 6;    }
            return $p;
        }

        my $q = $l < 0.5 ? $l * (1 + $s) : $l + $s - $l * $s;
        my $p = 2 * $l - $q;
        $r = hue2rgb($p, $q, $h + 1/3);
        $g = hue2rgb($p, $q, $h);
        $b = hue2rgb($p, $q, $h - 1/3);
    }

    return [ int($r * 255), int($g * 255), int($b * 255) ];
}

sub rgb_to_html_hex
{
    return sprintf "#%.2X%.2X%.2X", @{ $_[0] };
}

my %col1 = ( 'foo' => 1, 'bar' => 1 );

my %col2  = ('foo' => ['cat1','cat1','cat2'],
             'bar' => ['cat3','cat2','cat3'] );

my %col3  = ('foo' => [2.3,1.2,1.0],
             'bar' => [7.4,4.3,2.2]);


my %cat_colors =
(            #   Hue   Saturation
     cat1 => [ 0.00000, 1.00000 ],   # Red
     cat2 => [ 0.16667, 1.00000 ],   # Yellow
     cat3 => [ 0.33333, 1.00000 ],   # Green
);

sub weight_to_light
{
    return 1 - ($_[0] / 10);
}

my %col4;

foreach my $key (keys %col2)
{
    foreach my $i ( 0 .. scalar( @{ $col2{$key} } ) - 1 )
    {
        my $base_color = $cat_colors{ $col2{$key}->[$i] };
        my $rgb_color  = hsl_to_rgb( @$base_color,
                                     weight_to_light( $col3{$key}->[$i] ) );

        my $html_color = rgb_to_html_hex( $rgb_color );

        $col4{$key}->[$i] = $html_color;
    }
}


use YAML::XS;
say Dump( \%col4 );
于 2013-11-18T06:05:32.963 に答える