Javascript 在Vue.js组件中实现Bl.ocks.org图

Javascript 在Vue.js组件中实现Bl.ocks.org图,javascript,vue.js,d3.js,components,external,Javascript,Vue.js,D3.js,Components,External,我是D3初学者,我想在我的Vue.js组件中使用D3元素。这里的问题是,我需要的周期性旋转不起作用。它开始在全局定义的元素投影上循环null错误。第一次似乎有效,但在第二次中,对象不再被定义 代码如下: <template> <div> <svg></svg> </div> </template> <script> import * as d3 from "d3&quo

我是D3初学者,我想在我的Vue.js组件中使用D3元素。这里的问题是,我需要的周期性旋转不起作用。它开始在全局定义的元素投影上循环null错误。第一次似乎有效,但在第二次中,对象不再被定义

代码如下:

<template>
    <div>
        <svg></svg>
    </div>
</template>

<script>
import * as d3 from "d3";
import { feature } from "topojson-client";
import { json } from "d3-fetch";
export default {
    name: "WorldCases",
    data: function() {
        return {
            svg: null,
            markerGroup: null,
            projection: null,
            initialScale: null,
            path: null,
            center: null,
            config: null,
            locations: [
                { latitude: 22, longitude: 88 },
                { latitude: 12.61315, longitude: 38.37723 },
                { latitude: -30, longitude: -58 },
                { latitude: -14.270972, longitude: -170.132217 },
                { latitude: 28.033886, longitude: 1.659626 },
                { latitude: 40.463667, longitude: -3.74922 },
                { latitude: 35.907757, longitude: 127.766922 },
                { latitude: 23.634501, longitude: -102.552784 },
            ],
        };
    },
    mounted() {
        this.graph();
    },
    methods: {
        graph() {
            const width = 960;
            const height = 500;
            this.config = {
                speed: 0.005,
                verticalTilt: -30,
                horizontalTilt: 0,
            };
            this.svg = d3
                .select("svg")
                .attr("width", width)
                .attr("height", height);
            this.markerGroup = this.svg.append("g");
            this.projection = d3.geoOrthographic();
            console.log(this.projection);
            this.initialScale = this.projection.scale();
            this.path = d3.geoPath().projection(this.projection);
            this.center = [width / 2, height / 2];

            this.drawGlobe();
            this.drawGraticule();

            d3.timer(function(elapsed) {
                this.projection.rotate([
                    this.config.speed * elapsed - 120,
                    this.config.verticalTilt,
                    this.config.horizontalTilt,
                ]);
                this.svg.selectAll("path").attr("d", this.path);
                this.drawMarkers();
            }); 
        },
        drawGlobe() {
            Promise.all([json("./world-110m.json")]).then(([worldData, error]) => {
                // Do your stuff. Content of both files is now available in stations and svg
                this.svg
                    .selectAll(".segment")
                    .data(feature(worldData, worldData.objects.countries).features)
                    .enter()
                    .append("path")
                    .attr("class", "segment")
                    .attr("d", this.path)
                    .style("stroke", "#888")
                    .style("stroke-width", "1px")
                    .style("fill", (d, i) => "#e5e5e5")
                    .style("opacity", ".6");
                this.drawMarkers();
            });
        },
        drawMarkers() {
            const markers = this.markerGroup.selectAll("circle").data(this.locations);
            markers
                .enter()
                .append("circle")
                .merge(markers)
                .attr("cx", (d) => this.projection([d.longitude, d.latitude])[0])
                .attr("cy", (d) => this.projection([d.longitude, d.latitude])[1])
                .attr("fill", (d) => {
                    const coordinate = [d.longitude, d.latitude];
                    var gdistance = d3.geoDistance(coordinate, this.projection.invert(this.center));
                    return gdistance > 1.57 ? "none" : "steelblue";
                })
                .attr("r", 7);

            this.markerGroup.each(function() {
                this.parentNode.appendChild(this);
            });
        },

        drawGraticule() {
            const graticule = d3.geoGraticule().step([10, 10]);

            this.svg
                .append("path")
                .datum(graticule)
                .attr("class", "graticule")
                .attr("d", this.path)
                .style("fill", "#fff")
                .style("stroke", "#ccc");
        },
    },
};
</script>

<style></style>

从“d3”导入*作为d3;
从“topojson客户端”导入{feature};
从“D3FETCH”导入{json};
导出默认值{
名称:“世界案例”,
数据:函数(){
返回{
svg:null,
markerGroup:null,
投影:空,
initialScale:null,
路径:null,
中心:空,
config:null,
地点:[
{纬度:22,经度:88},
{纬度:12.61315,经度:38.37723},
{纬度:-30,经度:-58},
{纬度:-14.270972,经度:-170.132217},
{纬度:28.033886,经度:1.659626},
{纬度:40.463667,经度:-3.74922},
{纬度:35.907757,经度:127.766922},
{纬度:23.634501,经度:-102.552784},
],
};
},
安装的(){
这是一个.graph();
},
方法:{
图(){
常数宽度=960;
常数高度=500;
this.config={
速度:0.005,
垂直倾斜:-30,
水平倾斜:0,
};
this.svg=d3
.选择(“svg”)
.attr(“宽度”,宽度)
.attr(“高度”,高度);
this.markerGroup=this.svg.append(“g”);
this.projection=d3.geoporthographic();
console.log(this.projection);
this.initialScale=this.projection.scale();
this.path=d3.geoPath().projection(this.projection);
this.center=[宽度/2,高度/2];
这个.drawGlobe();
这个。drawgracile();
d3.计时器(功能(已用){
这个。投影。旋转([
this.config.speed*经过-120,
this.config.verticalTilt,
this.config.horizontaldtilt,
]);
this.svg.selectAll(“path”).attr(“d”,this.path);
这个。drawMarkers();
}); 
},
地球仪(){
Promise.all([json(“./world-110m.json”)])。然后([worldData,error])=>{
//这两个文件的内容现在都可以在stations和svg中使用
这个是.svg
.selectAll(“.segment”)
.数据(特征(worldData,worldData.Object.countries).features)
.输入()
.append(“路径”)
.attr(“类”、“段”)
.attr(“d”,此.path)
.style(“笔划”,“#888”)
.style(“笔划宽度”、“1px”)
.style(“填充”(d,i)=>“#e5”)
.style(“不透明”和“.6”);
这个。drawMarkers();
});
},
绘图标记(){
const markers=this.markerGroup.selectAll(“圆圈”).data(this.locations);
标记
.输入()
.附加(“圆圈”)
.合并(标记)
.attr(“cx”,(d)=>此.projection([d.经度,d.纬度])[0])
.attr(“cy”,(d)=>this.projection([d.经度,d.纬度])[1])
.attr(“填充”,(d)=>{
常量坐标=[d.经度,d.纬度];
var gdistance=d3.大地距离(坐标,此.投影.反转(此.中心));
返回距离>1.57?“无”:“钢蓝”;
})
.attr(“r”,7);
this.markerGroup.each(函数(){
this.parentNode.appendChild(this);
});
},
拉丝分划(){
常数分划=d3.地理分划().步骤([10,10]);
这个是.svg
.append(“路径”)
.基准面(分划)
.attr(“类别”、“分划”)
.attr(“d”,此.path)
.style(“填充”、“fff”)
.风格(“笔划”、“ccc”);
},
},
};
错误显示在下图中:

我怎样才能修好它?在此配置中,它不起作用


谢谢

我解决了我的问题,记住在Javascript中,有时当我们在其他函数中工作时,“this”元素并不总是我们所期望的

因此,我需要做的是将“this”对象保存在一个变量中,并使用该变量执行我需要的操作:

var x = this;
d3.timer(function(elapsed) {
            x.projection.rotate([
                x.config.speed * elapsed - 120,
                x.config.verticalTilt,
                x.config.horizontalTilt,
            ]);
            x.svg.selectAll("path").attr("d", this.path);
            x.drawMarkers();
        });