0

数字のチャンクをバインドするヒート マップを作成しようとしています。これまでのところ、関連付けられたマップの一部であるべき番号は、コンテキストによって指定する必要があります

それはある程度まで機能します..まだRGBアルゴリズムを少し解決する必要がありますが、問題のある部分は、setHeat計算関数内のforループです。

私が望むのは、「最大」または「最小」が変更されるたびに、現在「要素」配列にあるすべての要素の色を更新することです。

しかし、要素が「要素」配列に追加されると、その要素の色を設定したいだけですが、それには最大値と最小値が必要なので、最小値と最大値の更新が1つを呼び出すように呼び出しを適切に分離する方法がわかりません要素の更新は他の要素を呼び出します。

また、バインディングを改善する方法についての批評も受け付けています。

<!-- ko foreach:items -->
            <tr>
                <td class="postCell">
                    <div class="ui-post-icon" data-bind="class: $parents[2].setPostIcon(post)"></div>
                    <span data-bind="text:post"></span>
                </td>
                <!-- ko foreach:combinations -->
                <td data-bind="heat:{value:amount,context:'exotics'}"></td>
                <!-- /ko -->
            </tr>
            <!-- /ko -->


ko.bindingHandlers.heat = {
        init: function (element, value, allBindings, viewModel, bindingConext) {
            var item = value();
            var model = bindingConext.$root;

            if (!model["koHeat"])
                model["koHeat"] = {};

            if (!model["koHeat"][item.context])
                model["koHeat"][item.context] = ko.observable(new HeatContext());

            var ctx = model["koHeat"][item.context];

            if (!isNaN(item.value)) {
                if (+item.value > ctx().max()) ctx().max(+item.value);
                if (+item.value < ctx().min()) ctx().min(+item.value);
                ctx().elements.push(element);
            }

            $(element).html(item.value).data('koHeat', item.value);

            //set value

            function HeatContext() {
                var self = this;
                this.max = ko.observable(0);
                this.min = ko.observable(Number.MAX_VALUE);
                this.elements = ko.observableArray([]);

                this.setHeat = ko.computed(function () {

                    var max = self.max(),
                        min = self.min(),
                        elems = self.elements(),
                        mid = (max + min) / 2,
                        range = max - min,
                        r, g, b, x;

                    for (var i = 0; i < elems.length; i++) {
                        var val = $(elems[i]).data('koHeat');
                        x = (val - mid) / range;
                        if (x > 0) {
                            g = Math.abs(Math.round(x* 100));
                            b = 0.0;
                            r = Math.abs(Math.round((1.0 - x) * 100));
                        } else {
                            g = Math.abs(Math.round(x * 100));
                            b = Math.abs(Math.round((1.0 - x) * 100));
                            r = 0.0;
                        }
                        log(r,g,b);

                        $(elems[i]).css('color', "rgb(" + r + "," + g + "," + b + ")");
                    }
                });
            }
        }
    };

編集 私は状況に合わせて簡単なフィドルを作りました

http://jsfiddle.net/rwJfK/3/

4

1 に答える 1

1

setHeatを作成する代わりに、プレフィックスを削除してサブスクライブすることにより、computed内部でプライベート関数として宣言し、次のように変更します。HeatContextthis.minmax

this.min.subscribe(setHeat);
this.max.subscribe(setHeat);

現在、またはが更新されsetHeatたときにのみ実行され、要素が配列にプッシュされたときは実行されません。minmax

このバインディングを改善する方法はたくさんあります。数日中に改良版をまとめてみます。この回答を編集します。

于 2012-10-11T22:43:45.577 に答える