<commit_before>/**
    @external BaseClass
    @see https://github.com/d3plus/d3plus-common#BaseClass
*/

import {min} from "d3-array";
import {color} from "d3-color";
import {pointer, select, selectAll} from "d3-selection";
import {transition} from "d3-transition";

import {accessor, assign, attrize, BaseClass, configPrep, constant, elem} from "d3plus-common";
import {colorContrast} from "d3plus-color";
import * as paths from "d3-shape";
import {strip, TextBox} from "d3plus-text";

import Image from "../Image";
import pointDistance from "../geom/pointDistance";

/**
    @class Shape
    @extends external:BaseClass
    @desc An abstracted class for generating shapes.
*/
export default class Shape extends BaseClass {

  /**
      @memberof Shape
      @desc Invoked when creating a new class instance, and sets any default parameters.
      @private
  */
  constructor(tagName = "g") {

    super();

    this._activeOpacity = 0.25;
    this._activeStyle = {
      "stroke": (d, i) => {
        let c = this._fill(d, i);
        if (["transparent", "none"].includes(c)) c = this._stroke(d, i);
        return color(c).darker(1);
      },
      "stroke-width": (d, i) => {
        const s = this._strokeWidth(d, i) || 1;
        return s * 3;
      }
    };
    this._ariaLabel = constant("");
    this._backgroundImage = constant(false);
    this._backgroundImageClass = new Image();
    this._data = [];
    this._duration = 600;
    this._fill = constant("black");
    this._fillOpacity = constant(1);

    this._hoverOpacity = 0.5;
    this._hoverStyle = {
      "stroke": (d, i) => {
        let c = this._fill(d, i);
        if (["transparent", "none"].includes(c)) c = this._stroke(d, i);
        return color(c).darker(0.5);
      },
      "stroke-width": (d, i) => {
        const s = this._strokeWidth(d, i) || 1;
        return s * 2;
      }
    };
    this._id = (d, i) => d.id !== void 0 ? d.id : i;
    this._label = constant(false);
    this._labelClass = new TextBox();
    this._labelConfig = {
      fontColor: (d, i) => colorContrast(this._fill(d, i)),
      fontSize: 12,
      padding: 5
    };
    this._name = "Shape";
    this._opacity = constant(1);
    this._pointerEvents = constant("visiblePainted");
    this._role = constant("presentation");
    this._rotate = constant(0);
    this._rx = constant(0);
    this._ry = constant(0);
    this._scale = constant(1);
    this._shapeRendering = constant("geometricPrecision");
    this._stroke = (d, i) => color(this._fill(d, i)).darker(1);
    this._strokeDasharray = constant("0");
    this._strokeLinecap = constant("butt");
    this._strokeOpacity = constant(1);
    this._strokeWidth = constant(0);
    this._tagName = tagName;
    this._textAnchor = constant("start");
    this._vectorEffect = constant("non-scaling-stroke");
    this._verticalAlign = constant("top");

    this._x = accessor("x", 0);
    this._y = accessor("y", 0);

  }

  /**
      @memberof Shape
      @desc Given a specific data point and index, returns the aesthetic properties of the shape.
      @param {Object} *data point*
      @param {Number} *index*
      @private
  */
  _aes() {
    return {};
  }

  /**
      @memberof Shape
      @desc Adds event listeners to each shape group or hit area.
      @param {D3Selection} *update* The update cycle of the data binding.
      @private
  */
  _applyEvents(handler) {

    const events = Object.keys(this._on);
    for (let e = 0; e < events.length; e++) {
      handler.on(events[e], (event, d, i) => {
        if (!this._on[events[e]]) return;
        if (d.i !== void 0) i = d.i;
        if (d.nested && d.values) {
          const calcPoint = (d, i) => {
            if (this._discrete === "x") return [this._x(d, i), cursor[1]];
            else if (this._discrete === "y") return [cursor[0], this._y(d, i)];
            else return [this._x(d, i), this._y(d, i)];
          };
          const cursor = pointer(event, this._select.node()),
                values = d.values.map(d => pointDistance(cursor, calcPoint(d, i)));
          i = values.indexOf(min(values));
          d = d.values[i];
        }
        this._on[events[e]].bind(this)(d, i);
      });
    }<commit_msg>passes mouse event as 4th arg in on events<commit_after>/**
    @external BaseClass
    @see https://github.com/d3plus/d3plus-common#BaseClass
*/

import {min} from "d3-array";
import {color} from "d3-color";
import {pointer, select, selectAll} from "d3-selection";
import {transition} from "d3-transition";

import {accessor, assign, attrize, BaseClass, configPrep, constant, elem} from "d3plus-common";
import {colorContrast} from "d3plus-color";
import * as paths from "d3-shape";
import {strip, TextBox} from "d3plus-text";

import Image from "../Image";
import pointDistance from "../geom/pointDistance";

/**
    @class Shape
    @extends external:BaseClass
    @desc An abstracted class for generating shapes.
*/
export default class Shape extends BaseClass {

  /**
      @memberof Shape
      @desc Invoked when creating a new class instance, and sets any default parameters.
      @private
  */
  constructor(tagName = "g") {

    super();

    this._activeOpacity = 0.25;
    this._activeStyle = {
      "stroke": (d, i) => {
        let c = this._fill(d, i);
        if (["transparent", "none"].includes(c)) c = this._stroke(d, i);
        return color(c).darker(1);
      },
      "stroke-width": (d, i) => {
        const s = this._strokeWidth(d, i) || 1;
        return s * 3;
      }
    };
    this._ariaLabel = constant("");
    this._backgroundImage = constant(false);
    this._backgroundImageClass = new Image();
    this._data = [];
    this._duration = 600;
    this._fill = constant("black");
    this._fillOpacity = constant(1);

    this._hoverOpacity = 0.5;
    this._hoverStyle = {
      "stroke": (d, i) => {
        let c = this._fill(d, i);
        if (["transparent", "none"].includes(c)) c = this._stroke(d, i);
        return color(c).darker(0.5);
      },
      "stroke-width": (d, i) => {
        const s = this._strokeWidth(d, i) || 1;
        return s * 2;
      }
    };
    this._id = (d, i) => d.id !== void 0 ? d.id : i;
    this._label = constant(false);
    this._labelClass = new TextBox();
    this._labelConfig = {
      fontColor: (d, i) => colorContrast(this._fill(d, i)),
      fontSize: 12,
      padding: 5
    };
    this._name = "Shape";
    this._opacity = constant(1);
    this._pointerEvents = constant("visiblePainted");
    this._role = constant("presentation");
    this._rotate = constant(0);
    this._rx = constant(0);
    this._ry = constant(0);
    this._scale = constant(1);
    this._shapeRendering = constant("geometricPrecision");
    this._stroke = (d, i) => color(this._fill(d, i)).darker(1);
    this._strokeDasharray = constant("0");
    this._strokeLinecap = constant("butt");
    this._strokeOpacity = constant(1);
    this._strokeWidth = constant(0);
    this._tagName = tagName;
    this._textAnchor = constant("start");
    this._vectorEffect = constant("non-scaling-stroke");
    this._verticalAlign = constant("top");

    this._x = accessor("x", 0);
    this._y = accessor("y", 0);

  }

  /**
      @memberof Shape
      @desc Given a specific data point and index, returns the aesthetic properties of the shape.
      @param {Object} *data point*
      @param {Number} *index*
      @private
  */
  _aes() {
    return {};
  }

  /**
      @memberof Shape
      @desc Adds event listeners to each shape group or hit area.
      @param {D3Selection} *update* The update cycle of the data binding.
      @private
  */
  _applyEvents(handler) {

    const events = Object.keys(this._on);
    for (let e = 0; e < events.length; e++) {
      handler.on(events[e], (event, d, i) => {
        if (!this._on[events[e]]) return;
        if (d.i !== void 0) i = d.i;
        if (d.nested && d.values) {
          const calcPoint = (d, i) => {
            if (this._discrete === "x") return [this._x(d, i), cursor[1]];
            else if (this._discrete === "y") return [cursor[0], this._y(d, i)];
            else return [this._x(d, i), this._y(d, i)];
          };
          const cursor = pointer(event, this._select.node()),
                values = d.values.map(d => pointDistance(cursor, calcPoint(d, i)));
          i = values.indexOf(min(values));
          d = d.values[i];
        }
        this._on[events[e]].bind(this)(d, i, undefined, event);
      });
    }
{'fraction_non_alphanumeric': 0.16250148051640412, 'fraction_numerical': 0.011015042046665877, 'mean_word_length': 2.5764506565014824, 'pattern_counts': {'":': 8, '<': 5, '<?xml version=': 0, '>': 23, 'https://': 2, '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': '2803784', 'n_tokens_mistral': 2800, 'n_tokens_neox': 2715, 'n_words': 708}