this is my three.js code in react, I want to add button inside the group for the glb file how can i do it?
I tried most of them, i used <mesh> as button didnt work, same goes for <block>
also how do i put colors on my onChange, it's not reading it.
function Violon({ ...props }) {
const group = useRef()
const snap = useSnapshot(state)
// Animate model
const [violonBody, setviolonBody] = useState('')
const [violonStick, setviolonStick] = useState('')
const [violonChincrest, setviolonChincrest] = useState('')
const addCustomizations = () => {
//{object}
Axios.post('http://localhost:5000/customizations', {
violonBody: violonBody,
violonStick: violonStick,
violonChincrest: violonChincrest,
user: JSON.parse(localStorage.getItem('user'))
}).then(() => {
console.log('success')
})
}
// Cursor showing current color
const [hovered, set] = useState(null)
const { nodes, materials } = useGLTF('v.glb')
return (
<group
ref={group}
dispose={null}
onPointerOver={(e) => (e.stopPropagation(), set(e.object.material.name))}
onPointerOut={(e) => e.intersections.length === 0 && set(null)}
onPointerMissed={() => (state.current = null)}
onPointerDown={(e) => (e.stopPropagation(), (state.current = e.object.material.name))}>
<mesh
geometry={nodes.subD3_Bout001.geometry}
material={materials.defaultMat002}
material-color={snap.items.defaultMat002}
rotation={[Math.PI / 2, 0, 0]}
onChange={(event) => {
setviolonBody(event.target.value)
}}
/>
<mesh
geometry={nodes.subD3_Bridge.geometry}
material={materials.defaultMat003}
material-color={snap.items.defaultMat003}
rotation={[Math.PI / 2, 0, 0]}
/>
<mesh
geometry={nodes.subD3_Chincrest.geometry}
material={materials.defaultMat004}
material-color={snap.items.defaultMat004}
rotation={[Math.PI / 2, 0, 0]}
onChange={(event) => {
setviolonChincrest(event.target.value)
}}
/>
<mesh
geometry={nodes.subD3_End_pin.geometry}
material={materials.defaultMat005}
material-color={snap.items.defaultMat005}
rotation={[Math.PI / 2, 0, 0]}
/>
<mesh
geometry={nodes.subD3_Eyelet.geometry}
material={materials.defaultMat006}
material-color={snap.items.defaultMat006}
rotation={[Math.PI / 2, 0, 0]}
/>
<mesh
geometry={nodes.subD3_Fingerboard.geometry}
material={materials.defaultMat007}
material-color={snap.items.defaultMat007}
rotation={[Math.PI / 2, 0, 0]}
/>
<mesh
geometry={nodes.subD3_Hair.geometry}
material={materials.defaultMat008}
material-color={snap.items.defaultMat008}
rotation={[Math.PI / 2, 0, 0]}
/>
<mesh
geometry={nodes.subD3_Pegs.geometry}
material={materials.defaultMat009}
material-color={snap.items.defaultMat009}
rotation={[Math.PI / 2, 0, 0]}
/>
<mesh
geometry={nodes['subD3_Scroll-and-neck'].geometry}
material={materials.defaultMat010}
material-color={snap.items.defaultMat010}
rotation={[Math.PI / 2, 0, 0]}
/>
<mesh
geometry={nodes.subD3_Stick.geometry}
material={materials.defaultMat011}
material-color={snap.items.defaultMat011}
rotation={[Math.PI / 2, 0, 0]}
onChange={(event) => {
setviolonStick(event.target.value)
}}
/>
<mesh
geometry={nodes.subD3_Strings.geometry}
material={materials.defaultMat012}
material-color={snap.items.defaultMat012}
rotation={[Math.PI / 2, 0, 0]}
/>
<mesh
geometry={nodes.subD3_Tailpiece.geometry}
material={materials.defaultMat013}
material-color={snap.items.defaultMat013}
rotation={[Math.PI / 2, 0, 0]}
/>
<mesh
geometry={nodes.subD3_Tuners.geometry}
material={materials.defaultMat014}
material-color={snap.items.defaultMat014}
rotation={[Math.PI / 2, 0, 0]}
/>
<mesh
geometry={nodes.subD3_Violin001.geometry}
material={materials.defaultMat015}
material-color={snap.items.defaultMat015}
rotation={[Math.PI / 2, 0, 0]}
/>
</group>
)
}
this is my three.js code in react, I want to add button inside the group for the glb file how can i do it?
Thank you for your helpp!
There is a library called Drei, which allows you to transform a Html section as a 3D mesh.
You could try something like:
<mesh geometry={nodes.subD3_Bout001.geometry}
material={materials.defaultMat002}
material-color={snap.items.defaultMat002}
rotation={[Math.PI / 2, 0, 0]}
onChange={(event) => {
setviolonBody(event.target.value)
}}
/>
<Html transform occlude>
<Button ...props />
</Html>
</Mesh>
The one caveat with Lucas's solution: using Drei, is that there is currently a bug in Firefox that will cause the <Html> component to render completely blurry.
I have the following render function:
render() {
return (
<View style={styles.container}>
<View style={styles.header}>
<Text> Header
</Text>
</View>
<View style={styles.services}>
<Text>Services</Text>
</View>
<View style={styles.chart}>
<VictoryChart>
<VictoryLine
style={{
data: {stroke: "#c43a31"},
parent: {border: "1px solid #ccc"}
}}
data={[
{x: 1, y: 2},
{x: 2, y: 3},
{x: 3, y: 5},
{x: 4, y: 4},
{x: 5, y: 7}
]}
/>
</VictoryChart>
</View>
</View>
);
}
I have some sort of chart in the bottom section of page, But I cannot force the chart to fill the its parent, It kind of overflows from its dedicated section, How can I achieve this?(I tried to use flexWrap but it is no help !)
Here is the preview of what it looks like now:
And here is my style sheet for this simple design:
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F5FCFF',
},
header: {
flex: 1,
backgroundColor: '#e7fe52'
},
services: {
flex: 4,
backgroundColor: '#20fe23'
},
chart: {
flex: 2,
flexWrap: 'wrap',
backgroundColor: '#4fccb0'
}
});
VictoryChart seems to have a default height of 300 and it doesn't adapt to its parent height. So, one way to solve this would be to remove the flex: 2 attribute from the chart style and add manually calculated dimensions. Something like this:
const chartHeight = Dimensions.get("window").height * 0.3;
const chartWidth = Dimensions.get("window").width;
<VictoryChart height={chartHeight} width={chartWidth} >
<VictoryLine
style={{
data: {stroke: "#c43a31"},
parent: {border: "1px solid #ccc"}
}}
data={[
{x: 1, y: 2},
{x: 2, y: 3},
{x: 3, y: 5},
{x: 4, y: 4},
{x: 5, y: 7}
]}
/>
</VictoryChart>
// styles
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F5FCFF',
},
header: {
flex: 1,
backgroundColor: '#e7fe52'
},
services: {
flex: 4,
backgroundColor: '#20fe23'
},
chart: {
//remove flex from here
backgroundColor: '#4fccb0'
}
});
Although this is not perfect it works, but I would set a minimum height for the chart. I mean if the available space is too small, it won't look nice.
In this case you could wrap your screen inside a ScrollView.
each flex container is one flex try to divide your component into 1
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F5FCFF',
},
header: {
flex: 0.15,
backgroundColor: '#e7fe52'
},
services: {
flex: 0.5,
backgroundColor: '#20fe23'
},
chart: {
flex: 0.35,
flexWrap: 'wrap',
backgroundColor: '#4fccb0'
}
});
0.15 + 0.5 + 0.35 = 1
i try to use the devexpress's scheduler plugin into my project.
After creating a project using angular Cli and installing the devexpress plugin using this command :
npm install --save devextreme devextreme-angular
Here is what i've get in my project :
calendrier.component.css
/deep/ .options {
padding: 20px;
background-color: #f5f5f5;
margin-top: 20px;
}
/deep/ .caption {
font-size: 18px;
font-weight: 500;
}
/deep/ .option {
margin-top: 10px;
display: inline-block;
width: 19%;
}
/deep/ .switcher-mode {
width: 100%;
}
/deep/ .option > span {
margin-right: 10px;
}
/deep/ .option > .dx-selectbox {
display: inline-block;
vertical-align: middle;
}
calendrier.component.html
<dx-scheduler
style="height: 100%; display: block"
[dataSource]="appointmentsData"
[currentDate]="currentDate"
startDateExpr="StartDate"
endDateExpr="EndDate"
textExpr="Text"
[views]="['agenda','workWeek']"
currentView="workWeek"
[firstDayOfWeek]="1"
[startDayHour]="9"
[endDayHour]="19"
[resources]="resourcesData"
></dx-scheduler>
calendrier.component.ts
import { NgModule, Component, enableProdMode } from '#angular/core';
import {BrowserModule} from '#angular/platform-browser';
import {platformBrowserDynamic} from '#angular/platform-browser-dynamic';
import {Appointment, Resource, Service} from './calendrier.service';
import {DxSchedulerModule, DxCheckBoxModule, DxSelectBoxModule} from 'devextreme-angular';
if(!/localhost/.test(document.location.host)) {
enableProdMode();
}
#Component({
selector: 'calendrier',
templateUrl: './calendrier.component.html',
styleUrls: ['./calendrier.component.css'],
providers: [Service]
})
export class CalendrierComponent {
appointmentsData: Appointment[];
currentDate: Date = new Date(2015, 4, 25);
resourcesData: Resource[];
switchModeNames: string[];
constructor(service: Service) {
this.switchModeNames = ["Tabs", "Drop-Down Menu"];
this.appointmentsData = service.getAppointments();
this.resourcesData = service.getResources();
}
}
#NgModule({
imports: [
BrowserModule,
DxSchedulerModule,
DxCheckBoxModule,
DxSelectBoxModule
],
declarations: [CalendrierComponent],
bootstrap: [CalendrierComponent]
})
export class CalendrierModule {}
platformBrowserDynamic().bootstrapModule(CalendrierModule)
calendrier.component.service
import { Injectable } from "#angular/core";
export class Appointment {
text: string;
ownerId: number[];
startDate: Date;
endDate: Date;
allDay?: boolean;
recurrenceRule?: string;
}
export class Resource {
text: string;
id: number;
color: string;
}
let appointments: Appointment[] = [
{
text: "Website Re-Design Plan",
ownerId: [4],
startDate: new Date(2015, 4, 25, 9, 30),
endDate: new Date(2015, 4, 25, 11, 30)
}, {
text: "Book Flights to San Fran for Sales Trip",
ownerId: [2],
startDate: new Date(2015, 4, 25, 12, 0),
endDate: new Date(2015, 4, 25, 13, 0),
allDay: true
}, {
text: "Install New Router in Dev Room",
ownerId: [1],
startDate: new Date(2015, 4, 25, 14, 30),
endDate: new Date(2015, 4, 25, 15, 30)
}, {
text: "Approve Personal Computer Upgrade Plan",
ownerId: [3],
startDate: new Date(2015, 4, 26, 10, 0),
endDate: new Date(2015, 4, 26, 11, 0)
}, {
text: "Final Budget Review",
ownerId: [1],
startDate: new Date(2015, 4, 26, 12, 0),
endDate: new Date(2015, 4, 26, 13, 35)
}, {
text: "New Brochures",
ownerId: [4],
startDate: new Date(2015, 4, 26, 14, 30),
endDate: new Date(2015, 4, 26, 15, 45)
}, {
text: "Install New Database",
ownerId: [2],
startDate: new Date(2015, 4, 27, 9, 45),
endDate: new Date(2015, 4, 27, 11, 15)
}, {
text: "Approve New Online Marketing Strategy",
ownerId: [3, 4],
startDate: new Date(2015, 4, 27, 12, 0),
endDate: new Date(2015, 4, 27, 14, 0)
}, {
text: "Upgrade Personal Computers",
ownerId: [2],
startDate: new Date(2015, 4, 27, 15, 15),
endDate: new Date(2015, 4, 27, 16, 30)
}, {
text: "Customer Workshop",
ownerId: [3],
startDate: new Date(2015, 4, 28, 11, 0),
endDate: new Date(2015, 4, 28, 12, 0),
allDay: true
}, {
text: "Prepare 2015 Marketing Plan",
ownerId: [1, 3],
startDate: new Date(2015, 4, 28, 11, 0),
endDate: new Date(2015, 4, 28, 13, 30)
}, {
text: "Brochure Design Review",
ownerId: [4],
startDate: new Date(2015, 4, 28, 14, 0),
endDate: new Date(2015, 4, 28, 15, 30)
}, {
text: "Create Icons for Website",
ownerId: [3],
startDate: new Date(2015, 4, 29, 10, 0),
endDate: new Date(2015, 4, 29, 11, 30)
}, {
text: "Upgrade Server Hardware",
ownerId: [4],
startDate: new Date(2015, 4, 29, 14, 30),
endDate: new Date(2015, 4, 29, 16, 0)
}, {
text: "Submit New Website Design",
ownerId: [1],
startDate: new Date(2015, 4, 29, 16, 30),
endDate: new Date(2015, 4, 29, 18, 0)
}, {
text: "Launch New Website",
ownerId: [2],
startDate: new Date(2015, 4, 29, 12, 20),
endDate: new Date(2015, 4, 29, 14, 0)
}, {
text: "Stand-up meeting",
ownerId: [1, 2, 3, 4],
startDate: new Date(2015, 4, 25, 9, 0),
endDate: new Date(2015, 4, 25, 9, 15),
recurrenceRule: "FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR;UNTIL=20150530"
}
];
let resources: Resource[] = [
{
text: "Samantha Bright",
id: 1,
color: "#cb6bb2"
}, {
text: "John Heart",
id: 2,
color: "#56ca85"
}, {
text: "Todd Hoffman",
id: 3,
color: "#1e90ff"
}, {
text: "Sandra Johnson",
id: 4,
color: "#ff9747"
}
];
#Injectable()
export class Service {
getAppointments(): Appointment[] {
return appointments;
}
getResources(): Resource[] {
return resources;
}
}
index.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CroissantBoard</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/17.1.4/css/dx.spa.css" />
<link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/17.1.4/css/dx.common.css" />
<link rel="dx-theme" data-theme="generic.light" href="https://cdn3.devexpress.com/jslib/17.1.4/css/dx.light.css" />
<script src="https://unpkg.com/core-js#2.4.1/client/shim.min.js"></script>
<script src="https://unpkg.com/zone.js#0.6.25/dist/zone.js"></script>
<script src="https://unpkg.com/reflect-metadata#0.1.3/Reflect.js"></script>
<script src="https://unpkg.com/systemjs#0.19.31/dist/system.js"></script>
</head>
<body class="dx-viewport">
<div class="demo-container">
<calendrier>Loading...</calendrier>
</div>
</body>
</html>
when i launch the project using
ng serve
But i have a problem... my calendar is blank ... did you have an idea of how can i see the events who's on the "calendrier.service.ts"
Here is what i've got on my console :
compiler.es5.js:1689 Uncaught Error: Template parse errors:
Can't bind to 'dataSource' since it isn't a known property of 'dx-scheduler'.
1. If 'dx-scheduler' is an Angular component and it has 'dataSource' input, then verify that it is part of this module.
2. If 'dx-scheduler' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '#NgModule.schemas' of this component to suppress this message.
3. To allow any property add 'NO_ERRORS_SCHEMA' to the '#NgModule.schemas' of this component. ("<dx-scheduler
style="height: 100%; display: block"
[ERROR ->][dataSource]="appointmentsData"
[currentDate]="currentDate"
startDateExpr="StartDate"
"): ng:///AppModule/CalendrierComponent.html#2:4
Can't bind to 'currentDate' since it isn't a known property of 'dx-scheduler'.
1. If 'dx-scheduler' is an Angular component and it has 'currentDate' input, then verify that it is part of this module.
2. If 'dx-scheduler' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '#NgModule.schemas' of this component to suppress this message.
3. To allow any property add 'NO_ERRORS_SCHEMA' to the '#NgModule.schemas' of this component. ("
style="height: 100%; display: block"
[dataSource]="appointmentsData"
[ERROR ->][currentDate]="currentDate"
startDateExpr="StartDate"
endDateExpr="EndDate"
"): ng:///AppModule/CalendrierComponent.html#3:4
Can't bind to 'views' since it isn't a known property of 'dx-scheduler'.
1. If 'dx-scheduler' is an Angular component and it has 'views' input, then verify that it is part of this module.
2. If 'dx-scheduler' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '#NgModule.schemas' of this component to suppress this message.
3. To allow any property add 'NO_ERRORS_SCHEMA' to the '#NgModule.schemas' of this component. ("
endDateExpr="EndDate"
textExpr="Text"
[ERROR ->][views]="['agenda','workWeek']"
currentView="workWeek"
[firstDayOfWeek]="1"
"): ng:///AppModule/CalendrierComponent.html#7:4
Can't bind to 'firstDayOfWeek' since it isn't a known property of 'dx-scheduler'.
1. If 'dx-scheduler' is an Angular component and it has 'firstDayOfWeek' input, then verify that it is part of this module.
2. If 'dx-scheduler' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '#NgModule.schemas' of this component to suppress this message.
3. To allow any property add 'NO_ERRORS_SCHEMA' to the '#NgModule.schemas' of this component. ("
[views]="['agenda','workWeek']"
currentView="workWeek"
[ERROR ->][firstDayOfWeek]="1"
[startDayHour]="9"
[endDayHour]="19"
"): ng:///AppModule/CalendrierComponent.html#9:4
Can't bind to 'startDayHour' since it isn't a known property of 'dx-scheduler'.
1. If 'dx-scheduler' is an Angular component and it has 'startDayHour' input, then verify that it is part of this module.
2. If 'dx-scheduler' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '#NgModule.schemas' of this component to suppress this message.
3. To allow any property add 'NO_ERRORS_SCHEMA' to the '#NgModule.schemas' of this component. ("
currentView="workWeek"
[firstDayOfWeek]="1"
[ERROR ->][startDayHour]="9"
[endDayHour]="19"
[resources]="resourcesData"
"): ng:///AppModule/CalendrierComponent.html#10:4
Can't bind to 'endDayHour' since it isn't a known property of 'dx-scheduler'.
1. If 'dx-scheduler' is an Angular component and it has 'endDayHour' input, then verify that it is part of this module.
2. If 'dx-scheduler' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '#NgModule.schemas' of this component to suppress this message.
3. To allow any property add 'NO_ERRORS_SCHEMA' to the '#NgModule.schemas' of this component. ("
[firstDayOfWeek]="1"
[startDayHour]="9"
[ERROR ->][endDayHour]="19"
[resources]="resourcesData"
></dx-scheduler>
"): ng:///AppModule/CalendrierComponent.html#11:4
Can't bind to 'resources' since it isn't a known property of 'dx-scheduler'.
1. If 'dx-scheduler' is an Angular component and it has 'resources' input, then verify that it is part of this module.
2. If 'dx-scheduler' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '#NgModule.schemas' of this component to suppress this message.
3. To allow any property add 'NO_ERRORS_SCHEMA' to the '#NgModule.schemas' of this component. ("
[startDayHour]="9"
[endDayHour]="19"
[ERROR ->][resources]="resourcesData"
></dx-scheduler>
"): ng:///AppModule/CalendrierComponent.html#12:4
'dx-scheduler' is not a known element:
1. If 'dx-scheduler' is an Angular component, then verify that it is part of this module.
2. If 'dx-scheduler' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '#NgModule.schemas' of this component to suppress this message. ("[ERROR ->]<dx-scheduler
style="height: 100%; display: block"
[dataSource]="appointmentsData"
"): ng:///AppModule/CalendrierComponent.html#0:0
at syntaxError (http://localhost:4200/vendor.bundle.js:260856:34)
at TemplateParser.webpackJsonp.../../../compiler/#angular/compiler.es5.js.TemplateParser.parse (http://localhost:4200/vendor.bundle.js:271969:19)
at JitCompiler.webpackJsonp.../../../compiler/#angular/compiler.es5.js.JitCompiler._compileTemplate (http://localhost:4200/vendor.bundle.js:286019:39)
at http://localhost:4200/vendor.bundle.js:285939:62
at Set.forEach (native)
at JitCompiler.webpackJsonp.../../../compiler/#angular/compiler.es5.js.JitCompiler._compileComponents (http://localhost:4200/vendor.bundle.js:285939:19)
at http://localhost:4200/vendor.bundle.js:285826:19
at Object.then (http://localhost:4200/vendor.bundle.js:260846:148)
at JitCompiler.webpackJsonp.../../../compiler/#angular/compiler.es5.js.JitCompiler._compileModuleAndComponents (http://localhost:4200/vendor.bundle.js:285825:26)
at JitCompiler.webpackJsonp.../../../compiler/#angular/compiler.es5.js.JitCompiler.compileModuleAsync (http://localhost:4200/vendor.bundle.js:285754:37)
could you take a look please ?
You are using the wrong field names from your class, they are appointmentsData and resourcesData:
<dx-scheduler
style="height: 100%; display: block"
[currentDate]="currentDate"
startDateExpr="StartDate"
endDateExpr="EndDate"
textExpr="Text"
[views]="['agenda','workWeek']"
currentView="workWeek"
[firstDayOfWeek]="1"
[startDayHour]="9"
[endDayHour]="19"
[dataSource]="appointmentsData" // <-- here
[resources]="resourcesData" // <-- and here
></dx-scheduler>
You need to import the DxDataGrid module into your module:
#NgModule({
imports: [
CommonModule,
DxDataGridModule
],
...
Below you see a small test element. It creates a SVG and whenever you click the SVG it should add a circle. Inspecting the element shows that the circles are indeed added (I know the position isn't exactly correct), but they are not shown.
This is svg-test.html
<link rel="import" href="../polymer/polymer.html">
<dom-module name="svg-test">
<link rel="import" type="css" href="svg-test.css">
<template>
<svg id="test" width$="{{width}}" height$="{{height}}" xmlns="http://www.w3.org/2000/svg"></svg>
</template>
<script>
Polymer({
is: 'svg-test',
properties: {
width: {
type: String,
value: "200"
},
height: {
type: String,
value: "200"
}
},
listeners: {
'test.tap': 'addCircle'
},
addCircle: function(e) {
var uri = 'http://www.w3.org/2000/svg';
var svg = this.$$('svg');
var circle = document.createElementNS(uri,'circle');
circle.setAttributeNS(uri, 'r', '5');
circle.setAttributeNS(uri, 'cx', e.detail.x);
circle.setAttributeNS(uri, 'cy', e.detail.y);
circle.setAttributeNS(uri, 'fill', 'white');
circle.setAttributeNS(uri, 'stroke', 'black');
circle.setAttributeNS(uri, 'stroke-width', '2');
svg.appendChild(circle);
}
});
</script>
</dom-module>
This is a test page:
<!DOCTYPE html>
<html>
<head>
<title>svg-test Demo</title>
<script src="../webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="svg-test.html">
</head>
<body unresolved>
<p>An example of svg-test looks like this:</p>
<svg-test></svg-test>
</body>
</html>
And this is bower.json:
{
"name": "svg-test",
"dependencies": {
"polymer": "Polymer/polymer#^1.1.2"
}
}
Although SVG elements are in the SVG namespace, attributes are typically in the null namespace so you want this...
var circle = document.createElementNS(uri,'circle');
circle.setAttribute('r', '5');
circle.setAttribute('cx', e.detail.x);
circle.setAttribute('cy', e.detail.y);
circle.setAttribute('fill', 'white');
circle.setAttribute('stroke', 'black');
circle.setAttribute('stroke-width', '2');