如何将D3组件附加到另一个vue文件中的div

时间:2019-05-03 10:12:49

标签: vue.js d3.js

我在我的VueJS应用程序中合并了D3JS图表,并且在理解如何将D3组件连接到.vue文件中的div时遇到了麻烦。当我将D3图表附加到HTML正文时,它可以呈现精美的外观,但是我不希望它出现在每个视图中,仅是我已将其导入到的视图中以及仅显示在想要的div上。

我已经查看了有关在Vue中安装和计算D3组件的其他答案-所有这些似乎都过于复杂。

可能我不了解D3图表如何作为Vue组件工作。我正在尝试使其尽可能简单。这是我的Home.vue视图/

<template>
  <div id="chart">
  </div>
</template>

<script>
import MainChart from "@/components/MainChart.vue";

export default {
  name: 'chart',
  components: {
    MainChart
  }
}    
</script>

然后是我在组件中的MainChart组件/

<template>
  <div id="chart">
    </div>

  </div>
</template>

<script>
import * as d3 from "d3";
export default {
  name: "MainChart",
};
// 2. Use the margin convention practice 
var margin = {top: 50, right: 50, bottom: 50, left: 50}
  , width = window.innerWidth - margin.left - margin.right // Use the window's width 
  , height = window.innerHeight - margin.top - margin.bottom; // Use the window's height

// The number of datapoints
var n = 30;

// 5. X scale will use the index of our data
var xScale = d3.scalePow()
    .domain([0, n-1]) // input
    .range([0, width]); // output

// 6. Y scale will use the randomly generate number 
var yScale = d3.scalePow()
    .domain([0, 1000]) // input 
    .range([height, 0]); // output 

// 1. Add the SVG to the page and employ #2
var svg = d3.select("#chart").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// 3. Call the x axis in a group tag
svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(d3.axisBottom(xScale)); // Create an axis component with d3.axisBottom

svg.append("text")
    .attr("class", "x label")
    .attr("text-anchor", "end")
    .attr("x", width)
    .attr("y", height - 6)
    .text("Time");

// 4. Call the y axis in a group tag
svg.append("g")
    .attr("class", "y axis")
    .call(d3.axisLeft(yScale)); // Create an axis component with d3.axisLeft

svg.append("text")
    .attr("class", "y label")
    .attr("text-anchor", "end")
    .attr("y", 6)
    .attr("dy", ".75em")
    .attr("transform", "rotate(-90)")
    .text("Views");


// 7. d3's line generator
var line = d3.line()
    .x(function(d, i) { return xScale(i); }) // set the x values for the line generator
    .y(function(d) { return yScale(d.y); }) // set the y values for the line generator 
    .curve(d3.curveMonotoneX) // apply smoothing to the line

// 8. An array of objects of length N. Each object has key -> value pair, the key being "y" and the value is a random number
// var dataset = d3.range(n).map(function(d) { return {"y": d3.randomUniform(1)() } })
var dataset = [],
    n = 30,
    a = 20,
    b = 1.15;

for (var k = 0; k < n; k++) {
    dataset.push({x: 1 * k, y: a * Math.pow(b, k)});
}

// 9. Append the path, bind the data, and call the line generator 
svg.append("path")
    .datum(dataset) // 10. Binds data to the line 
    .attr("class", "line") // Assign a class for styling
    .attr("d", line) // 11. Calls the line generator  
    .attr("stroke-dasharray", 100 + " " + 100)
    .attr("stroke-dashoffset", 1000)
    .attr("fill", "none")
    .transition()
    .duration(10000)
    .ease(d3.easeLinear)
    .attr("stroke-dashoffset", 0);


// 12. Appends a circle for each datapoint 
svg.selectAll(".dot")
    .data(dataset)
  .enter().append("circle") // Uses the enter().append() method
    .attr("class", "dot") // Assign a class for styling
    .attr("cx", function(d, i) { return xScale(i) })
    .attr("cy", function(d) { return yScale(d.y) })
    .attr("r", 5);


</script>

<style>
/* 13. Basic Styling with CSS */

/* Style the lines by removing the fill and applying a stroke */
.line {
    fill: none;
    stroke: #678C1A;
    stroke-width: 3;
}

.axis text { display: none; }

/* Style the dots by assigning a fill and stroke */
.dot {
    fill: #C7D941;
    stroke: #fff;
}
</style>

因为当我将svg附加到“ body”时效果很好,所以一定是D3图表在加载到Home.vue中时找不到div的情况,对吧?

1 个答案:

答案 0 :(得分:0)

从发布的示例中,我看到了一些语法错误。

  

Home.vue

<template>
  <div id="home">
    <MainChart></MainChart>
  </div>
</template>

<script>
import MainChart from "@/components/MainChart.vue";

export default {
  name: 'chart',
  components: {
    MainChart
  }
}    
</script>

  

MainChart.vue

<template>
  <div id="chart"></div>
</template>

<script>
import * as d3 from "d3";
export default {
  name: "MainChart",
};
// 2. Use the margin convention practice 
var margin = {top: 50, right: 50, bottom: 50, left: 50}
  , width = window.innerWidth - margin.left - margin.right // Use the window's width 
  , height = window.innerHeight - margin.top - margin.bottom; // Use the window's height

// The number of datapoints
var n = 30;

// 5. X scale will use the index of our data
var xScale = d3.scalePow()
    .domain([0, n-1]) // input
    .range([0, width]); // output

// 6. Y scale will use the randomly generate number 
var yScale = d3.scalePow()
    .domain([0, 1000]) // input 
    .range([height, 0]); // output 

// 1. Add the SVG to the page and employ #2
var svg = d3.select("#chart").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// 3. Call the x axis in a group tag
svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(d3.axisBottom(xScale)); // Create an axis component with d3.axisBottom

svg.append("text")
    .attr("class", "x label")
    .attr("text-anchor", "end")
    .attr("x", width)
    .attr("y", height - 6)
    .text("Time");

// 4. Call the y axis in a group tag
svg.append("g")
    .attr("class", "y axis")
    .call(d3.axisLeft(yScale)); // Create an axis component with d3.axisLeft

svg.append("text")
    .attr("class", "y label")
    .attr("text-anchor", "end")
    .attr("y", 6)
    .attr("dy", ".75em")
    .attr("transform", "rotate(-90)")
    .text("Views");


// 7. d3's line generator
var line = d3.line()
    .x(function(d, i) { return xScale(i); }) // set the x values for the line generator
    .y(function(d) { return yScale(d.y); }) // set the y values for the line generator 
    .curve(d3.curveMonotoneX) // apply smoothing to the line

// 8. An array of objects of length N. Each object has key -> value pair, the key being "y" and the value is a random number
// var dataset = d3.range(n).map(function(d) { return {"y": d3.randomUniform(1)() } })
var dataset = [],
    n = 30,
    a = 20,
    b = 1.15;

for (var k = 0; k < n; k++) {
    dataset.push({x: 1 * k, y: a * Math.pow(b, k)});
}

// 9. Append the path, bind the data, and call the line generator 
svg.append("path")
    .datum(dataset) // 10. Binds data to the line 
    .attr("class", "line") // Assign a class for styling
    .attr("d", line) // 11. Calls the line generator  
    .attr("stroke-dasharray", 100 + " " + 100)
    .attr("stroke-dashoffset", 1000)
    .attr("fill", "none")
    .transition()
    .duration(10000)
    .ease(d3.easeLinear)
    .attr("stroke-dashoffset", 0);


// 12. Appends a circle for each datapoint 
svg.selectAll(".dot")
    .data(dataset)
  .enter().append("circle") // Uses the enter().append() method
    .attr("class", "dot") // Assign a class for styling
    .attr("cx", function(d, i) { return xScale(i) })
    .attr("cy", function(d) { return yScale(d.y) })
    .attr("r", 5);

</script>

<style>
.line {
    fill: none;
    stroke: #678C1A;
    stroke-width: 3;
}

.axis text { 
  display: none; 
}

.dot {
    fill: #C7D941;
    stroke: #fff;
}
</style>