D3JsDay19 地图加入了事件,地点资料就呈现—为地图加入互动事件

制作样板

昨天已经绘制出每个淡绿色的点来显示资料中的经纬度在svg地图上面,今天要做的事情是当滑鼠移入的时候我们可以观看资料的内容。

第一步我们可以手动写html来观看显示画面,之後再将这些撰写的程序码使用d3的html()来动态新增至画面中具体操作方法等等会说明

首先观看什麽资料要印出到网页画面当中

https://ithelp.ithome.com.tw/upload/images/20211004/20125095OiQy6ewbm5.png
Photo、AgriBtItemCost、AgriBtItemCnt、AgriBtItemNm、AgriBtItemSpec、AgriTel、AgriMainAdrs分别是代表照片、价格、内容、产品名、产品说明、电话和住址

因此我们先使用任何一笔资料写在html的<body>当中观看显示的样子

<div class="wrap-item">
<div >
  <img src="https://ezgo.coa.gov.tw/Uploads/opendata/BestItem/APPLY_D/20151216180812.jpg">
</div>
  <h2>产品名:金碧椪柑</h2>
  <p>介绍:石冈乡以其得天独厚的土壤、气候、阳光,共同滋养着累累结实的椪柑,「金碧椪柑」乃此中严挑精选的顶级产品,果形完整丰满,色泽澄黄亮丽,入口甜中带酸甘醇多汁,而象徵财源滚滚、大吉大利的「金碧」之名,在椪柑熟成的年节期间更增添圆满的喜气。"</p>
  <p>电话:(04)25819933</p>
  <p>住址:台中市石冈区万安里石冈街67号</p>
  <p>价格:350 元/ 盒</p>
  <p>其他说明:25A,精品16 粒入。
  产期:12 月~ 翌年1 月,售完为止</p>
</div>

https://ithelp.ithome.com.tw/upload/images/20211004/20125095yawtiIZ8LV.png

添加CSS到样板

之後写一些css样式到<style></style>调整排列

.wrap-item{
    box-sizing: border-box;
    width: 400px;
    height: 500px;
    padding: 40px;
}
.wrap-item img{
    max-width: 100%;
    max-height:100%;
}

呈现如下图

https://ithelp.ithome.com.tw/upload/images/20211004/20125095E3Qu4B5Zbl.png

这边的html文档先留着

添加on函数

接下来我们就在先前的程序码加入on的函数,添加滑鼠移入的事件,这边使用select(this)让滑鼠滑入触发的<circle>进行颜色的变换,这边可以使用一个变数储存滑入东西的资料
const selectObj = d3.select(this).data();所示,可以console.log看看是否有如期取得当前滑入的资料值。

 g.selectAll("circle")
  .data(product)
  .join("circle")
  .attr("cx", function(d) {
      return projection([d.Longitude, d.Latitude])[0];
  })
  .attr("cy", function(d) {
      return projection([d.Longitude, d.Latitude])[1];
  })
  .attr("r", 1)
  .style("fill", "lightgreen")
  .on("mouseenter", function(){ 
    d3.select(this).style("fill", "darkgreen");
    const selectObj = d3.select(this).data();
     console.log(selectObj);
  }

应当会看到如下图

插入样板

我们可以使用 selection.html([value])函数来插入html的语法,把刚刚所建立好的html语法放入进去。这边使用样板字面值的Javascript语法来撰写也方便变数和固定要插入的内容作转换,因此在on("mouseenter", function(){})的程序码如下

d3.select(this).style("fill", "darkgreen");
  const selectObj = d3.select(this).data();
  console.log(selectObj);
  d3.select(".wrap-item").html(
      `<div >
          <img src="${selectObj[0].Photo}">
      </div>
      <h2>产品名:${selectObj[0].AgriBtItemNm}</h2>
      <p>介绍:${selectObj[0].AgriBtItemCnt}</p>
      <p>电话:${selectObj[0].AgriTel}</p>
      <p>住址:${selectObj[0].AgriMainAdrs}</p>
      <p>价格:${selectObj[0].AgriBtItemCost}</p>
      <p>其他说明:${selectObj[0].AgriBtItemSpec}</p>
      </div>
  `

MDN样板字面值

这时候应该可以看到滑鼠移入的时候会有产品显示,如下图

https://ithelp.ithome.com.tw/upload/images/20211004/20125095IYx83MVKkh.png

添加mouselevae修正

可以注意到的地方是我们滑鼠移入之後,圆点变成深绿色,当我们移入下一个点的时候,深绿色没有变回来浅绿色,因此最後还要再加入一个mouseleave事件来还原点的样式

因此最後这边插入离开滑鼠事件将原本的圆型点填入淡绿色,最後加入之前所学习的zoom的变焦模式

完整程序码如下

<style>
    .wrap{
        width: 1440px;
        display: flex;
        justify-content: center;
    }
    .wrap-item{
        box-sizing: border-box;
        width: 400px;
        padding: 40px;
    }
    .wrap-item img{
        max-width: 100%;
        max-height:100%;
    }
    svg{
        border:solid 1px  black;
    }

    svg circle{
        cursor: pointer;
    }

</style>
<body>
    <script>
    let width = 800;
        let height = 600;
        const projection = d3.geoMercator()
                        .center([123, 24 ])
                        .scale(5000);
        const svg = d3.select("body")
                    .select(".wrap")
                    .append("svg")
                    .attr("width", width)
                    .attr("height", height);
        const path = d3.geoPath()
                        .projection(projection);
        const g = svg.append("g");
        d3.select(".wrap")
        .append("div")
        .classed("wrap-item",true);
        d3.json("taiwantopo.json")
        .then(function(topology) {
            const makeColor = d3.scaleSequential(t => d3.hsl(t * 360, .8, .9).formatRgb()).domain([0,30]);
            g.selectAll("path")
                .data(
                    topojson
                        .feature(topology, topology.objects.COUNTY_MOI_1090820)
                        .features
                        )
                .join("path")
                .style('fill', (d,i)=>{
                    return makeColor(i);
                })
                .style("stroke", "gray")
                .style("stroke-width",".25")
                .style("stroke-opacity",".5")
                .attr("d", path);
                const zoom = d3.zoom()
            .scaleExtent([1, 8])
            .on('zoom', function(event) {
                g.selectAll('path')
                .attr('transform', event.transform);
                g.selectAll("circle")
                .attr('transform', event.transform);
        });
        svg.call(zoom);
            d3.json("farm-product-map.json")
            .then(function(product){
                g.selectAll("circle")
                .data(product)
                .join("circle")
                .attr("cx", function(d) {
                    return projection([d.Longitude, d.Latitude])[0];
                })
                .attr("cy", function(d) {
                    return projection([d.Longitude, d.Latitude])[1];
                })
                .attr("r", 1)
                .style("fill", "lightgreen")
                    .on("mouseenter", function(){  
                    d3.select(this).style("fill", "darkgreen");
                    const selectObj = d3.select(this).data();
                    d3.select(".wrap-item").html(
                        `<div >
                            <img src="${selectObj[0].Photo}">
                        </div>
                        <h2>产品名:${selectObj[0].AgriBtItemNm}</h2>
                        <p>介绍:${selectObj[0].AgriBtItemCnt}</p>
                        <p>电话:${selectObj[0].AgriTel}</p>
                        <p>住址:${selectObj[0].AgriMainAdrs}</p>
                        <p>价格:${selectObj[0].AgriBtItemCost}</p>
                        <p>其他说明:${selectObj[0].AgriBtItemSpec}</p>
                        </div>
                    `
                    );
                })
                .on("mouseleave ", function(){
                    d3.select(this).style("fill", "lightgreen");
                })
            });

        })
    <script>
</body>

最後成果如下图

最後附上githubPage

githubPage


<<:  建立 React component

>>:  [C 语言笔记--Day22] warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]

3.移转 Aras PLM大小事-Agile 汇出 Part & BOM (1)

第3话 Agile 汇出 Part & BOM(1) 想要汇出Agile的Part与BOM,...

EP 20: Custom Launch Screen for Android

Hello, 各位 iT邦帮忙 的粉丝们大家好~~~ 本篇是 Re: 从零开始用 Xamarin 技...

Day30 帝君最爱 凤九拿手菜-糖醋鲈鱼

始於糖醋,终於糖醋,一如挑战30天铁人出好菜的滋味,酸酸甜甜 最後一场铁人,再次挑战炸物料理,有了...

Python 演算法 Day 8 - 理论基础 统计 & 机率

Chap.I 理论基础 Part 4:统计 & 机率 Analyze the data th...

【Day 04】C 的一些基本语法

识别符号 用来标示函式、变数,或者使用者自定专案的名称,识别符号可用大写字母(A 到 Z)、小写字母...