Get id using useParams hook in functional component - react router dom v6 - javascript
I am following Colt Steele's React course. Sadly, the course is outdated so I chose to migrate to the latest versions of libraries myself.
Coming to the point, I am now facing this error where I am not able to extract URL params using the useParams hook in my functional component. I am pasting my code below for the community to check.
App.js
import Palette from './Palette';
import seedPalettes from './assets/seedPalettes'
import './css/App.css'
import { generatePalette } from './assets/colorHelpers';
import { Routes, Route, Link, useParams } from 'react-router-dom';
function App() {
const { id } = useParams()
const findPalette = id => {
return seedPalettes.find(function (palette) {
return palette.id == id;
})
}
console.log(id);
return (
<div className='App'>
<Routes>
<Route path='/' element={<h1>Welcome Home</h1>} />
<Route path='/palette/:id' element={<Palette palette={generatePalette(findPalette(id))} />} />
</Routes>
{/* <Link to='/palette'>See Palette</Link> */}
{/* <Palette palette={generatePalette(seedPalettes[4])} /> */}
</div>
);
}
export default App;
seedPalettes.js
export default [
{
paletteName: "Material UI Colors",
id: "material-ui-colors",
emoji: "🎨",
colors: [
{ name: "red", color: "#F44336" },
{ name: "pink", color: "#E91E63" },
{ name: "purple", color: "#9C27B0" },
{ name: "deeppurple", color: "#673AB7" },
{ name: "indigo", color: "#3F51B5" },
{ name: "blue", color: "#2196F3" },
{ name: "lightblue", color: "#03A9F4" },
{ name: "cyan", color: "#00BCD4" },
{ name: "teal", color: "#009688" },
{ name: "green", color: "#4CAF50" },
{ name: "lightgreen", color: "#8BC34A" },
{ name: "lime", color: "#CDDC39" },
{ name: "yellow", color: "#FFEB3B" },
{ name: "amber", color: "#FFC107" },
{ name: "orange", color: "#FF9800" },
{ name: "deeporange", color: "#FF5722" },
{ name: "brown", color: "#795548" },
{ name: "grey", color: "#9E9E9E" },
{ name: "bluegrey", color: "#607D8B" }
]
},
{
paletteName: "Flat UI Colors v1",
id: "flat-ui-colors-v1",
emoji: "🤙",
colors: [
{ name: "Turquoise", color: "#1abc9c" },
{ name: "Emerald", color: "#2ecc71" },
{ name: "PeterRiver", color: "#3498db" },
{ name: "Amethyst", color: "#9b59b6" },
{ name: "WetAsphalt", color: "#34495e" },
{ name: "GreenSea", color: "#16a085" },
{ name: "Nephritis", color: "#27ae60" },
{ name: "BelizeHole", color: "#2980b9" },
{ name: "Wisteria", color: "#8e44ad" },
{ name: "MidnightBlue", color: "#2c3e50" },
{ name: "SunFlower", color: "#f1c40f" },
{ name: "Carrot", color: "#e67e22" },
{ name: "Alizarin", color: "#e74c3c" },
{ name: "Clouds", color: "#ecf0f1" },
{ name: "Concrete", color: "#95a5a6" },
{ name: "Orange", color: "#f39c12" },
{ name: "Pumpkin", color: "#d35400" },
{ name: "Pomegranate", color: "#c0392b" },
{ name: "Silver", color: "#bdc3c7" },
{ name: "Asbestos", color: "#7f8c8d" }
]
},
{
paletteName: "Flat UI Colors Dutch",
id: "flat-ui-colors-dutch",
emoji: "🇳🇱",
colors: [
{ name: "Sunflower", color: "#FFC312" },
{ name: "Energos", color: "#C4E538" },
{ name: "BlueMartina", color: "#12CBC4" },
{ name: "LavenderRose", color: "#FDA7DF" },
{ name: "BaraRose", color: "#ED4C67" },
{ name: "RadiantYellow", color: "#F79F1F" },
{ name: "AndroidGreen", color: "#A3CB38" },
{ name: "MediterraneanSea", color: "#1289A7" },
{ name: "LavenderTea", color: "#D980FA" },
{ name: "VerryBerry", color: "#B53471" },
{ name: "PuffinsBill", color: "#EE5A24" },
{ name: "PixelatedGrass", color: "#009432" },
{ name: "MerchantMarineBlue", color: "#0652DD" },
{ name: "ForgottenPurple", color: "#9980FA" },
{ name: "HollyHock", color: "#833471" },
{ name: "RedPigment", color: "#EA2027" },
{ name: "TurkishAqua", color: "#006266" },
{ name: "20000LeaguesUnderTheSea", color: "#1B1464" },
{ name: "CircumorbitalRing", color: "#5758BB" },
{ name: "MagentaPurple", color: "#6F1E51" }
]
},
{
paletteName: "Flat UI Colors American",
id: "flat-ui-colors-american",
emoji: "🇺🇸",
colors: [
{ name: "LightGreenishBlue", color: "#55efc4" },
{ name: "FadedPoster", color: "#81ecec" },
{ name: "GreenDarnerTail", color: "#74b9ff" },
{ name: "ShyMoment", color: "#a29bfe" },
{ name: "CityLights", color: "#dfe6e9" },
{ name: "MintLeaf", color: "#00b894" },
{ name: "RobinsEggBlue", color: "#00cec9" },
{ name: "ElectronBlue", color: "#0984e3" },
{ name: "ExodusFruit", color: "#6c5ce7" },
{ name: "SoothingBreeze", color: "#b2bec3" },
{ name: "SourLemon", color: "#ffeaa7" },
{ name: "FirstDate", color: "#fab1a0" },
{ name: "PinkGlamour", color: "#ff7675" },
{ name: "Pico8Pink", color: "#fd79a8" },
{ name: "AmericanRiver", color: "#636e72" },
{ name: "BrightYarrow", color: "#fdcb6e" },
{ name: "OrangeVille", color: "#e17055" },
{ name: "Chi-Gong", color: "#d63031" },
{ name: "PrunusAvium", color: "#e84393" },
{ name: "DraculaOrchid", color: "#2d3436" }
]
},
{
paletteName: "Flat UI Colors Aussie",
id: "flat-ui-colors-aussie",
emoji: "🇦🇺",
colors: [
{ name: "Beekeeper", color: "#f6e58d" },
{ name: "SpicedNectarine", color: "#ffbe76" },
{ name: "PinkGlamour", color: "#ff7979" },
{ name: "JuneBud", color: "#badc58" },
{ name: "CoastalBreeze", color: "#dff9fb" },
{ name: "Turbo", color: "#f9ca24" },
{ name: "QuinceJelly", color: "#f0932b" },
{ name: "CarminePink", color: "#eb4d4b" },
{ name: "PureApple", color: "#6ab04c" },
{ name: "HintOfIcePack", color: "#c7ecee" },
{ name: "MiddleBlue", color: "#7ed6df" },
{ name: "Heliotrope", color: "#e056fd" },
{ name: "ExodusFruit", color: "#686de0" },
{ name: "DeepKoamaru", color: "#30336b" },
{ name: "SoaringEagle", color: "#95afc0" },
{ name: "GreenlandGreen", color: "#22a6b3" },
{ name: "SteelPink", color: "#be2edd" },
{ name: "Blurple", color: "#4834d4" },
{ name: "DeepCove", color: "#130f40" },
{ name: "WizardGrey", color: "#535c68" }
]
},
{
paletteName: "Flat UI Colors British",
id: "flat-ui-colors-british",
emoji: "🇬🇧",
colors: [
{ name: "ProtossPylon", color: "#00a8ff" },
{ name: "Periwinkle", color: "#9c88ff" },
{ name: "Rise-N-Shine", color: "#fbc531" },
{ name: "DownloadProgress", color: "#4cd137" },
{ name: "Seabrook", color: "#487eb0" },
{ name: "VanaDylBlue", color: "#0097e6" },
{ name: "MattPurple", color: "#8c7ae6" },
{ name: "NanohanachaGold", color: "#e1b12c" },
{ name: "SkirretGreen", color: "#44bd32" },
{ name: "Naval", color: "#40739e" },
{ name: "NasturcianFlower", color: "#e84118" },
{ name: "LynxWhite", color: "#f5f6fa" },
{ name: "BlueberrySoda", color: "#7f8fa6" },
{ name: "MazarineBlue", color: "#273c75" },
{ name: "BlueNights", color: "#353b48" },
{ name: "HarleyOrange", color: "#c23616" },
{ name: "HintOfPensive", color: "#dcdde1" },
{ name: "ChainGangGrey", color: "#718093" },
{ name: "PicoVoid", color: "#192a56" },
{ name: "ElectroMagnetic", color: "#2f3640" }
]
},
{
paletteName: "Flat UI Colors Spanish",
id: "flat-ui-colors-spanish",
emoji: "🇪🇸",
colors: [
{ name: "JacksonsPurple", color: "#40407a" },
{ name: "C64Purple", color: "#706fd3" },
{ name: "SwanWhite", color: "#f7f1e3" },
{ name: "SummerSky", color: "#34ace0" },
{ name: "CelestialGreen", color: "#33d9b2" },
{ name: "LuckyPoint", color: "#2c2c54" },
{ name: "Liberty", color: "#474787" },
{ name: "HotStone", color: "#aaa69d" },
{ name: "DevilBlue", color: "#227093" },
{ name: "PalmSpringsSplash", color: "#218c74" },
{ name: "FlourescentRed", color: "#ff5252" },
{ name: "SyntheticPumpkin", color: "#ff793f" },
{ name: "CrocodileTooth", color: "#d1ccc0" },
{ name: "MandarinSorbet", color: "#ffb142" },
{ name: "SpicedButterNut", color: "#ffda79" },
{ name: "EyeOfNewt", color: "#b33939" },
{ name: "ChileanFire", color: "#cd6133" },
{ name: "GreyPorcelain", color: "#84817a" },
{ name: "AlamedaOchre", color: "#cc8e35" },
{ name: "Desert", color: "#ccae62" }
]
},
{
paletteName: "Flat UI Colors Indian",
id: "flat-ui-colors-indian",
emoji: "🇮🇳",
colors: [
{ name: "OrchidOrange", color: "#FEA47F" },
{ name: "SpiroDiscoBall", color: "#25CCF7" },
{ name: "HoneyGlow", color: "#EAB543" },
{ name: "SweetGarden", color: "#55E6C1" },
{ name: "FallingStar", color: "#CAD3C8" },
{ name: "RichGardenia", color: "#F97F51" },
{ name: "ClearChill", color: "#1B9CFC" },
{ name: "WhitePepper", color: "#F8EFBA" },
{ name: "Keppel", color: "#58B19F" },
{ name: "ShipsOfficer", color: "#2C3A47" },
{ name: "FieryFuchsia", color: "#B33771" },
{ name: "BlueBell", color: "#3B3B98" },
{ name: "GeorgiaPeach", color: "#FD7272" },
{ name: "OasisStream", color: "#9AECDB" },
{ name: "BrightUbe", color: "#D6A2E8" },
{ name: "MagentaPurple", color: "#6D214F" },
{ name: "EndingNavyBlue", color: "#182C61" },
{ name: "SasquatchSocks", color: "#FC427B" },
{ name: "PineGlade", color: "#BDC581" },
{ name: "HighlighterLavender", color: "#82589F" }
]
},
{
paletteName: "Flat UI Colors French",
id: "flat-ui-colors-french",
emoji: "🇫🇷",
colors: [
{ name: "FlatFlesh", color: "#fad390" },
{ name: "MelonMelody", color: "#f8c291" },
{ name: "Livid", color: "#6a89cc" },
{ name: "Spray", color: "#82ccdd" },
{ name: "ParadiseGreen", color: "#b8e994" },
{ name: "SquashBlossom", color: "#f6b93b" },
{ name: "MandarinRed", color: "#e55039" },
{ name: "AzraqBlue", color: "#4a69bd" },
{ name: "Dupain", color: "#60a3bc" },
{ name: "AuroraGreen", color: "#78e08f" },
{ name: "IcelandPoppy", color: "#fa983a" },
{ name: "TomatoRed", color: "#eb2f06" },
{ name: "YueGuangBlue", color: "#1e3799" },
{ name: "GoodSamaritan", color: "#3c6382" },
{ name: "Waterfall", color: "#38ada9" },
{ name: "CarrotOrange", color: "#e58e26" },
{ name: "JalapenoRed", color: "#b71540" },
{ name: "DarkSapphire", color: "#0c2461" },
{ name: "ForestBlues", color: "#0a3d62" },
{ name: "ReefEncounter", color: "#079992" }
]
}
];
colorHelpers.js
This is where I am creating my palette from a seed palette.
import chroma from 'chroma-js';
const levels = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900];
const generatePalette = (starterPalette) => {
let newPalette = {
paletteName: starterPalette.paletteName,
id: starterPalette.id,
emoji: starterPalette.emoji,
colors: {}
};
for (let level of levels) {
newPalette.colors[level] = [];
}
for (let color of starterPalette.colors) {
let scale = generateScale(color.color, 10).reverse();
for (let i in scale) {
newPalette.colors[levels[i]].push({
name: `${color.name} ${levels[i]}`,
id: color.name.toLowerCase().replace(/ /g, '-'),
hex: scale[i],
rgb: chroma(scale[i]).css().replace(/,/g, ', '),
rgba: chroma(scale[i]).css().replace('rgb', 'rgba').replace(')', ',1.0)').replace(/,/g, ', ')
})
}
}
return newPalette;
}
const getRange = (hexColor) => {
const end = '#fff';
return [
chroma(hexColor).darken(1.4).hex(),
hexColor,
end
]
}
const generateScale = (hexColor, numOfColors) => {
return chroma.scale(getRange(hexColor)).mode('lab').colors(numOfColors);
}
export { generatePalette };
Please help me, as a beginner, it is very overwhelming :(. Also, sorry for the bulky code blocks.
The useParams hook can only access the route match params of a Route within the context of the Routes component rendering it. App is outside the Routes component that renders a route rendering path='/palette/:id'.
You can create a wrapper component to "sip" the id route match param and do the filtering.
import seedPalettes from './assets/seedPalettes';
const findPalette = id => seedPalettes.find(palette => palette.id == id);
const PaletteWrapper = () => {
const { id } = useParams();
const palette = generatePalette(findPalette(id))
return <Palette palette={palette} />;
};
...
function App() {
return (
<div className='App'>
<Routes>
<Route path='/' element={<h1>Welcome Home</h1>} />
<Route path='/palette/:id' element={<PaletteWrapper />} />
</Routes>
</div>
);
}
Related
react-d3-graph cannot move nodes inside a spesific project
I modified this component in a seperate project. It was working just fine. Then i copied that segment into my main project. The graph is rendered with no problem however, when i try to change position of any node it does not work and creates these errors. enter image description here The versions of d3 are the same in both of the projects. I thought it might be caused by some other component and i tried to render it in app.js on its own and it still did not work. I wonder what causes this and cannot find it. import * as React from "react"; import { Graph } from "react-d3-graph"; const data = { nodes: [ { id: "NEWS1", color: "black", size: 800 }, { id: "NEWS2", color: "black", size: 800 }, { id: "NEWS3", color: "black", size: 800 }, { id: "NEWS4", color: "black", size: 800 }, { id: "Sharer1", color: "red", size: 300 }, { id: "Sharer2", color: "green", size: 300 }, { id: "Sharer3", color: "red", size: 300 }, { id: "Sharer4", color: "red", size: 300 }, { id: "Sharer11", color: "red", size: 300 }, { id: "Sharer12", color: "red", size: 300 }, { id: "Sharer13", color: "red", size: 300 }, { id: "Sharer21", color: "red", size: 300 }, { id: "Sharer22", color: "red", size: 300 }, { id: "Sharer23", color: "red", size: 300 }, { id: "Sharer31", color: "red", size: 300 }, { id: "Sharer32", color: "red", size: 300 }, { id: "Sharer33", color: "red", size: 300 }, { id: "Sharer41", color: "red", size: 300 }, { id: "Sharer411", color: "red", size: 300 }, { id: "Sharer4111", color: "red", size: 300 } ], links: [ { source: "NEWS1", target: "Sharer1" }, { source: "NEWS2", target: "Sharer2" }, { source: "NEWS3", target: "Sharer3" }, { source: "NEWS4", target: "Sharer4" }, { source: "Sharer1", target: "Sharer11" }, { source: "Sharer1", target: "Sharer12" }, { source: "Sharer1", target: "Sharer13" }, { source: "Sharer2", target: "Sharer21" }, { source: "Sharer2", target: "Sharer22" }, { source: "Sharer2", target: "Sharer23" }, { source: "Sharer3", target: "Sharer31" }, { source: "Sharer3", target: "Sharer32" }, { source: "Sharer3", target: "Sharer33" }, { source: "Sharer4", target: "Sharer41" }, { source: "Sharer41", target: "Sharer411" }, { source: "Sharer411", target: "Sharer4111" } ] }; const myConfig = { nodeHighlightBehavior: true, node: { color: "lightgreen", size: 120, labelProperty: "id", highlightStrokeColor: "blue" }, link: { type: "LINE_SMOOTH", highlightColor: "red" } }; function NetworkGraph() { const [state,showModal] = React.useState(false) const handleShowMessageClick = (id) => showModal(true); const handleCloseModal = (id) => showModal(false); const onClickGraph = () => { // window.alert(`Clicked the graph background`); }; const onClickNode = (nodeId) => { // }; const onDoubleClickNode = (nodeId) => { // window.alert(`Double clicked node ${nodeId}`); }; const onRightClickNode = (event, nodeId) => { // window.alert(`Right clicked node ${nodeId}`); }; const onMouseOverNode = (nodeId) => { //handleShowMessageClick(nodeId); }; const onMouseOutNode = (nodeId) => { //handleCloseModal(nodeId); }; const onClickLink = (source, target) => { // window.alert(`Clicked link between ${source} and ${target}`); }; const onRightClickLink = (event, source, target) => { // window.alert(`Right clicked link between ${source} and ${target}`); }; const onMouseOverLink = (source, target) => { // window.alert(`Mouse over in link between ${source} and ${target}`); }; const onMouseOutLink = (source, target) => { // window.alert(`Mouse out link between ${source} and ${target}`); }; return ( <div> <Graph id="graph-id" data={data} config={myConfig} onClickNode={onClickNode} onRightClickNode={onRightClickNode} onClickGraph={onClickGraph} onClickLink={onClickLink} onRightClickLink={onRightClickLink} onMouseOverNode={onMouseOverNode} onMouseOutNode={onMouseOutNode} onMouseOverLink={onMouseOverLink} onMouseOutLink={onMouseOutLink} /> </div> ); } export default NetworkGraph
Get trees closer together
I am using tree layout and I have multiple trees (multiple roots). How can I get the trees to be packed together and fill the empty space using layout. Here is an example of my trees: unpacked trees image I want them to be more like this: packed trees image here is my current layout: let myDiagram = new go.Diagram("myDiagramDiv", { layout: new go.TreeLayout({ treeStyle: go.TreeLayout.StyleLastParents, arrangement: go.TreeLayout.ArrangementHorizontal, compaction: go.TreeLayout.CompactionBlock, // properties for most of the tree: angle: 90, layerSpacing: 35, // properties for the "last parents": alternateAngle: 90, alternateLayerSpacing: 35, alternateAlignment: go.TreeLayout.AlignmentBus, alternateNodeSpacing: 20, }) });
#HumanTarget has the right idea. Here's an example: <script type="module"> import * as go from "../release/go-module.js"; import { ArrangingLayout } from "../extensionsJSM/ArrangingLayout.js"; import { PackedLayout } from "../extensionsJSM/PackedLayout.js"; const $ = go.GraphObject.make; const myDiagram = $(go.Diagram, "myDiagramDiv", { layout: $(ArrangingLayout, { primaryLayout: $(go.TreeLayout, { angle: 90 }), arrangingLayout: $(PackedLayout, { spacing: 10 }), }) }); myDiagram.nodeTemplate = $(go.Node, "Auto", $(go.Shape, { fill: "white" }, new go.Binding("fill", "color")), $(go.TextBlock, { margin: 8 }, new go.Binding("text")) ); myDiagram.model = new go.GraphLinksModel( [ { key: 1, text: "Alpha", color: "lightblue" }, { key: 2, text: "Beta", color: "orange" }, { key: 3, text: "Gamma", color: "lightgreen" }, { key: 4, text: "Delta", color: "pink" }, { key: 5, text: "Epsilon", color: "lightblue" }, { key: 6, text: "Zeta", color: "orange" }, { key: 7, text: "Eta", color: "lightgreen" }, { key: 8, text: "Theta", color: "pink" }, { key: 9, text: "Iota", color: "lightblue" }, { key: 10, text: "Kappa", color: "orange" }, { key: 11, text: "Lambda", color: "lightgreen" }, { key: 12, text: "Mu", color: "pink" }, { key: 13, text: "Nu", color: "lightblue" }, { key: 14, text: "Xi", color: "orange" }, { key: 15, text: "Omicron", color: "lightgreen" }, { key: 16, text: "Pi", color: "pink" }, ], [ { from: 1, to: 2 }, { from: 1, to: 3 }, { from: 4, to: 5 }, { from: 4, to: 6 }, { from: 6, to: 7 }, { from: 8, to: 9 }, { from: 9, to: 10 }, { from: 11, to: 12 }, { from: 13, to: 14 }, { from: 13, to: 15 }, { from: 13, to: 16 }, ]); </script> Result: But note that PackedLayout will treat each subtree as occupying a rectangular area, so it won't try to fit subtrees together where one or both of the subtrees has some empty space.
Multiple data values for label text in cytoscape.js
I am trying to add multiple values to a label in cytoscape.js like so - { "selector": "edge", "style": { "curve-style": "haystack", "text-wrap": "wrap", "label": "data(count)" + "data(edgevalue)", "font-size": "8px", "color": "black", "haystack-radius": "0.5", "opacity": "0.4", "line-color": "#bbb", "width": "mapData(weight, 0, 1, 1, 8)", } }, However this is literally just displaying - data(count)data(edgevalue) As the label text. If I remove one or the other it prints the correct value for each. I tried adding a '\n' for a line break, which created a line break but the values were just the same as above. I also tried data(count + edgevalue) to no avail. How can I achieve multiple data attributes in a label text?
You can use mappers to get the correct data into your styles: mappers Also, I usually use template strings: { label: function (element) { return `${element.data("attribute_01")} + ${element.data("attribute_02")}` } } Here you can see a simple example: document.addEventListener("DOMContentLoaded", function() { var cy = (window.cy = cytoscape({ container: document.getElementById("cy"), // demo your layout layout: { name: "klay" // some more options here... }, style: [{ selector: "node", style: { "background-color": "#dd4de2" } }, { selector: ".leaf", style: { "background-color": "#000" } }, { selector: "edge", style: { "curve-style": "bezier", "target-arrow-shape": "triangle", "line-color": "#dd4de2", "target-arrow-color": "#dd4de2", "opacity": "0.5", "label": function(node) { return `${node.data("source")} -> ${node.data("target")}` } } } ], elements: { nodes: [{ data: { id: "n0" } }, { data: { id: "n1" } }, { data: { id: "n2" } }, { data: { id: "n3" } }, { data: { id: "n4" } }, { data: { id: "n5" } }, { data: { id: "n6" } }, { data: { id: "n7" } }, { data: { id: "n8" } }, { data: { id: "n9" } }, { data: { id: "n10" } }, { data: { id: "n11" } }, { data: { id: "n12" } }, { data: { id: "n13" } }, { data: { id: "n14" } }, { data: { id: "n15" } } ], edges: [{ data: { source: "n0", target: "n1" } }, { data: { source: "n1", target: "n2" } }, { data: { source: "n1", target: "n3" } }, { data: { source: "n2", target: "n4" } }, { data: { source: "n4", target: "n5" } }, { data: { source: "n4", target: "n6" } }, { data: { source: "n6", target: "n7" } }, { data: { source: "n6", target: "n8" } }, { data: { source: "n8", target: "n9" } }, { data: { source: "n8", target: "n10" } }, { data: { source: "n10", target: "n11" } }, { data: { source: "n11", target: "n12" } }, { data: { source: "n12", target: "n13" } }, { data: { source: "n13", target: "n14" } }, { data: { source: "n13", target: "n15" } } ] } })); cy.nodes().leaves().addClass("leaf"); }); body { font-family: helvetica neue, helvetica, liberation sans, arial, sans-serif; font-size: 14px; } #cy { position: absolute; left: 0; top: 0; bottom: 0; right: 0; z-index: 999; } <html> <head> <script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script> <script src="https://unpkg.com/klayjs#0.4.1/klay.js"></script> <script src="https://cdn.jsdelivr.net/npm/cytoscape-klay#3.1.3/cytoscape-klay.min.js"></script> </head> <body> <div id="cy"></div> </body> </html>
Limit drop area with Cytoscape
I'm trying to make a web designer with Cytoscape, and I'd like to set a restricted area in which the user can drop a node. In essence: the user can drop a node out of the "canvas" (just a rectangle in CSS) and they get lost. Like in the image below: As you can see, my node is shaped as a rectangle, which can be dropped out of the zone I'm trying to limit. What should I do? Thanks!
The following code snippet uses both the built in cy.fit() function as well as the cytoscape-autopan-on-drag extension. document.addEventListener("DOMContentLoaded", function() { var cy = (window.cy = cytoscape({ container: document.getElementById("cy"), style: [{ selector: "node", style: { content: "data(id)" } }, { selector: "edge", style: { "target-arrow-shape": "triangle" } }, { selector: ":selected", style: {} } ], elements: { nodes: [{ data: { id: "n0" } }, { data: { id: "n1" } }, { data: { id: "n2" } }, { data: { id: "n3" } }, { data: { id: "n4" } }, { data: { id: "n5" } }, { data: { id: "n6" } }, { data: { id: "n7" } }, { data: { id: "n8" } }, { data: { id: "n9" } }, { data: { id: "n10" } }, { data: { id: "n11" } }, { data: { id: "n12" } }, { data: { id: "n13" } }, { data: { id: "n14" } }, { data: { id: "n15" } }, { data: { id: "n16" } } ], edges: [{ data: { source: "n0", target: "n1" } }, { data: { source: "n1", target: "n2" } }, { data: { source: "n1", target: "n3" } }, { data: { source: "n4", target: "n5" } }, { data: { source: "n4", target: "n6" } }, { data: { source: "n6", target: "n7" } }, { data: { source: "n6", target: "n8" } }, { data: { source: "n8", target: "n9" } }, { data: { source: "n8", target: "n10" } }, { data: { source: "n11", target: "n12" } }, { data: { source: "n12", target: "n13" } }, { data: { source: "n13", target: "n14" } }, { data: { source: "n13", target: "n15" } } ] }, layout: { name: "dagre", padding: 50 } })); // demo your core ext cy.autopanOnDrag({ /* Options here */ }); cy.on('tapdrag', 'node', function() { cy.fit(cy.elements(), 50); cy.center(); }) }); body { font-family: helvetica neue, helvetica, liberation sans, arial, sans-serif; font-size: 14px; } #cy { position: absolute; width: 60%; height: 60%; border: 1px solid gray; } <html> <head> <script src="https://cdn.jsdelivr.net/npm/jquery#3.4.1/dist/jquery.min.js"></script> <script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script> <script src="https://unpkg.com/dagre#0.7.4/dist/dagre.js"></script> <script src="https://cdn.jsdelivr.net/npm/cytoscape-dagre#2.1.0/cytoscape-dagre.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/cytoscape-autopan-on-drag#2.2.0/cytoscape-autopan-on-drag.min.js"></script> </head> <body> <div id="cy"></div> </body> </html>
Add CSS or style to each node in swimlane (GOjs library)
I am currently using GOjs library's new graph which is the swimlane. My problem is I want to add DIFFERENT styles to each node (like, one node has a bg-color of red, the other is blue, others are green and etc). Anyone knows how to do this? Any help is greatly appreciated. Or anyone can suggest another library that does my thing.
As you haven't posted your code Ill be working off the swinlane examples (http://www.gojs.net/latest/samples/swimlanes.html). If you have a look at the documentation for nodes (http://gojs.net/beta/intro/nodes.html) you can see how they are changing the color there. diagram.nodeTemplate = $(go.Node, "Auto", $(go.Shape, "Rectangle", new go.Binding("fill", "color")), $(go.TextBlock, { margin: 5 }, new go.Binding("text", "key")) ); diagram.model.nodeDataArray = [ { key: "Alpha", color: "lightblue" } ]; In the swimlane example they have the following relevant code: myDiagram.nodeTemplate = $(go.Node, "Auto", $(go.Shape, "Rectangle", { fill: "white", portId: "", cursor: "pointer", fromLinkable: true, toLinkable: true }), $(go.TextBlock, { margin: 5 }, new go.Binding("text", "key")), // limit dragging of Nodes to stay within the containing Group, defined above { dragComputation: stayInGroup, mouseDrop: function (e, node) { // dropping a copy of some Nodes and Links onto this Node adds them to this Node's Group if (!e.shift && !e.control) return; // cannot change groups with an unmodified drag-and-drop var grp = node.containingGroup; if (grp !== null) { var ok = grp.addMembers(node.diagram.selection, true); if (!ok) grp.diagram.currentTool.doCancel(); } }, layoutConditions: go.Part.LayoutAdded | go.Part.LayoutNodeSized } ); myDiagram.model = new go.GraphLinksModel( [ // node data { key: "Lane1", isGroup: true, color: "lightblue" }, { key: "Lane2", isGroup: true, color: "lightgreen" }, { key: "Lane3", isGroup: true, color: "lightyellow" }, { key: "Lane4", isGroup: true, color: "orange" }, { key: "oneA", group: "Lane1" }, { key: "oneB", group: "Lane1" }, { key: "oneC", group: "Lane1" }, { key: "oneD", group: "Lane1" }, { key: "twoA", group: "Lane2" }, { key: "twoB", group: "Lane2" }, { key: "twoC", group: "Lane2" }, { key: "twoD", group: "Lane2" }, { key: "twoE", group: "Lane2" }, { key: "twoF", group: "Lane2" }, { key: "twoG", group: "Lane2" }, { key: "fourA", group: "Lane4" }, { key: "fourB", group: "Lane4" }, { key: "fourC", group: "Lane4" }, { key: "fourD", group: "Lane4" }, ], [ // link data { from: "oneA", to: "oneB" }, { from: "oneA", to: "oneC" }, { from: "oneB", to: "oneD" }, { from: "oneC", to: "oneD" }, { from: "twoA", to: "twoB" }, { from: "twoA", to: "twoC" }, { from: "twoA", to: "twoF" }, { from: "twoB", to: "twoD" }, { from: "twoC", to: "twoD" }, { from: "twoD", to: "twoG" }, { from: "twoE", to: "twoG" }, { from: "twoF", to: "twoG" }, { from: "fourA", to: "fourB" }, { from: "fourB", to: "fourC" }, { from: "fourC", to: "fourD" } ]); To allow each node their own fill color you change the line { fill: "white", portId: "", cursor: "pointer", fromLinkable: true, toLinkable: true }), to { fill: "lightblue", portId: "", cursor: "pointer", fromLinkable: true, toLinkable: true }, new go.Binding("fill", "color")), After making those changes you can then specify what fill colors you want in the node data. Note that I changed the original fill value above to lighblue. Now lightblue will be the default color if you do not specify a color for a node (fourD will be lightblue): myDiagram.model = new go.GraphLinksModel( [ // node data { key: "Lane1", isGroup: true, color: "lightblue" }, { key: "Lane2", isGroup: true, color: "lightgreen" }, { key: "Lane3", isGroup: true, color: "lightyellow" }, { key: "Lane4", isGroup: true, color: "orange" }, { key: "oneA", group: "Lane1", color: "green" }, { key: "oneB", group: "Lane1", color: "red" }, { key: "oneC", group: "Lane1", color: "yellow" }, { key: "oneD", group: "Lane1", color: "purple" }, { key: "twoA", group: "Lane2", color: "orange" }, { key: "twoB", group: "Lane2", color: "green" }, { key: "twoC", group: "Lane2", color: "red" }, { key: "twoD", group: "Lane2", color: "yellow" }, { key: "twoE", group: "Lane2", color: "purple" }, { key: "twoF", group: "Lane2", color: "orange" }, { key: "twoG", group: "Lane2", color: "green" }, { key: "fourA", group: "Lane4", color: "red" }, { key: "fourB", group: "Lane4", color: "yellow" }, { key: "fourC", group: "Lane4", color: "purple" }, { key: "fourD", group: "Lane4" }, ], [ // link data { from: "oneA", to: "oneB" }, { from: "oneA", to: "oneC" }, { from: "oneB", to: "oneD" }, { from: "oneC", to: "oneD" }, { from: "twoA", to: "twoB" }, { from: "twoA", to: "twoC" }, { from: "twoA", to: "twoF" }, { from: "twoB", to: "twoD" }, { from: "twoC", to: "twoD" }, { from: "twoD", to: "twoG" }, { from: "twoE", to: "twoG" }, { from: "twoF", to: "twoG" }, { from: "fourA", to: "fourB" }, { from: "fourB", to: "fourC" }, { from: "fourC", to: "fourD" } ]);