<commit_before>import { NodeGlyphShape } from "../NodeGlyphInterface"
import { EdgeGlyphShape } from "../EdgeGlyphInterface";
import { Selection } from "d3-selection";
import { extent } from "d3-array";
import { DynamicGraph, Node, Edge } from "../../model/dynamicgraph";
import { LineGlyphShape } from "./LineGlyphShape";
import { SVGAttrOpts } from "../DGLOsSVG";
import { ScaleOrdinal, scaleOrdinal, schemeCategory20, scaleLinear } from "d3-scale";

/**
 * The __GestaltGlyphsShape__ class contains all of the methods required to draw and position a Gestalt Glyph on screen.
 * The only attribute in the class is its __ _shapeType __ which is readonly. Shape types are used to coordinate 
 * transisitons between shapes.
 * 
 * The class implements __EdgeGlyphShape__ and as such must contain the following methods:
 * 	 *init()*, 
 * 	 *initDraw()*,
 * 	 *updateDraw()*, 
 * 	 *transformTo()*,
 *	 *draw()*, 
 */
export class GestaltGlyphShape extends LineGlyphShape implements EdgeGlyphShape {
	readonly _shapeType = "Gestalt";

	/**
 	* The init method is a requirement of the __EdgeGlyphShape__ interface.
 	* 
 	* It takes an SVG selection and appends a <g> tag with class name GestaltGlyphs.
 	* This class is used to store the Gestalt Glyph objects.
 	* @param location
 	*/
	public init(location: Selection<any, {}, any, {}>): Selection<any, {}, any, {}> {
		return location.append("g").classed("GestaltGlyphs", true);
	}
	/**
	 * The initDraw method is a requirement of the __EdgeGlyphShape__ interface.
	 * 
	 * It takes an SVG selection with entered data and creates Gestalt Glyph objects with
	 * an ID based on the source and target of the edge.
	 * 
	 * The DynamicGraph and number parameteres are required by the interface but are not
	 * explicitly used here.
	 * @param glyphs 
	 * @param data 
	 * @param TimeStampIndex 
	 */
	public initDraw(edges: Selection<any, Edge, any, {}>, data: DynamicGraph, TimeStampIndex: number): Selection<any, {}, any, {}> {
		let self = this;
		let ret: Selection<any, Edge, any, {}> = edges.append("line")
			.classed("edgeGestalt", true)
			.attr("id", function (d: Edge): string { return d.source.id + ":" + d.target.id })
			.attr("weight", function (d: Edge): string {
				return d.weight + "";
			})
			.attr("timestep", function (e: Edge): string {
				return e.timestep + "";
			})
		return ret;
	}

	/**
	 * Assign and/or update edge attributes
	 * @param edges 
	 */
	public updateDraw(glyphs: Selection<any, {}, any, {}>, attrOpts: SVGAttrOpts, data: DynamicGraph, timeStampIndex: number, svgWidth: number, svgHeight: number): Selection<any, {}, any, {}> {
		try {
			let weightScale = scaleLinear<number>()
				.domain(this.createDomain(data.timesteps[timeStampIndex].edges))
				.range([-10, 10]);
			let thicknessScale = scaleLinear<number>()
				.domain(this.createDomain(data.timesteps[timeStampIndex].edges))
				.range([.25, 1.5]);
			let steps = data.timesteps.length;
			let self = this;
			glyphs
				.attr("x1", function (d: Edge) {
					return d.x;
				})
				.attr("y1", function (d: Edge) {
					// let yPos = 0;
					// for (let edge of data.timesteps[timeStampIndex].edges) {
					// 	if (edge.target === d.source && edge.source === d.target && edge.timestep === d.timestep) {
					// 		let yPos = weightScale(d.weight);
					// 		d.y = yPos + d.y;
					// 		break;
					// 	}
					// }
					// return yPos + d.y;
					return 10;
				})
				.attr("x2", function (d: Edge) {
					//return d.x + ((svgWidth / data.timesteps[timeStampIndex].nodes.length) * (7 / 8));
					return 10;
				})
				.attr("y2", function (d: Edge) {
					// let yPos = 0
					// for (let edge of data.timesteps[timeStampIndex].edges) {
					// 	if (edge.source === d.target && edge.target === d.source && edge.timestep === d.timestep) {
					// 		let yPos = weightScale(edge.weight);
					// 		if (yPos === NaN) {
					// 			yPos = 0;
					// 		}
					// 		d.y = yPos + d.y;
					// 		break;
					// 	}
					// }
					// return yPos + d.y;
					return 10;

				})
				.attr("stroke", attrOpts.stroke)
				.attr("stroke-width", function (d: Edge) {
					return thicknessScale(d.weight);
				});



			return glyphs;
		}
		catch (err) {
			// console.log("gestalt update error");
		}
	}

	/**
	 * Transform the current EdgeGlyphShape to given EdgeGlyphShape
	 * @param sourceG 
	 * @param targetShape 
	 * @param targetG 
	 */
	public transformTo(sourceG: Selection<any, {}, any, {}>, targetShape: EdgeGlyphShape, targetG: Selection<any, {}, any, {}>): void {
		switch (targetShape.shapeType) {
			case "Rect":
				console.log("Gestalt-->Rect");
				break;

			case "STLine":
				console.log("Gestalt-->STLine");
				break;

			case "Gestalt":
				console.log("Gestalt-->Gestalt Catch");
				break;
<commit_msg>GestaltGlyphShape progress, self edge is gone in newcomb data set<commit_after>import { NodeGlyphShape } from "../NodeGlyphInterface"
import { EdgeGlyphShape } from "../EdgeGlyphInterface";
import { Selection } from "d3-selection";
import { extent } from "d3-array";
import { DynamicGraph, Node, Edge } from "../../model/dynamicgraph";
import { LineGlyphShape } from "./LineGlyphShape";
import { SVGAttrOpts } from "../DGLOsSVG";
import { ScaleOrdinal, scaleOrdinal, schemeCategory20, scaleLinear } from "d3-scale";

/**
 * The __GestaltGlyphsShape__ class contains all of the methods required to draw and position a Gestalt Glyph on screen.
 * The only attribute in the class is its __ _shapeType __ which is readonly. Shape types are used to coordinate 
 * transisitons between shapes.
 * 
 * The class implements __EdgeGlyphShape__ and as such must contain the following methods:
 * 	 *init()*, 
 * 	 *initDraw()*,
 * 	 *updateDraw()*, 
 * 	 *transformTo()*,
 *	 *draw()*, 
 */
export class GestaltGlyphShape extends LineGlyphShape implements EdgeGlyphShape {
	readonly _shapeType = "Gestalt";

	/**
 	* The init method is a requirement of the __EdgeGlyphShape__ interface.
 	* 
 	* It takes an SVG selection and appends a <g> tag with class name GestaltGlyphs.
 	* This class is used to store the Gestalt Glyph objects.
 	* @param location
 	*/
	public init(location: Selection<any, {}, any, {}>): Selection<any, {}, any, {}> {
		return location.append("g").classed("GestaltGlyphs", true);
	}
	/**
	 * The initDraw method is a requirement of the __EdgeGlyphShape__ interface.
	 * 
	 * It takes an SVG selection with entered data and creates Gestalt Glyph objects with
	 * an ID based on the source and target of the edge.
	 * 
	 * The DynamicGraph and number parameteres are required by the interface but are not
	 * explicitly used here.
	 * @param glyphs 
	 * @param data 
	 * @param TimeStampIndex 
	 */
	public initDraw(edges: Selection<any, Edge, any, {}>, data: DynamicGraph, TimeStampIndex: number): Selection<any, {}, any, {}> {
		let self = this;
		let ret: Selection<any, Edge, any, {}> = edges.append("line")
			.classed("edgeGestalt", true)
			.attr("id", function (d: Edge): string { return d.source.id + ":" + d.target.id })
			.attr("weight", function (d: Edge): string {
				return d.weight + "";
			})
			.attr("timestep", function (e: Edge): string {
				return e.timestep + "";
			})
		return ret;
	}

	/**
	 * Assign and/or update edge attributes
	 * @param edges 
	 */
	public updateDraw(glyphs: Selection<any, {}, any, {}>, attrOpts: SVGAttrOpts, data: DynamicGraph, timeStampIndex: number, svgWidth: number, svgHeight: number): Selection<any, {}, any, {}> {
		console.log(data.timesteps[timeStampIndex].edges);
		console.log(data.timesteps[timeStampIndex].nodes);
		try {
			let weightScale = scaleLinear<number>()
				.domain(this.createDomain(data.timesteps[timeStampIndex].edges))
				.range([-10, 10]);
			let thicknessScale = scaleLinear<number>()
				.domain(this.createDomain(data.timesteps[timeStampIndex].edges))
				.range([.25, 1.5]);
			let steps = data.timesteps.length;
			let self = this;
			glyphs
				.attr("x1", function (d: Edge) {
					return d.x;
				})
				.attr("y1", function (d: Edge) {
					let yPos = 0;
					for (let edge of data.timesteps[timeStampIndex].edges) {
						if (edge.target === d.source && edge.source === d.target && edge.timestep === d.timestep) {
							let yPos = weightScale(d.weight);
							d.y = yPos + d.y;
							break;
						}
					}
					return yPos + d.y;
				})
				.attr("x2", function (d: Edge) {
					return d.x + ((svgWidth / data.timesteps[timeStampIndex].nodes.length) * (7 / 8));
				})
				.attr("y2", function (d: Edge) {
					let yPos = 0
					for (let edge of data.timesteps[timeStampIndex].edges) {
						if (edge.source === d.target && edge.target === d.source && edge.timestep === d.timestep) {
							let yPos = weightScale(edge.weight);
							if (yPos === NaN) {
								yPos = 0;
							}
							d.y = yPos + d.y;
							break;
						}
					}
					return yPos + d.y;
				})
				.attr("stroke", attrOpts.stroke)
				.attr("stroke-width", function (d: Edge) {
					return thicknessScale(d.weight);
				});



			return glyphs;
		}
		catch (err) {
			console.log("gestalt update error");
		}
	}

	/**
	 * Transform the current EdgeGlyphShape to given EdgeGlyphShape
	 * @param sourceG 
	 * @param targetShape 
	 * @param targetG 
	 */
	public transformTo(sourceG: Selection<any, {}, any, {}>, targetShape: EdgeGlyphShape, targetG: Selection<any, {}, any, {}>): void {
		switch (targetShape.shapeType) {
			case "Rect":
				console.log("Gestalt-->Rect");
				break;

			case "STLine":
				console.log("Gestalt-->STLine");
				break;

			case "Gestalt":
				console.log("Gestalt-->Gestalt Catch");
				break;

{'fraction_non_alphanumeric': 0.14779972823246576, 'fraction_numerical': 0.005226298735235706, 'mean_word_length': 3.113499570077386, 'pattern_counts': {'":': 8, '<': 27, '<?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': '3090870', 'n_tokens_mistral': 3707, 'n_tokens_neox': 3082, 'n_words': 869}