Javascript按钮onclick事件调用模块中函数内部的函数

Javascript按钮onclick事件调用模块中函数内部的函数,javascript,html,d3.js,Javascript,Html,D3.js,我正在使用D3.js基于数据绘制和着色线条,并希望在单击按钮时更新它们的颜色。我的问题是:如何从index.html中某个按钮的onclick事件调用drawLines.js中函数drawLines中声明的colorP1和colorP2 我试过: 使用window.drawLines=drawLines技巧并让onclick事件引用window.drawLines.colorP2,但我得到了未捕获的TypeError:colorP2不是一个函数 使用window.colorP2=colorP2,

我正在使用D3.js基于数据绘制和着色线条,并希望在单击按钮时更新它们的颜色。我的问题是:如何从index.html中某个按钮的onclick事件调用drawLines.js中函数drawLines中声明的colorP1和colorP2

我试过:

使用window.drawLines=drawLines技巧并让onclick事件引用window.drawLines.colorP2,但我得到了未捕获的TypeError:colorP2不是一个函数 使用window.colorP2=colorP2,但我不知道在这种情况下导入将如何工作 有什么想法可以启发这个卑微的初学者的头脑吗?据我所知,colorP1和colorP2必须留在drawLines中,因为它们需要drawLines中的数据和线条变量。请随意证明我的错误

index.html

.线路{ 笔画宽度:4px; 填充:无; } 从“./drawLines.js”导入{drawLines}; d3.jsontest.geojson.thendrawLines; 颜色1 色素P2 drawLines.js

函数colorInterpoleData,属性{ 让max_d=d3.maxdata.features.mapd=>d.properties[property]; 设范围=[max_d,1]; 返回d3.scaleSequential.domainrange.interpolatord3.interpolateViridis; } 导出函数drawLinesdata{ 宽度=900, 高度=500, initialScale=1.properties.p2 } 函数colorP1{ 设myColor=colorInterpoleData,'p1'; 行。选择所有“路径” .attrstroke,d=>myclord.properties.p1 } } test.geojson

{
"type": "FeatureCollection",
"name": "lines",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "id": 3, "p1": 1, "p2": 3}, "geometry": { "type": "LineString", "coordinates": [ [ -74.201304101157845, 40.033790926216739 ], [ -74.201226425025339, 40.033761910802717 ], [ -74.201164135201353, 40.033738641825124 ] ] } },
{ "type": "Feature", "properties": { "id": 4, "p1": 2, "p2": 2}, "geometry": { "type": "LineString", "coordinates": [ [ -74.200521185229846, 40.034804885753857 ], [ -74.200535458528648, 40.034780636493231 ], [ -74.200698022608137, 40.034504451003734 ], [ -74.200932444446437, 40.034106179618831 ], [ -74.201017665586349, 40.033961391736824 ] ] } }
]
}

您可以这样调用来调用内部函数:

<button onclick="(new drawLines().colorP1())">colorP1</button>
<button onclick="(new drawLines().colorP2())">colorP2</button>

您可以这样调用来调用内部函数:

<button onclick="(new drawLines().colorP1())">colorP1</button>
<button onclick="(new drawLines().colorP2())">colorP2</button>

你的假设是错误的:

据我所知,colorP1和colorP2必须留在绘图线内,因为它们需要来自绘图线的数据和线条变量

D3将数据绑定到使用.datadata.join或.datadata.enter输入的元素。基准面将附着到节点。当使用.attrsome时,函数d{d引用绑定的数据,而不是原始数据数组。因此,您不需要原始数据数组,它是DOM元素的一部分

此外,您不需要行,因为您可以重新生成该选择:d3.selectAllPath或d3.selectAll.line

因此,可以将p1/p2函数移到drawLines函数之外

为了简化下面的代码段,我得到了一个传递数据的函数来绘制一些圆。然后我将事件侦听器分配给按钮,我还可以使用D3直接使用按钮上的onclick=属性来调用重新绘制圆的函数:

function color1() {
 d3.selectAll("circle")
   .attr("fill",d=>d.color1);
}
函数访问绑定数据和给定属性d=>d.color1,通过使用d3.selectAll,我们可以选择单击时存在的所有圆:

函数drawdata{ var svg=d3.selectbody .appendsvg .宽度,300 .身高200; svg.selectAllcircle .数据 进来 A.附加圆 .attrcx,d=>d.x .attracy,d=>d.y .attrfill,d=>d.color2 .attrr,20岁; } 绘制[{x:100,y:50,颜色1:steelblue,颜色2:crimson},{x:200,y:50,颜色1:steelblue,颜色2:crimson}] d3.选择所有按钮 .数据[0,1] .onclick,functionevent,d{ 如果d染色2; else染色1; } 函数颜色1{ d3.selectAllcircle .attrfill,d=>d.color1; } 函数颜色2{ d3.selectAllcircle .attrfill,d=>d.color2; } 蓝色 红色
你的假设是错误的:

据我所知,colorP1和colorP2必须留在绘图线内,因为它们需要来自绘图线的数据和线条变量

D3将数据绑定到使用.datadata.join或.datadata.enter输入的元素。数据附加到节点。当使用.attrsome时,函数d{d指绑定的数据,而不是原始数据数组。因此,您不需要原始数据数组,它是DOM元素的一部分

此外,您不需要行,因为您可以重新生成该选择:d3.selectAllPath或d3.selectAll.line

因此,可以将p1/p2函数移到drawLines函数之外

为了简化下面的代码段,我得到了一个传递数据的函数来绘制一些圆。然后我将事件侦听器分配给按钮,我还可以使用D3直接使用按钮上的onclick=属性来调用重新绘制圆的函数:

function color1() {
 d3.selectAll("circle")
   .attr("fill",d=>d.color1);
}
函数访问绑定数据和给定属性d=>d.color1,通过使用d3.selectAll,我们可以选择单击时存在的所有圆:

函数drawdata{ var svg=d3.selectbody .appendsvg .宽度,300 .身高200; svg.selectAllcircle .数据 进来 A.附加圆 .attrcx,d=>d.x .attracy,d=>d.y .attrfill,d=>d.color2 .attrr,20岁; } 绘制[{x:100,y:50,颜色1:steelblue,颜色2:crimson},{x:200,y:50,颜色1:steelblue,颜色2:crimson}] d3.选择所有按钮 .数据[0,1] .onclick,functionevent,d{ 如果d染色2; 其他的 色素1; } 函数颜色1{ d3.selectAllcircle .attrfill,d=>d.color1; } 函数颜色2{ d3.selectAllcircle .attrfill,d=>d.color2; } 蓝色 红色 以及继续工作的工作示例

var json1={type:FeatureCollection,name:lines,crs:{type:name,properties:{name:urn:ogc:def:crs:ogc:1.3:CRS84}},features:[{type:Feature,properties:{id:3,p1:1,p2:3},几何体:{type:LineString,坐标:[-74.201304101157845,40.0337909216739],-74.20122642502539,40.033761910802717],[-74.201164135201353,40.033738641825124]},{type:Feature,properties:{id:4,p1:2,p2:2},geometry:{type:LineString,座标:[-74.200521185229846,40.0348048858753857],-74.200535458528648,40.034780636493231],-74.200698022608137,40.034504451003734],-74.2009324446437,40.034107931],[ -74.201017665586349, 40.033961391736824 ]]}}]}'; 可变宽度=900, 高度=500, initialScale=1 d.属性[属性]; 设范围=[max_d,1]; 返回d3.scaleSequential .domainrange .interpolatord3.interpolateViridis; } 函数drawLinesdata{ 设myColor=colorInterpoleData,'p1'; 行。选择所有“路径” .datadata.features .加入“路径” .attr'class','line' .attr'd',路径 .中风,功能正常{ 返回myclord.properties.p1; }; } 函数colorP2data{ 设myColor=color插值数据'p2'; 行。选择所有“路径” .attrstroke,d=>myclord.properties.p2; } 函数colorP1data{ 设myColor=colorInterpoleData,'p1'; 行。选择所有“路径” .attrstroke,d=>myclord.properties.p1; } .线路{ 笔画宽度:4px; 填充:无; } //从“./drawLines.js”导入{drawLines}; //d3.jsontest.geojson.thendrawLines; drawLinesJSON.parsejson1; 颜色1 色素P2 以及继续工作的工作示例

var json1={type:FeatureCollection,name:lines,crs:{type:name,properties:{name:urn:ogc:def:crs:ogc:1.3:CRS84}},features:[{type:Feature,properties:{id:3,p1:1,p2:3},几何体:{type:LineString,坐标:[-74.201304101157845,40.0337909216739],-74.20122642502539,40.033761910802717],[-74.201164135201353,40.033738641825124]},{type:Feature,properties:{id:4,p1:2,p2:2},geometry:{type:LineString,座标:[-74.200521185229846,40.0348048858753857],-74.200535458528648,40.034780636493231],-74.200698022608137,40.034504451003734],-74.2009324446437,40.034107931],[ -74.201017665586349, 40.033961391736824 ]]}}]}'; 可变宽度=900, 高度=500, initialScale=1 d.属性[属性]; 设范围=[max_d,1]; 返回d3.scaleSequential .domainrange .interpolatord3.interpolateViridis; } 函数drawLinesdata{ 设myColor=colorInterpoleData,'p1'; 行。选择所有“路径” .datadata.features .加入“路径” .attr'class','line' .attr'd',路径 .中风,功能正常{ 返回myclord.properties.p1; }; } 函数colorP2data{ 设myColor=color插值数据'p2'; 行。选择所有“路径” .attrstroke,d=>myclord.properties.p2; } 函数colorP1data{ 设myColor=colorInterpoleData,'p1'; 行。选择所有“路径” .attrstroke,d=>myclord.properties.p1; } .线路{ 笔画宽度:4px; 填充:无; } //从“./drawLines.js”导入{drawLines}; //d3.jsontest.geojson.thendrawLines; drawLinesJSON.parsejson1; 颜色1 色素P2
感谢您的及时回复,onclick事件现在正在调用该函数。问题出现在drawLines.js的第2行,因为它无法读取未定义的属性“features”,因为数据是未定义的。鉴于colorP2是在drawLines中定义的,它不应该具有数据的值吗?是的,在这种情况下,数据将未定义,因为调用drawlines每次都会调用它来创建一个新实例。在这种情况下,您的设计似乎不正确。我可以考虑修改当前代码的一点是,最初将数据存储在一个全局变量中,并在绘图线内每次都使用它。在d3中实现的正确方法是选择id selectAll并使用fill来更改颜色。现在,color1和color2将不在drawLines函数中。我明白了,这是有意义的,您提到的第二个选项听起来更干净。也就是说,您将如何规范化colormap,让myColor=colorInterpolatedata,'p2';没有数据?如果可能的话,我希望没有全局变量。您将像调用th一样调用drawLinesis:d3.jsontest.geojson.thenerr,data=>drawLinesdata;现在drawLines将有数据。现在您可以将数据传递给上面所说的colorInterpolate。感谢您的及时回复,onclick事件现在正在调用函数。
现在的问题出现在drawLines.js的第2行,因为它无法读取未定义的属性“features”,因为数据未定义。如果colorP2是在drawLines中定义的,那么它不应该具有数据的值吗?是的,在这种情况下,数据将是未定义的,因为每次调用drawLines都会调用它来创建一个新实例。在这种情况下,您的设计似乎不正确。我可以考虑修改当前代码的一件事是,最初将数据存储在全局变量中,并在绘图线中使用它。在d3中实现的正确方法是选择id selectAll并使用fill更改颜色。现在,color1和color2将不在drawLines函数中。我明白了,这是有意义的,您提到的第二个选项听起来更干净。也就是说,您将如何规范化colormap,让myColor=colorInterpolatedata,'p2';没有数据?如果可能的话,我希望没有全局变量;现在,绘图线将具有数据。现在,您可以在上面的代码行中将数据传递给colorInterpolate,但我不确定我是否遵循了。javascript代码会在哪里?我会把它插入一个新的标签吗?是的,所有代码都插入标签,或者如果代码很大,只在标签中插入链接,例如:谢谢你的代码,但我不确定我是否遵循了。javascript代码会在哪里?我会把它插入一个新的标签吗?是的,所有代码都插入标签,或者如果代码很大,只在标签中插入链接,例如:再次感谢,现在一切都清楚了。一个后续问题:如果我需要在单击按钮时通过数据对配色方案进行规范化,请参见第行:让myColor=ColorInterpoleData,'p2';,在没有数据的情况下,我如何进行规范化?您建议从DOM本身提取数据吗?@BernardoTrindade正在更新答案,但实际上您可以使用,您可以使用d3.selectAllegements.data重新创建数据数组来获取数据。再次感谢,现在一切都清楚了。一个后续问题:如果我需要在单击按钮时通过数据对配色方案进行规范化,请参见第行:让myColor=ColorInterpoleData,'p2';,在没有数据的情况下,我如何进行规范化?您是否建议从DOM本身提取它?@BernardoTrindade更新答案,但实际上您可以使用,您可以使用d3.selectAllegements.data重新创建数据数组来获取数据。