Small change to scatterplot

If I understand it correct, there are 7 different colors:
blue (#4140FF, #58E0FF), green (#00aa30, #00ff00), magenta (#f000d0, #ff60dd), cyan (#009090, #00ffff), orange (#d06000, #ff9000), red (#E25551, #bbb) and gray (#bbbbbb, #bbb). In parenthesis are the htmll color-codes of the fill and border colors (I cannot use colors on forum posts :disappointed:)

They are used as follows:

  • blue for “live games”. I think this isn’t used at the moment. Has someone seen that sometimes?
  • green ranked 19x19 games one can accept.
  • magenta ranked 13x13 games one can accept.
  • cyan ranked 9x9 games one can accept.
  • orange unranked games one can accept (any board size).
  • red own challenges.
  • gray not acceptable challenges.

If there is more than one open challenge for a point (time_per_move, rank) in the seek graph, the rectangle is bigger. (don’t trust the colors there, the color corresponds to at least 1 of the games, not necessarily all of them. Gray or red are only used if all of the games are either color).

source code
    redraw() {{{
        let ctx = this.canvas[0].getContext("2d");
        let w = this.canvas.width();
        let h = this.canvas.height();
        let padding = this.padding;
        let blitz_line = Math.round(SeekGraph.blitz_line_ratio * (w - padding) + padding);
        let live_line = Math.round(SeekGraph.live_line_ratio * (w - padding) + padding);

        ctx.clearRect(0, 0, w, h);
        this.drawAxes();



        let plot_ct = {};
        this.challenge_points = {};


        let sorted = [];
        for (let id in this.challenges) {
            sorted.push(this.challenges[id]);
        }
        sorted.sort((A, B) => {
            if (A.eligible && !B.eligible) { return 1; }
            if (!A.eligible && B.eligible) { return -1; }

            if (A.user_challenge && !B.user_challenge) { return 1; }
            if (!A.user_challenge && B.user_challenge) { return -1; }

            if (A.ranked && !B.ranked) { return 1; }
            if (!A.ranked && B.ranked) { return -1; }

            return B.challenge_id - A.challenge_id;
        });
        if (this.show_live_games) {
            for (let id in this.live_games) {
                sorted.push(this.live_games[id]);
            }
        }


        /* Plot our challenges */
        for (let j = 0; j < sorted.length; ++j) {
            let C = sorted[j];

            let rank_ratio = (Math.min(MAX_RATIO, (C.rank + 1) / 40));

            let time_ratio = 0;
            let last_tpm = 0;
            for (let i = 0; i < SeekGraph.time_columns.length; ++i) {
                let col = SeekGraph.time_columns[i];
                if (C.time_per_move <= col.time_per_move) {
                    if (C.time_per_move === 0) {
                        time_ratio = col.ratio;
                        break;
                    }

                    let alpha = (C.time_per_move - last_tpm) / (-last_tpm + col.time_per_move);
                    time_ratio = lerp(time_ratio, col.ratio, alpha);
                    break;
                }
                last_tpm = col.time_per_move;
                time_ratio = col.ratio;
            }

            let cx = Math.round(padding + ((w - padding) * time_ratio));
            let cy = Math.round(h - (padding + ((h - padding) * rank_ratio)));

            C.cx = cx;
            C.cy = cy;

            let plot_ct_pos = time_ratio + "," + rank_ratio;
            if (!(plot_ct_pos in plot_ct)) {
                plot_ct[plot_ct_pos] = 0;
            }
            let ct = ++plot_ct[plot_ct_pos];

            /* Draw */
            let d = this.square_size;
            let sx = cx - d / 2 + 0.5;
            let sy = cy - d / 2 + 0.5;
            ctx.save();
            ctx.beginPath();
            ctx.strokeStyle = "#000";
            if (C.live_game) {
                ctx.fillStyle = "#4140FF";
                ctx.strokeStyle = "#58E0FF";
            } else if (C.eligible) {
                if (C.ranked) {
                    if (C.width === 19) {
                        ctx.fillStyle = "#00aa30";
                        ctx.strokeStyle = "#00ff00";
                    } else if (C.width === 13) {
                        ctx.fillStyle = "#f000d0";
                        ctx.strokeStyle = "#ff60dd";
                    } else {
                        ctx.fillStyle = "#009090";
                        ctx.strokeStyle = "#00ffff";
                    }
                } else {
                    ctx.fillStyle = "#d06000";
                    ctx.strokeStyle = "#ff9000";
                }
                ctx.fillRect(sx, sy, d, d);
            } else if (ct === 1) {
                if (C.user_challenge) {
                    ctx.fillStyle = "#E25551";
                    ctx.strokeStyle = "#bbb";
                } else {
                    ctx.fillStyle = "#bbbbbb";
                    ctx.strokeStyle = "#bbb";
                }
                ctx.fillRect(sx, sy, d, d);
            }
            if (ct > 1) {
                let cc = Math.min((this.width < 200 ? 2 : 4), ct - 1);
                sx -= cc;
                sy -= cc;
                d += cc * 2;
            }
            if (!C.eligible) {
                ctx.strokeStyle = "#bbb";
            }
            if (C.eligible || C.live_game) {
                ctx.strokeRect(sx, sy, d, d);
            }
            ctx.restore();
        }

        //console.log("Redrawing seekgraph");
}}}

https://github.com/online-go/online-go.com/blob/devel/src/components/SeekGraph/SeekGraph.tsx

7 Likes