簡體   English   中英

Javascript 按鈕 onclick 事件調用 function 內部 ZC1C425268E68385D14AB5074C17A 模塊

[英]Javascript button onclick event to call function inside function in module

我正在根據 D3.js 的數據繪制和着色線條,並希望在單擊按鈕時更新其 colors。 我的問題是:如何從 index.ZFC35FDC70D5FC67A53EZ 中的一個按鈕的onclick事件調用在drawLines.js中的index.html drawLines中聲明的colorP1()colorP2()

我努力了:

  1. using the window.drawLines = drawLines trick and have the onclick event refer to window.drawLines.colorP2() , but I get Uncaught TypeError: colorP2 is not a function
  2. 使用window.colorP2 = colorP2 ,但我不知道在這種情況下導入將如何工作

有什么想法可以啟發這個卑微的初學者的思想嗎? 據我了解, colorP1()colorP2()必須保留在drawLines()中,因為它們需要drawLines() () 中的datalines變量——在這里隨時證明我錯了。

索引.html

<html>
<head>
<style>
.line {
    stroke-width: 4px;
    fill: none;
}
</style>
</head>

<script src="https://d3js.org/d3.v6.min.js"></script>
<script type="module">
  import {drawLines} from './drawLines.js';

  d3.json("test.geojson").then(drawLines);
</script>

<body>
    <svg id='map'></svg>
    <button onclick="colorP1()">colorP1</button>
    <button onclick="colorP2()">colorP2</button>

</body>
</html>

drawLines.js

function colorInterpolate(data, property) {
    let max_d = d3.max(data.features.map(d => d.properties[property]));
    let range = [max_d, 1];
    return d3.scaleSequential().domain(range).interpolator(d3.interpolateViridis); 
}

export function drawLines(data) {

    let width = 900,
        height = 500,
        initialScale = 1 << 23,
        initialCenter = [-74.200698022608137, 40.034504451003734]

    let svg = d3.select('#map')
        .attr('height', height)
        .attr('width', width)

    let projection = d3.geoMercator()
        .scale(initialScale)
        .center(initialCenter)
        .translate([width / 2, height / 2])

    let path = d3.geoPath(projection)

    let myColor = colorInterpolate(data, 'p1');

    let lines = svg.append('g')

    lines.selectAll('path')
        .data(data.features)
        .join('path')
        .attr('class', 'line')
        .attr('d', path)
        .attr("stroke", function(d) {
                return myColor(d.properties.p1);
            })

    function colorP2() {
        let myColor = colorInterpolate(data, 'p2');
        lines.selectAll('path')
            .attr("stroke", d => myColor(d.properties.p2))
    }

    function colorP1() {
        let myColor = colorInterpolate(data, 'p1');
        lines.selectAll('path')
            .attr("stroke", d => myColor(d.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>

你的假設是錯誤的:

據我了解, colorP1() 和 colorP2() 必須留在 drawLines() 內,因為它們需要 drawLines() 中的數據和線條變量

D3 將數據綁定到使用.data(data).join().data(data).enter()輸入的元素。 基准附加到節點。 使用.attr("something",function(d) {時, d指的是綁定數據,而不是原始數據數組。因此,您不需要原始數據數組,它是 DOM 元素的一部分。

此外,您不需要lines ,因為您可以重新選擇: d3.selectAll("paths")d3.selectAll(".line")

因此,您可以將 p1/p2 函數移到 drawLines function 之外。

正如我想簡化下面的代碼片段一樣,我有一個 function 傳遞數據以繪制一些圓圈。 然后我使用 D3 將事件偵聽器分配給按鈕(我也可以直接在按鈕上使用onclick=""屬性)來調用重新着色圓圈的函數:

function color1() {
 d3.selectAll("circle")
   .attr("fill",d=>d.color1);
}

function 訪問綁定數據和給定屬性( d=>d.color1 ),通過使用d3.selectAll()我們可以 select 單擊時存在的所有圓圈:

 function draw(data) { var svg = d3.select("body").append("svg").attr("width", 300).attr("height", 200); svg.selectAll("circle").data(data).enter().append("circle").attr("cx",d=>dx).attr("cy",d=>dy).attr("fill",d=>d.color2).attr("r", 20); } draw([{x: 100,y:50, color1: "steelblue",color2:"crimson"},{x:200,y:50,color1:"steelblue",color2:"crimson"}]) d3.selectAll("button").data([0,1]).on("click", function(event,d) { if (d) color2(); else color1(); }) function color1() { d3.selectAll("circle").attr("fill",d=>d.color1); } function color2() { d3.selectAll("circle").attr("fill",d=>d.color2); }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js"></script> <div> <button> Blue </button> <button> Red </button> </div>

如果您需要數據數組本身,您可以使用d3.selectAll("elements").data()提取它

當然,我們也可以 append 您的 drawLines function 中的按鈕,這可能會產生更清晰的結果,特別是如果按鈕依賴於任何形式的數據。 這樣,如果您想更改按鈕或功能,一切都在一個地方,例如:

 var 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 ] ] } }]}; function drawLines(data) { let width = 500, height = 400, initialScale = 1 << 23, initialCenter = [-74.200698022608137, 40.034504451003734] let svg = d3.select('#map').attr('height', height).attr('width', width) let projection = d3.geoMercator().fitSize([width,height],data) let path = d3.geoPath(projection) let myColor = colorInterpolate(data, 'p1'); let lines = svg.append('g') lines.selectAll('path').data(data.features).join('path').attr('class', 'line').attr('d', path) colorBy("p1"); function colorBy(property) { let myColor = colorInterpolate(property); lines.selectAll('path').attr("stroke", d => myColor(d.properties[property])) } function colorInterpolate(property) { let max_d = d3.max(data.features.map(d => d.properties[property])); let range = [max_d, 1]; return d3.scaleSequential().domain(range).interpolator(d3.interpolateViridis); } d3.selectAll(".property").data(["p1","p2"]).enter().append("button").attr("class","property").text(d=>d).on("click", function(_,d) { colorBy(d); }).lower(); } drawLines(geojson);
 .line { stroke-width: 4px; fill: none; }
 <script src="https://d3js.org/d3.v6.min.js"></script> <svg id='map'></svg>

和繼續工作的工作示例......

 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}, "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 ]]}}]}'; var width = 900, height = 500, initialScale = 1 << 23, initialCenter = [-74.198698022608137, 40.034504451003734] var svg = d3.select('#map').attr('height', height).attr('width', width); var lines = svg.append('g'); var projection = d3.geoMercator().scale(initialScale).center(initialCenter).translate([width / 2, height / 2]) var path = d3.geoPath(projection) function colorInterpolate(data, property) { let max_d = d3.max(data.features.map(d => d.properties[property])); let range = [max_d, 1]; return d3.scaleSequential().domain(range).interpolator(d3.interpolateViridis); } function drawLines(data) { let myColor = colorInterpolate(data, 'p1'); lines.selectAll('path').data(data.features).join('path').attr('class', 'line').attr('d', path).attr("stroke", function(d) { return myColor(d.properties.p1); }); } function colorP2(data){ let myColor = colorInterpolate(data, 'p2'); lines.selectAll('path').attr("stroke", d=>myColor(d.properties.p2)); } function colorP1(data){ let myColor = colorInterpolate(data, 'p1'); lines.selectAll('path').attr("stroke", d=>myColor(d.properties.p1)); }
 <html> <head> <style>.line { stroke-width: 4px; fill: none; } </style> </head> <script src="https://d3js.org/d3.v6.min.js"></script> <script type="module"> //import {drawLines} from './drawLines.js'; //d3.json("test.geojson").then(drawLines); drawLines(JSON.parse(json1)); </script> <body> <svg id='map'></svg> <button onclick="colorP1(JSON.parse(json1))">colorP1</button> <button onclick="colorP2(JSON.parse(json1))">colorP2</button> </body> </html>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM