<commit_before>"use strict";

/**
 * Graph element is used to draw interactive line graphs.
 *
 * It is meant to be used as input in forms to controls values in arrays.
 *
 * Multiple graph lines can be displayed, each graph line has a name that can be used to access its properties.
 *
 * @class Graph
 * @extends {Element}
 * @param {Element} parent Parent element.
 * @param {String} name Name of the default graph.
 * @param {String} color CSS hex color code of the default graph.
 */
function Graph(parent, name, color)
{
	Element.call(this, parent, "div");

	var self = this;

	this.element.style.overflow = "visible";

	//Graphs
	this.graph = [];

	//Label margin
	this.scaleMargin = 22;
	this.buttonRadius = 10;

	//Range
	this.max = 1.0;
	this.min = 0.0;

	/**
	 * Grid canvas element.
	 *
	 * @property grid
	 * @type {DOM}
	 */
	this.grid = document.createElement("canvas");
	this.grid.style.position = "absolute";
	this.grid.style.marginLeft = this.scaleMargin + "px";
	this.element.appendChild(this.grid);

	//Graph
	var canvas = document.createElement("canvas");
	canvas.style.position = "absolute";
	canvas.style.marginLeft = this.scaleMargin + "px";
	this.element.appendChild(canvas);

	//Default graph
	this.graph.push(
	{
		canvas: canvas,
		name: (name !== undefined) ? name : "default",
		color: (color !== undefined) ? color : "#FFFFFF",
		values: [],
		buttons: [],
		onchange: null
	});
	
	/**
	 * Scale DOM elements.
	 *
	 * @property scale
	 * @type {Array}
	 */
	this.scale = [];
	this.createScale(3);
}

Graph.prototype = Object.create(Element.prototype);

/**
 * Create numeric scale for this graph.
 *
 * @method createScale
 * @param {Number} size Number of values in the scale.
 */
Graph.prototype.createScale = function(size)
{
	for(var i = 0; i < this.scale; i++)
	{
		this.element.removeChild(this.scale[i]);
	}
	
	var step = (this.max - this.min) / (size - 1);

	for(var i = 0; i < size; i++)
	{
		var scale = document.createElement("div");
		scale.style.position = "absolute";
		scale.style.pointerEvents = "none";
		scale.style.color = Editor.theme.textColor;

		var text = document.createTextNode(this.max - (step * i));
		scale.text = text;
		scale.appendChild(text);

		this.scale.push(scale);
		this.element.appendChild(scale);
	}
};

/**
 * Update values of the scale.
 *
 * @method updateScale
 */
Graph.prototype.updateScale = function()
{
	var step = (this.max - this.min) / (this.scale.length - 1);

	for(var i = 0; i < this.scale.length; i++)
	{
		this.scale[(this.scale.length - 1) - i].text.data = this.min + (step * i);
	}
};

/**
 * Add new graph line.
 *
 * @method addGraph
 * @param {String} name Name of the graph.
 * @param {Color} color Color of the graph.
 */
Graph.prototype.addGraph = function(name, color)
{
	var canvas = document.createElement("canvas");
	canvas.style.position = "absolute";
	canvas.style.marginLeft = this.scaleMargin + "px";
	this.element.appendChild(canvas);

	this.graph.push({canvas: canvas, name: name, color: color, values: [], buttons: [], onchange: null});
};

/** 
 * Attach onchange onChange to a graph by its name.
 *
 * @method setOnChange
 * @param {Function} onChange
 * @param {String} name Graph name.
 */
Graph.prototype.setOnChange = function(onChange, name)
{
	var graph = this.getGraph(name);
	graph.onchange = onChange;<commit_msg>GraphLine subclass<commit_after>"use strict";

/**
 * Graph element is used to draw interactive line graphs.
 *
 * It is meant to be used as input in forms to controls values in arrays.
 *
 * Multiple graph lines can be displayed, each graph line has a name that can be used to access its properties.
 * 
 * @class Graph
 * @extends {Element}
 * @param {Element} parent Parent element.
 * @param {String} name Name of the default graph.
 * @param {String} color CSS hex color code of the default graph.
 */
function Graph(parent, name, color)
{
	Element.call(this, parent, "div");

	var self = this;

	this.element.style.overflow = "visible";

	/**
	 * Scale margin in pixels.
	 *
	 * @property scaleMargin
	 * @type {Number}
	 */
	this.scaleMargin = 22;

	/**
	 * Value button size.
	 *
	 * @property buttonRadius
	 * @type {Number}
	 */
	this.buttonRadius = 10;

	/**
	 * Maximum value displayed vertically.
	 *
	 * @property max
	 * @type {Number}
	 */
	this.max = 1.0;

	/**
	 * Minimum value displayed vertically.
	 *
	 * @property min
	 * @type {Number}
	 */
	this.min = 0.0;

	/**
	 * Grid canvas element.
	 *
	 * @property grid
	 * @type {DOM}
	 */
	this.grid = document.createElement("canvas");
	this.grid.style.position = "absolute";
	this.grid.style.marginLeft = this.scaleMargin + "px";
	this.element.appendChild(this.grid);

	/**
	 * The graph lines stored in this graph.
	 *
	 * @property graph
	 * @type {Array}
	 */
	this.graph = [];
	this.addGraph(name, color);
	
	/**
	 * Scale DOM elements.
	 *
	 * @property scale
	 * @type {Array}
	 */
	this.scale = [];
	this.createScale(3);
}

Graph.prototype = Object.create(Element.prototype);

Graph.GaphLine = function(canvas, name, color)
{
	if(canvas === undefined)
	{
		canvas = document.createElement("canvas");
		canvas.style.position = "absolute";
	}

	this.canvas = canvas;
	this.name = (name !== undefined) ? name : "default";
	this.color = (color !== undefined) ? color : "#FFFFFF";
	this.values = [];
	this.buttons = [];
	this.onchange = null;
};

/**
 * Create numeric scale for this graph.
 *
 * @method createScale
 * @param {Number} size Number of values in the scale.
 */
Graph.prototype.createScale = function(size)
{
	for(var i = 0; i < this.scale; i++)
	{
		this.element.removeChild(this.scale[i]);
	}
	
	var step = (this.max - this.min) / (size - 1);

	for(var i = 0; i < size; i++)
	{
		var scale = document.createElement("div");
		scale.style.position = "absolute";
		scale.style.pointerEvents = "none";
		scale.style.color = Editor.theme.textColor;

		var text = document.createTextNode(this.max - (step * i));
		scale.text = text;
		scale.appendChild(text);

		this.scale.push(scale);
		this.element.appendChild(scale);
	}
};

/**
 * Update values of the scale.
 *
 * @method updateScale
 */
Graph.prototype.updateScale = function()
{
	var step = (this.max - this.min) / (this.scale.length - 1);

	for(var i = 0; i < this.scale.length; i++)
	{
		this.scale[(this.scale.length - 1) - i].text.data = this.min + (step * i);
	}
};

/**
 * Add new graph line.
 *
 * @method addGraph
 * @param {String} name Name of the graph.
 * @param {Color} color Color of the graph.
 */
Graph.prototype.addGraph = function(name, color)
{
	var canvas = document.createElement("canvas");
	canvas.style.position = "absolute";
	canvas.style.marginLeft = this.scaleMargin + "px";
	this.element.appendChild(canvas);

	this.graph.push(new Graph.GaphLine(canvas, name, color));
};

/** 
 * Attach onchange onChange to a graph by its name.
 *
 * @method setOnChange
 * @param {Function} onChange
 * @param {String} name Graph name.
 */
Graph.prototype.setOnChange = function(onChange, name)
{
	var graph = this.getGraph(name);
	graph.onchange = onChange;
{'fraction_non_alphanumeric': 0.15620562340244248, 'fraction_numerical': 0.0042601533655211585, 'mean_word_length': 3.401875, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 3, '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': '399225', 'n_tokens_mistral': 2427, 'n_tokens_neox': 2290, 'n_words': 645}