<commit_before>// This file was adapted from the nanogui::Graph class, which was developed
// by <NAME> <<EMAIL>> and based on the NanoVG demo application
// by <NAME>. Modifications were developed by <NAME> <<EMAIL>>.
// This file is published under the BSD 3-Clause License within the LICENSE file.

#include <tev/MultiGraph.h>

#include <nanogui/theme.h>
#include <nanogui/opengl.h>
#include <nanogui/serializer/core.h>

using namespace Eigen;
using namespace nanogui;
using namespace std;

TEV_NAMESPACE_BEGIN

MultiGraph::MultiGraph(Widget *parent, const std::string &caption)
: Widget(parent), mCaption(caption) {
    mBackgroundColor = Color(20, 128);
    mForegroundColor = Color(255, 192, 0, 128);
    mTextColor = Color(240, 192);
}

Vector2i MultiGraph::preferredSize(NVGcontext *) const {
    return Vector2i(180, 80);
}

void MultiGraph::draw(NVGcontext *ctx) {
    Widget::draw(ctx);

    NVGpaint bg = nvgBoxGradient(ctx,
        mPos.x() + 1, mPos.y() + 1 + 1.0f, mSize.x() - 2, mSize.y() - 2,
        3, 4, Color(120, 32), Color(32, 32));

    nvgBeginPath(ctx);
    nvgRoundedRect(ctx, mPos.x() + 1, mPos.y() + 1 + 1.0f, mSize.x() - 2,
        mSize.y() - 2, 3);

    nvgFillPaint(ctx, bg);

    nvgFill(ctx);

    if (mValues.cols() >= 1 && mValues.rows() >= 2) {
        array<Color, 3> colors = {{
            Color{255, 0, 0, 200},
            Color{0, 255, 0, 200},
            Color{0, 0, 255, 200},
        }};

        nvgSave(ctx);
        // Additive blending
        nvgGlobalCompositeBlendFunc(ctx, NVGblendFactor::NVG_SRC_ALPHA, NVGblendFactor::NVG_ONE);

        for (size_t i = 0; i < (size_t)mValues.cols(); i++) {
            nvgBeginPath(ctx);
            nvgMoveTo(ctx, mPos.x(), mPos.y() + mSize.y());
            for (size_t j = 0; j < (size_t)mValues.rows(); j++) {
                float value = mValues(j, i);
                float vx = mPos.x() + j * mSize.x() / (float)(mValues.rows() - 1);
                float vy = mPos.y() + (1 - value) * mSize.y();
                nvgLineTo(ctx, vx, vy);
            }

            auto color = i < colors.size() ? colors[i] : mForegroundColor;
            nvgLineTo(ctx, mPos.x() + mSize.x(), mPos.y() + mSize.y());
            nvgFillColor(ctx, colors[i]);
            nvgFill(ctx);
        }

        nvgRestore(ctx);

        if (mZeroBin > 0) {
            nvgBeginPath(ctx);
            nvgRect(ctx, mPos.x() + mZeroBin * mSize.x() / (float)(mValues.rows() - 1), mPos.y() + 15, 1, mSize.y() - 15);
            nvgFillColor(ctx, Color(200, 255));
            nvgFill(ctx);
        }

        nvgFontFace(ctx, "sans");

        nvgFontSize(ctx, 14.0f);
        nvgTextAlign(ctx, NVG_ALIGN_LEFT | NVG_ALIGN_TOP);
        nvgFillColor(ctx, mTextColor);
        nvgText(ctx, mPos.x() + 3, mPos.y() + 1, tfm::format("%.3f", mMinimum).c_str(), NULL);

        nvgTextAlign(ctx, NVG_ALIGN_MIDDLE | NVG_ALIGN_TOP);
        nvgFillColor(ctx, mTextColor);
        string meanString = tfm::format("%.3f", mMean);
        float textWidth = nvgTextBounds(ctx, 0, 0, meanString.c_str(), nullptr, nullptr);
        nvgText(ctx, mPos.x() + mSize.x() / 2 - textWidth / 2, mPos.y() + 1, meanString.c_str(), NULL);

        nvgTextAlign(ctx, NVG_ALIGN_RIGHT | NVG_ALIGN_TOP);
        nvgFillColor(ctx, mTextColor);
        nvgText(ctx, mPos.x() + mSize.x() - 3, mPos.y() + 1, tfm::format("%.3f", mMaximum).c_str(), NULL);

        if (!mCaption.empty()) {<commit_msg>Do not hide the left-most and right-most portions of the histogram<commit_after>// This file was adapted from the nanogui::Graph class, which was developed
// by <NAME> <<EMAIL>> and based on the NanoVG demo application
// by <NAME>. Modifications were developed by <NAME> <<EMAIL>>.
// This file is published under the BSD 3-Clause License within the LICENSE file.

#include <tev/MultiGraph.h>

#include <nanogui/theme.h>
#include <nanogui/opengl.h>
#include <nanogui/serializer/core.h>

using namespace Eigen;
using namespace nanogui;
using namespace std;

TEV_NAMESPACE_BEGIN

MultiGraph::MultiGraph(Widget *parent, const std::string &caption)
: Widget(parent), mCaption(caption) {
    mBackgroundColor = Color(20, 128);
    mForegroundColor = Color(255, 192, 0, 128);
    mTextColor = Color(240, 192);
}

Vector2i MultiGraph::preferredSize(NVGcontext *) const {
    return Vector2i(180, 80);
}

void MultiGraph::draw(NVGcontext *ctx) {
    Widget::draw(ctx);

    NVGpaint bg = nvgBoxGradient(ctx,
        mPos.x() + 1, mPos.y() + 1 + 1.0f, mSize.x() - 2, mSize.y() - 2,
        3, 4, Color(120, 32), Color(32, 32));

    nvgBeginPath(ctx);
    nvgRoundedRect(ctx, mPos.x() + 1, mPos.y() + 1 + 1.0f, mSize.x() - 2,
        mSize.y() - 2, 3);

    nvgFillPaint(ctx, bg);

    nvgFill(ctx);

    if (mValues.cols() >= 1 && mValues.rows() >= 2) {
        array<Color, 3> colors = {{
            Color{255, 0, 0, 200},
            Color{0, 255, 0, 200},
            Color{0, 0, 255, 200},
        }};

        nvgSave(ctx);
        // Additive blending
        nvgGlobalCompositeBlendFunc(ctx, NVGblendFactor::NVG_SRC_ALPHA, NVGblendFactor::NVG_ONE);

        for (size_t i = 0; i < (size_t)mValues.cols(); i++) {
            nvgBeginPath(ctx);
            nvgMoveTo(ctx, mPos.x(), mPos.y() + mSize.y());
            
            for (size_t j = 0; j < (size_t)mValues.rows(); j++) {
                float value = mValues(j, i);
                float vx = mPos.x() + 2 + j * (mSize.x() - 4) / (float)(mValues.rows() - 1);
                float vy = mPos.y() + (1 - value) * mSize.y();
                nvgLineTo(ctx, vx, vy);
            }

            auto color = i < colors.size() ? colors[i] : mForegroundColor;
            nvgLineTo(ctx, mPos.x() + mSize.x(), mPos.y() + mSize.y());
            nvgFillColor(ctx, colors[i]);
            nvgFill(ctx);
        }

        nvgRestore(ctx);

        if (mZeroBin > 0) {
            nvgBeginPath(ctx);
            nvgRect(ctx, mPos.x() + 2 + mZeroBin * (mSize.x() - 4) / (float)(mValues.rows() - 1), mPos.y() + 15, 1, mSize.y() - 15);
            nvgFillColor(ctx, Color(200, 255));
            nvgFill(ctx);
        }

        nvgFontFace(ctx, "sans");

        nvgFontSize(ctx, 14.0f);
        nvgTextAlign(ctx, NVG_ALIGN_LEFT | NVG_ALIGN_TOP);
        nvgFillColor(ctx, mTextColor);
        nvgText(ctx, mPos.x() + 3, mPos.y() + 1, tfm::format("%.3f", mMinimum).c_str(), NULL);

        nvgTextAlign(ctx, NVG_ALIGN_MIDDLE | NVG_ALIGN_TOP);
        nvgFillColor(ctx, mTextColor);
        string meanString = tfm::format("%.3f", mMean);
        float textWidth = nvgTextBounds(ctx, 0, 0, meanString.c_str(), nullptr, nullptr);
        nvgText(ctx, mPos.x() + mSize.x() / 2 - textWidth / 2, mPos.y() + 1, meanString.c_str(), NULL);

        nvgTextAlign(ctx, NVG_ALIGN_RIGHT | NVG_ALIGN_TOP);
        nvgFillColor(ctx, mTextColor);
        nvgText(ctx, mPos.x() + mSize.x() - 3, mPos.y() + 1, tfm::format("%.3f", mMaximum).c_str(), NULL);

        if (!mCaption.empty()) {
{'fraction_non_alphanumeric': 0.16561242093156986, 'fraction_numerical': 0.0327774583093732, 'mean_word_length': 2.5065524193548385, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1259613', 'n_tokens_mistral': 2772, 'n_tokens_neox': 2546, 'n_words': 576}