Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/90.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 多折线图的颜色重叠部分_Javascript_Html_D3.js - Fatal编程技术网

Javascript 多折线图的颜色重叠部分

Javascript 多折线图的颜色重叠部分,javascript,html,d3.js,Javascript,Html,D3.js,我的代码如下: var数据=[ { 名称:“加拿大”, 价值观:[ {日期:“2000”,价格:“200”}, {日期:“2001”,价格:“120”}, {日期:“2002”,价格:“33”}, {日期:“2003”,价格:“21”}, {日期:“2004”,价格:“51”}, {日期:“2005”,价格:“190”}, {日期:“2006”,价格:“120”}, {日期:“2007”,价格:“85”}, {日期:“2008”,价格:“221”}, {日期:“2009”,价格:“101”}

我的代码如下:

var数据=[
{
名称:“加拿大”,
价值观:[
{日期:“2000”,价格:“200”},
{日期:“2001”,价格:“120”},
{日期:“2002”,价格:“33”},
{日期:“2003”,价格:“21”},
{日期:“2004”,价格:“51”},
{日期:“2005”,价格:“190”},
{日期:“2006”,价格:“120”},
{日期:“2007”,价格:“85”},
{日期:“2008”,价格:“221”},
{日期:“2009”,价格:“101”}
]
},
{
名称:“Maxico”,
价值观:[
{日期:“2000”,价格:“50”},
{日期:“2001”,价格:“10”},
{日期:“2002”,价格:“5”},
{日期:“2003”,价格:“71”},
{日期:“2004”,价格:“20”},
{日期:“2005”,价格:“9”},
{日期:“2006”,价格:“220”},
{日期:“2007”,价格:“235”},
{日期:“2008”,价格:“61”},
{日期:“2009”,价格:“10”}
]
}
];
var宽度=500;
var高度=300;
var保证金=50;
var持续时间=250;
var lineOpacity=“0.25”;
var lineOpacityHover=“0.85”;
var otherLinesOpacityHover=“0.1”;
var lineStroke=“1.5px”;
var linestrokehaver=“2.5px”;
var circleOpacity='0.85';
var circleOpacityOnLineHover=“0.25”
循环变异系数=3;
var circleRadiusHover=6;
/*格式数据*/
var parseDate=d3.timeParse(“%Y”);
data.forEach(函数(d){
d、 值。forEach(函数(d){
d、 日期=解析日期(d.date);
d、 价格=+d.价格;
});
});
/*鳞片*/
var xScale=d3.scaleTime()
.domain(d3.extent(数据[0]。值,d=>d.date))
.范围([0,宽度裕度]);
var yScale=d3.scaleLinear()
.domain([0,d3.max(数据[0]。值,d=>d.price)])
.范围([高度裕度,0]);
var color=d3.scaleOrdinal(d3.schemeCategory 10);
/*添加SVG*/
var svg=d3.选择(“图表”).追加(“svg”)
.attr(“宽度”,“宽度+边距)+“px”)
.attr(“高度”,“高度+边距)+“px”)
.append('g')
.attr(“transform”,`translate(${margin},${margin})`);
/*将行添加到SVG中*/
var line=d3.line()
.x(d=>xScale(d.date))
.y(d=>yScale(d.price));
让line=svg.append('g')
.attr(“类”、“行”);
行。选择全部(“.行组”)
.data(data).enter()
.append('g')
.attr('class','line group')
.on(“鼠标悬停”,功能(d,i){
svg.append(“文本”)
.attr(“类”、“标题文本”)
.样式(“填充”,颜色(i))
.文本(d.名称)
.attr(“文本锚定”、“中间”)
.attr(“x”,(宽度边距)/2)
.attr(“y”,5);
})
.开启(“鼠标出”,功能(d){
选择(“.title text”).remove();
})
.append('路径')
.attr('类','行')
.attr('d',d=>行(d.values))
.style('笔划',(d,i)=>颜色(i))
.style('opacity',lineOpacity)
.on(“鼠标悬停”,功能(d){
d3.选择全部(“.line”)
.style('opacity',otherLinesOpacityHover);
d3.选择全部(“.circle”)
.style('opacity',circleopacityOnline悬停);
d3.选择(本)
.style('opacity',lineOpacityHover)
.style(“笔划宽度”,线条笔划悬停)
.样式(“光标”、“指针”);
})
.开启(“鼠标出”,功能(d){
d3.选择全部(“.行”)
.样式(“不透明度”,线条不透明度);
d3.选择全部(“.circle”)
.样式(“不透明度”,圆形容量);
d3.选择(本)
.style(“笔划宽度”,线条笔划)
.样式(“光标”、“无”);
});
/*在行中添加圆*/
行。选择全部(“圆形组”)
.data(data).enter()
.附加(“g”)
.style(“填充”(d,i)=>颜色(i))
.selectAll(“圆圈”)
.data(d=>d.values)。输入()
.附加(“g”)
.attr(“类”、“圈”)
.on(“鼠标悬停”,功能(d){
d3.选择(本)
.style(“光标”、“指针”)
.append(“文本”)
.attr(“类”、“文本”)
.text(`${d.price}`)
.attr(“x”,d=>xScale(d.date)+5)
.attr(“y”,d=>yScale(d.price)-10);
})
.开启(“鼠标出”,功能(d){
d3.选择(本)
.style(“光标”、“无”)
.transition()
.持续时间(持续时间)
.selectAll(“.text”).remove();
})
.附加(“圆圈”)
.attr(“cx”,d=>xScale(d.date))
.attr(“cy”,d=>yScale(d.price))
.attr(“r”,circleRadius)
.style('opacity',circleOpacity)
.on(“鼠标悬停”,功能(d){
d3.选择(本)
.transition()
.持续时间(持续时间)
.attr(“r”,circleRadiusHover);
})
.开启(“鼠标出”,功能(d){
d3.选择(本)
.transition()
.持续时间(持续时间)
.attr(“r”,circleRadius);
});
/*将Axis添加到SVG中*/
var xAxis=d3.axisBottom(xScale).ticks(5);
var yAxis=d3.axisLeft(yScale).ticks(5);
svg.append(“g”)
.attr(“类”、“x轴”)
.attr(“transform”,`translate(0,${height margin})`)
.呼叫(xAxis);
svg.append(“g”)
.attr(“类”、“y轴”)
.呼叫(yAxis)
.append('文本')
.attr(“y”,15)
.attr(“变换”、“旋转(-90)”)
.attr(“填充”、“千”)
.文本(“总价值”)
svg{
字体系列:无衬线,Arial;
}
.线路{
笔画宽度:5;
填充:无;
}
.轴路径{
笔画:黑色;
}
.文本{
字体大小:12px;
}
.标题文本{
字体大小:12px;
}

第一步是重新建模数据,这样您将拥有一个数组,其中将包含以下类型的对象:{name,price1,price2}

const areaData = [];
data[0].values.forEach((value, index) => {
  areaData.push({date: value.date, price1: value.price, price2: data[1].values[index].price})
})
之后,您必须定义两个区域:一个用于点之间的内部空间(所有区域),另一个仅在第2行点位于第1行上方时才填充

var innerArea = d3.area()
    .x(d => xScale(d.date))
    .y0(d => yScale(d.price2))
    .y1(d => yScale(d.price1));

var line2PositiveArea = d3.area()
    .x(d => xScale(d.date))
    .y0(d => yScale(Math.min(d.price1, d.price2)))
    .y1(d => yScale(d.price2));
这样,您就可以在svg上定义一个剪裁遮罩,用于剪裁具有内部区域曲面定义的正填充区域:

svg
  .append('defs')
  .append('mask')
  .attr('id', 'hole')
  .append('path')
  .attr('d', d => innerArea(areaData))
  .attr('fill', '#fff')
然后,可以将区域添加到线上方的表示中:

svg.append('path')
  .attr('d', d => innerArea(areaData))
  .attr('fill', (d, i) => color(i))

svg.append('path')
  .attr('d', d => line2PositiveArea(areaData))
  .attr('fill', (d, i) => color())
  .attr('mask', 'url(#hole)'); 
下面是完整的js代码

var data = [

  {
    name: "Canada",
    values: [
      {date: "2000", price: "200"},
      {date: "2001", price: "120"},
      {date: "2002", price: "33"},
      {date: "2003", price: "21"},
      {date: "2004", price: "51"},
      {date: "2005", price: "190"},
      {date: "2006", price: "120"},
      {date: "2007", price: "85"},
      {date: "2008", price: "221"},
      {date: "2009", price: "101"}
    ]
  },
  {
    name: "Maxico",
    values: [
      {date: "2000", price: "50"},
      {date: "2001", price: "10"},
      {date: "2002", price: "5"},
      {date: "2003", price: "71"},
      {date: "2004", price: "20"},
      {date: "2005", price: "9"},
      {date: "2006", price: "220"},
      {date: "2007", price: "235"},
      {date: "2008", price: "61"},
      {date: "2009", price: "10"}
    ]
  }
];

var width = 500;
var height = 300;
var margin = 50;
var duration = 250;

var lineOpacity = "0.25";
var lineOpacityHover = "0.85";
var otherLinesOpacityHover = "0.1";
var lineStroke = "1.5px";
var lineStrokeHover = "2.5px";

var circleOpacity = '0.85';
var circleOpacityOnLineHover = "0.25"
var circleRadius = 3;
var circleRadiusHover = 6;


/* Format Data */
var parseDate = d3.timeParse("%Y");
data.forEach(function(d) { 
  d.values.forEach(function(d) {
    d.date = parseDate(d.date);
    d.price = +d.price;    
  });
});


/* Scale */
var xScale = d3.scaleTime()
  .domain(d3.extent(data[0].values, d => d.date))
  .range([0, width-margin]);

var yScale = d3.scaleLinear()
  .domain([0, d3.max(data[0].values, d => d.price)])
  .range([height-margin, 0]);

var color = d3.scaleOrdinal(d3.schemeCategory10);

/* Add SVG */
var svg = d3.select("#chart").append("svg")
  .attr("width", (width+margin)+"px")
  .attr("height", (height+margin)+"px")

var innerArea = d3.area()
    .x(d => xScale(d.date))
    .y0(d => yScale(d.price2))
    .y1(d => yScale(d.price1));

var line2PositiveArea = d3.area()
    .x(d => xScale(d.date))
    .y0(d => yScale(Math.min(d.price1, d.price2)))
    .y1(d => yScale(d.price2));


const areaData = [];
data[0].values.forEach((value, index) => {
  areaData.push({date: value.date, price1: value.price, price2: data[1].values[index].price})
})
svg.append('defs').append('mask').attr('id', 'hole').append('path').attr('d', d => innerArea(areaData)).attr('fill', '#fff')


svg = svg.append('g')
  .attr("transform", `translate(${margin}, ${margin})`);


/* Add line into SVG */
var line = d3.line()
  .x(d => xScale(d.date))
  .y(d => yScale(d.price));

let lines = svg.append('g')
  .attr('class', 'lines');


const linesGroup = lines.selectAll('.line-group')
  .data(data).enter()
  .append('g')
  .attr('class', 'line-group')  
  .on("mouseover", function(d, i) {
      svg.append("text")
        .attr("class", "title-text")
        .style("fill", color(i))        
        .text(d.name)
        .attr("text-anchor", "middle")
        .attr("x", (width-margin)/2)
        .attr("y", 5);
    })
  .on("mouseout", function(d) {
      svg.select(".title-text").remove();
    })


svg.append('path')
  .attr('d', d => innerArea(areaData))
  .attr('fill', (d, i) => color(i))


svg.append('path')
  .attr('d', d => line2PositiveArea(areaData))
  .attr('fill', (d, i) => color())
  .attr('mask', 'url(#hole)'); 


linesGroup.append('path')
  .attr('class', 'line')  
  .attr('d', d => line(d.values))
  .style('stroke', (d, i) => color(i))
  .style('opacity', lineOpacity)
  .on("mouseover", function(d) {
      d3.selectAll('.line')
                    .style('opacity', otherLinesOpacityHover);
      d3.selectAll('.circle')
                    .style('opacity', circleOpacityOnLineHover);
      d3.select(this)
        .style('opacity', lineOpacityHover)
        .style("stroke-width", lineStrokeHover)
        .style("cursor", "pointer");
    })
  .on("mouseout", function(d) {
      d3.selectAll(".line")
                    .style('opacity', lineOpacity);
      d3.selectAll('.circle')
                    .style('opacity', circleOpacity);
      d3.select(this)
        .style("stroke-width", lineStroke)
        .style("cursor", "none");
    });


/* Add circles in the line */
lines.selectAll("circle-group")
  .data(data).enter()
  .append("g")
  .style("fill", (d, i) => color(i))
  .selectAll("circle")
  .data(d => d.values).enter()
  .append("g")
  .attr("class", "circle")  
  .on("mouseover", function(d) {
      d3.select(this)     
        .style("cursor", "pointer")
        .append("text")
        .attr("class", "text")
        .text(`${d.price}`)
        .attr("x", d => xScale(d.date) + 5)
        .attr("y", d => yScale(d.price) - 10);
    })
  .on("mouseout", function(d) {
      d3.select(this)
        .style("cursor", "none")  
        .transition()
        .duration(duration)
        .selectAll(".text").remove();
    })
  .append("circle")
  .attr("cx", d => xScale(d.date))
  .attr("cy", d => yScale(d.price))
  .attr("r", circleRadius)
  .style('opacity', circleOpacity)
  .on("mouseover", function(d) {
        d3.select(this)
          .transition()
          .duration(duration)
          .attr("r", circleRadiusHover);
      })
    .on("mouseout", function(d) {
        d3.select(this) 
          .transition()
          .duration(duration)
          .attr("r", circleRadius);  
      });


/* Add Axis into SVG */
var xAxis = d3.axisBottom(xScale).ticks(5);
var yAxis = d3.axisLeft(yScale).ticks(5);

svg.append("g")
  .attr("class", "x axis")
  .attr("transform", `translate(0, ${height-margin})`)
  .call(xAxis);

svg.append("g")
  .attr("class", "y axis")
  .call(yAxis)
  .append('text')
  .attr("y", 15)
  .attr("transform", "rotate(-90)")
  .attr("fill", "#000")
  .text("Total values");