Skip to content
Snippets Groups Projects
Commit 71e3e0a4 authored by Maximilian Giller's avatar Maximilian Giller :squid:
Browse files

Implemented new color object

parent ff46658f
No related branches found
No related tags found
No related merge requests found
Pipeline #57089 failed
......@@ -147,7 +147,7 @@ export class Graph
this.createObjectGroup({
id: ++this.nextObjectGroupId,
name: "Default",
color: "#000000",
color: { r: 0, g: 0, b: 0 },
});
}
}
......
import { GraphElement } from "./graphelement";
export interface ColorData { r: number, g: number, b: number }
export interface NodeTypeData {
id: number;
name: string;
color?: string;
color?: ColorData;
}
export class NodeType
extends GraphElement<NodeTypeData, NodeTypeData>
implements NodeTypeData
{
implements NodeTypeData {
public id: number;
public name: string;
public color: string;
public color: ColorData;
constructor(name?: string, color?: string) {
constructor(name?: string, color?: ColorData) {
super(0);
this.name = name;
this.color = color;
......
export { getClientWidth, getWindowInnerHeight };
import { ColorData } from "./graph/nodetype";
export { getClientWidth, getWindowInnerHeight, colorToRGB };
/**
* Returns the maximum width that should be used if displaying elements inside of wordpress.
......@@ -15,3 +17,17 @@ function getClientWidth(elementId: string): number {
function getWindowInnerHeight(offset = 200): number {
return window.innerHeight - offset;
}
/**
* Simple string builder for color data.
* @param color ColorData object.
* @returns String describing color in the "rgb(..,..,..)" format.
*/
function colorToRGB(color: ColorData): string {
// Make it more robust against edge cases
const r = isNaN(color.r) ? 0 : color.r;
const g = isNaN(color.g) ? 0 : color.g;
const b = isNaN(color.b) ? 0 : color.b;
return "rgb(" + r + "," + g + "," + b + ")";
}
<?php
require_once(__DIR__ . "/ks-datasets-database.php");
$EMPTY_SPACE = '{"nodes":[{"id":0,"name":"Node","type":1},{"id":1,"name":"Node","type":1}],"links":[{"source":1,"target":0}],"objectGroups":[{"id":1,"name":"Default","color":"#000000"}]}';
$EMPTY_SPACE = '{"nodes":[{"id":0,"name":"Node","type":1},{"id":1,"name":"Node","type":1}],"links":[{"source":1,"target":0}],"objectGroups":[{"id":1,"name":"Default","color":{"r":0,"g":0,"b":0}}]}';
add_action("wp_ajax_get_space", "ks_get_space"); // Fires only for logged-in-users
add_action("wp_ajax_nopriv_get_space", 'ks_get_space' ); // Fires for everyone
function ks_get_space() {
add_action("wp_ajax_nopriv_get_space", 'ks_get_space'); // Fires for everyone
function ks_get_space()
{
$name = ks_escape_space_name($_POST["space"]);
$space = ks_select_space($name);
......@@ -23,12 +24,13 @@ function ks_get_space() {
}
add_action("wp_ajax_list_spaces", "ks_list_spaces"); // Fires only for logged-in-users
function ks_list_spaces() {
function ks_list_spaces()
{
$spaces = array();
foreach (ks_select_all_spaces() as $space) {
$spaces[] = $space->name;
}
$payload = array("spaces" => $spaces);
echo json_encode($payload);
......@@ -37,7 +39,8 @@ function ks_list_spaces() {
add_action("wp_ajax_update_space", "ks_update_space"); // Fires only for logged-in-users
//add_action("wp_ajax_nopriv_update_space", 'update_space' ); // Fires for everyone
function ks_update_space() {
function ks_update_space()
{
// Check user capabilities
if (current_user_can("edit_posts")) {
// Use json encoding.
......@@ -69,7 +72,8 @@ function ks_delete_space()
}
}
function ks_escape_space_name($space_name) {
function ks_escape_space_name($space_name)
{
// Cleaning up the space id
$space_name = str_replace("/", "-", $space_name);
$space_name = str_replace("\\", "-", $space_name);
......
import React, { useEffect, useRef, useState } from "react";
import { ColorData } from "../../common/graph/nodetype";
import "./collapsible.css";
interface CollapsibleProps {
open?: boolean;
header: string | React.ReactNode;
children?: React.ReactNode | React.ReactNode[];
color?: string;
color?: ColorData;
heightTransition?: boolean;
}
......@@ -23,7 +24,7 @@ function Collapsible({
open,
header,
children,
color = "gray",
color = { r: 128, g: 128, b: 128 },
heightTransition = true,
}: CollapsibleProps) {
const [isOpen, setIsOpen] = useState(open);
......
import React from "react";
import { ColorData } from "../../../common/graph/nodetype";
import { colorToRGB } from "../../../common/helpers";
import "./label.css";
interface ClassLabelProps {
text: string;
color: string;
color: ColorData;
width: number;
active?: boolean;
onClick?: (type: string) => void;
......@@ -42,7 +44,10 @@ function Label({
<p>{text}</p>
<div
className={"filter-class-label-color-strip"}
style={{ width: width + "px", backgroundColor: color }}
style={{
width: width + "px",
backgroundColor: colorToRGB(color),
}}
></div>
</div>
);
......
......@@ -4,6 +4,7 @@ import "./searchbar.css";
import searchicon from "./search_icon.svg";
import closeicon from "./close_icon.svg";
import { Node } from "../../common/graph/node";
import { colorToRGB } from "../../common/helpers";
interface SearchBarProps {
minified: boolean;
......@@ -121,7 +122,7 @@ function SearchBar({
<div
className={"searchbar-results-circle"}
style={{
backgroundColor: el.type.color,
backgroundColor: colorToRGB(el.type.color),
}}
></div>
<div>{el.name}</div>
......
......@@ -14,6 +14,8 @@ import { Object3D, Sprite } from "three";
import { Graph, Coordinate3D } from "../common/graph/graph";
import { Node } from "../common/graph/node";
import { Link } from "../common/graph/link";
import { colorToRGB } from "../common/helpers";
import { ColorData } from "../common/graph/nodetype";
export interface VisualGraphNode extends Node {
__threeObj: THREE.Group;
......@@ -107,7 +109,7 @@ export class GraphRenderer extends React.PureComponent<
const material = new THREE.SpriteMaterial({
//map: imageTexture,
color: node.type.color,
color: colorToRGB(node.type.color),
alphaMap: imageAlpha,
transparent: true,
alphaTest: 0.2,
......@@ -127,10 +129,13 @@ export class GraphRenderer extends React.PureComponent<
drawLink(link: Link) {
const colors = new Float32Array(
[].concat(
...[link.target, link.source]
.map((node) => node.type.color)
.map((color) => color.replace(/[^\d,]/g, "").split(",")) // Extract rgb() color components
.map((rgb) => rgb.map((v: string) => parseInt(v) / 255))
...[link.target, link.source].map((node) =>
[
node.type.color.r,
node.type.color.g,
node.type.color.b,
].map((v: number) => v / 255)
)
)
);
......
import React, { useState } from "react";
import { NodeType, NodeTypeData } from "../../common/graph/nodetype";
import { ColorData, NodeType, NodeTypeData } from "../../common/graph/nodetype";
import "./nodetypeentry.css";
type NodeTypeEntryProps = {
......@@ -22,23 +22,6 @@ function NodeTypeEntry({
enableDelete,
createCheckpoint,
}: NodeTypeEntryProps) {
const [tmpColor, setTmpColor] = useState<string>(undefined);
const isValidColor = (color: string) => {
if (color.length <= 0) {
return false;
}
// Source: https://stackoverflow.com/a/8027444
return /^#([0-9A-F]{3}){1,2}$/i.test(color);
};
const referenceData: NodeTypeData = {
id: nodeType.id,
color: nodeType.color,
name: nodeType.name,
};
const handleDataChange = function <ValueType>(
key: keyof NodeTypeData,
value: ValueType
......@@ -47,17 +30,21 @@ function NodeTypeEntry({
setChanged(true);
}
Object.assign(referenceData, { [key]: value });
onNodeTypeDataChange([referenceData], false);
Object.assign(nodeType, { [key]: value });
onNodeTypeDataChange([nodeType], false);
};
const handleColorChange = (color: string) => {
if (isValidColor(color)) {
handleDataChange("color", color);
setTmpColor(undefined);
} else {
setTmpColor(color);
}
const handleColorChange = (part: keyof ColorData, value: string) => {
// Parse new color
let colorValue = parseInt(value);
colorValue = Math.max(colorValue, 0);
colorValue = Math.min(colorValue, 255);
const newColor: ColorData = Object.assign({}, nodeType.color, {
[part]: colorValue,
});
handleDataChange("color", newColor);
};
const [changed, setChanged] = useState(false);
......@@ -82,13 +69,33 @@ function NodeTypeEntry({
}
/>
<br />
<label htmlFor="node-type-color">Color</label>
<label>Color</label>
<br />
<label htmlFor="node-type-color-r">R</label>
<input
id="node-type-color-r"
className="node-type-color"
type={"text"}
value={tmpColor !== undefined ? tmpColor : nodeType.color}
onChange={(event) => handleColorChange(event.target.value)}
type={"number"}
value={nodeType.color.r.toString()}
onChange={(event) => handleColorChange("r", event.target.value)}
/>
<br />
<label htmlFor="node-type-color-g">G</label>
<input
id="node-type-color-g"
className="node-type-color"
type={"number"}
value={nodeType.color.g.toString()}
onChange={(event) => handleColorChange("g", event.target.value)}
/>
<br />
<label htmlFor="node-type-color-b">B</label>
<input
id="node-type-color-b"
className="node-type-color"
type={"number"}
value={nodeType.color.b.toString()}
onChange={(event) => handleColorChange("b", event.target.value)}
/>
<br />
<button onClick={() => onNodeTypeSelect(nodeType)}>
......
......@@ -48,7 +48,7 @@ export class DynamicGraph extends Common.Graph {
data = {
id: ++this.nextObjectGroupId,
name: "Unnamed",
color: "#000000",
color: { r: 0, g: 0, b: 0 },
};
}
return super.createObjectGroup(data);
......
......@@ -5,6 +5,7 @@ import { Node } from "../common/graph/node";
import { ForceGraph2D } from "react-force-graph";
import { Link } from "../common/graph/link";
import { Coordinate2D } from "../common/graph/graph";
import { colorToRGB } from "../common/helpers";
export class GraphRenderer2D extends React.PureComponent<
InferType<typeof GraphRenderer2D.propTypes>,
......@@ -274,7 +275,7 @@ export class GraphRenderer2D extends React.PureComponent<
// Inner circle
ctx.beginPath();
ctx.arc(node.x, node.y, 4 * 0.3, 0, 2 * Math.PI, false);
ctx.fillStyle = node.type.color;
ctx.fillStyle = colorToRGB(node.type.color);
ctx.fill();
}
......@@ -316,8 +317,8 @@ export class GraphRenderer2D extends React.PureComponent<
);
// Have reversed colors
// Color at source node referencing the target node and vice versa
gradient.addColorStop(0, link.target.type.color);
gradient.addColorStop(1, link.source.type.color);
gradient.addColorStop(0, colorToRGB(link.target.type.color));
gradient.addColorStop(1, colorToRGB(link.source.type.color));
let lineWidth = 0.5;
if (
......@@ -379,7 +380,7 @@ export class GraphRenderer2D extends React.PureComponent<
nodeCanvasObjectMode={() => "after"}
linkCanvasObject={this.handleLinkCanvasObject}
linkCanvasObjectMode={() => "replace"}
nodeColor={(node: Node) => node.type.color}
nodeColor={(node: Node) => colorToRGB(node.type.color)}
onNodeDrag={this.handleNodeDrag}
onLinkRightClick={(link: Link) =>
this.props.onLinkDeletion([link.id])
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment