D3js无法显示渐变面积图

问题描述

我有一个项目需要重新创建渐变图表。我在网上找到了一些关于如何重新创建渐变面积图的文档:Documentation

主要问题是我无法让这段代码工作。我已将其更改为使用我的数据,但图表不会显示。轴被正确渲染。但是图表本身没有显示出来。

我已将 var x = d3.scaleTime().range([0,width]); 替换为 var x = d3.scaleBand().range([0,width]);,因为在文档中他们使用的是 x 轴上的 Date 对象。

没有控制台错误,但图表不会简单地显示出来。代码看起来很简单,但我似乎无法理解它有什么问题。我对 D3.js 非常陌生,并且仍在学习很多关于该库的知识。

<!DOCTYPE html>
    <html>
      <head>
        <title></title>
        <script src="https://unpkg.com/vue"></script>
        <script src="https://d3js.org/d3.v6.js"></script>
      </head>
      <body>
        <div class="p-3 flex flex-col" id="one">
          <div class="w-full flex-1">
            <div id="chart"></div>
          </div>
        </div>

        <script>
          new Vue({
            el: '#one',data: {
              type: Array,required: true,},mounted() {
    // set the dimensions and margins of the graph
    var margin = { top: 20,right: 20,bottom: 30,left: 50 },width = 960 - margin.left - margin.right,height = 500 - margin.top - margin.bottom;

    // append the svg obgect to the body of the page
    // appends a 'group' element to 'svg'
    // moves the 'group' element to the top left margin
    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 + ")");

    var data = [
      {
        date: "Jan",value: 1507
      },{
        date: "Feb",value: 1600
      },{
        date: "Mar",value: 1281
      },{
        date: "Apr",value: 1898
      },{
        date: "May",value: 1749
      },{
        date: "June",value: 1270
      },{
        date: "July",value: 1712
      },{
        date: "Aug",{
        date: "Sept",value: 1257
      },{
        date: "Oct",{
        date: "Nov",{
        date: "Dec",value: 1257
      }
    ];

    // set the ranges
    var x = d3.scaleBand().range([0,width]);

    var y = d3.scaleLinear().rangeRound([height,0]);

    // define the area
    var area = d3
      .area()
      .x(function(d) {
        console.log(d.date);
        console.log(x.domain());
        return x(d.date);
      })

      .y(function(d) {
        console.log(d.value);
        console.log(y.domain());
        return y(d.value);
      });

    x.domain(
      data.map(function(d) {
        return d.date;
      })
    );

    y.domain([
      0,d3.max(data,function(d) {
        return d.value;
      })
    ]);

    // set the gradient
    svg
      .append("linearGradient")
      .attr("id","area-gradient")
      .attr("gradientUnits","userSpaceOnUse")
      .attr("x1",0)
      .attr("y1",y(0))
      .attr("x2",0)
      .attr("y2",y(1000))
      .selectAll("stop")
      .data([
        { offset: "0%",color: "red" },{ offset: "30%",{ offset: "45%",color: "black" },{ offset: "55%",{ offset: "60%",color: "lawngreen" },{ offset: "100%",color: "lawngreen" }
      ])
      .enter()
      .append("stop")
      .attr("offset",function(d) {
        return d.offset;
      })
      .attr("stop-color",function(d) {
        return d.color;
      });

    // Add the area.
    svg
      .append("path")
      .datum(data)
      .attr("class","area")
      .attr("d",area);

    // Add the X Axis
    svg
      .append("g")
      .attr("transform","translate(0," + height + ")")
      .call(d3.axisBottom(x));

    // Add the Y Axis
    svg.append("g").call(d3.axisLeft(y));
  }
          });
        </script>
      </body>
    </html>

解决方法

两件事。

首先,您错过了设置 css 以填充渐变的 path

.area {                         
  fill: url(#area-gradient);                    
  stroke-width: 0px;            
}

其次,为了绘制“区域”,d3.area 生成器需要 .y0.y1 accessors。这就是从这里到那里填充的意思。

var area = d3
 .area()
 .x(function (d) {
   return x(d.date);
 })
 .y1(function (d) {
   return y(d.value);
 })
 .y0(height);

运行片段:

<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <script src="https://unpkg.com/vue"></script>
    <script src="https://d3js.org/d3.v6.js"></script>
    <style>
      .area {
        fill: url(#area-gradient);
        stroke-width: 0px;
      }
    </style>
  </head>
  <body>
    <div class="p-3 flex flex-col" id="one">
      <div class="w-full flex-1">
        <div id="chart"></div>
      </div>
    </div>

    <script>
      new Vue({
        el: '#one',data: {
          type: Array,required: true,},mounted() {
          // set the dimensions and margins of the graph
          var margin = { top: 20,right: 20,bottom: 30,left: 50 },width = 960 - margin.left - margin.right,height = 500 - margin.top - margin.bottom;

          // append the svg obgect to the body of the page
          // appends a 'group' element to 'svg'
          // moves the 'group' element to the top left margin
          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 + ')'
            );

          var data = [
            {
              date: 'Jan',value: 1507,{
              date: 'Feb',value: 1600,{
              date: 'Mar',value: 1281,{
              date: 'Apr',value: 1898,{
              date: 'May',value: 1749,{
              date: 'June',value: 1270,{
              date: 'July',value: 1712,{
              date: 'Aug',{
              date: 'Sept',value: 1257,{
              date: 'Oct',{
              date: 'Nov',{
              date: 'Dec',];

          // set the ranges
          var x = d3.scaleBand().range([0,width]);

          var y = d3.scaleLinear().rangeRound([height,0]);

          // define the area
          var area = d3
            .area()
            .x(function (d) {
              return x(d.date);
            })
            .y1(function (d) {
              return y(d.value);
            })
            .y0(height);

          x.domain(
            data.map(function (d) {
              return d.date;
            })
          );

          y.domain([
            0,d3.max(data,function (d) {
              return d.value;
            }),]);

          // set the gradient
          svg
            .append('linearGradient')
            .attr('id','area-gradient')
            .attr('gradientUnits','userSpaceOnUse')
            .attr('x1',0)
            .attr('y1',y(0))
            .attr('x2',0)
            .attr('y2',y(1000))
            .selectAll('stop')
            .data([
              { offset: '0%',color: 'red' },{ offset: '30%',{ offset: '45%',color: 'black' },{ offset: '55%',{ offset: '60%',color: 'lawngreen' },{ offset: '100%',])
            .enter()
            .append('stop')
            .attr('offset',function (d) {
              return d.offset;
            })
            .attr('stop-color',function (d) {
              return d.color;
            });

          // Add the area.
          svg.append('path').datum(data).attr('class','area').attr('d',area);

          // Add the X Axis
          svg
            .append('g')
            .attr('transform','translate(0,' + height + ')')
            .call(d3.axisBottom(x));

          // Add the Y Axis
          svg.append('g').call(d3.axisLeft(y));
        },});
    </script>
  </body>
</html>

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...