Javascript 修改D3流图中流的位置

Javascript 修改D3流图中流的位置,javascript,d3.js,visualization,stream-graph,Javascript,D3.js,Visualization,Stream Graph,我正在尝试构建类似于以下内容的D3可视化: group,translation,value,date "Grain","pearl barley",0,1640, "Grain","pearl barley",662,1641, "Grain","pearl barley",0,1642, "Grain","pearl barley",0,1643, "Grain","pearl barley",432,1644, "Grain","pearl barley",789,1645, "Grain"

我正在尝试构建类似于以下内容的D3可视化:

group,translation,value,date
"Grain","pearl barley",0,1640,
"Grain","pearl barley",662,1641,
"Grain","pearl barley",0,1642,
"Grain","pearl barley",0,1643,
"Grain","pearl barley",432,1644,
"Grain","pearl barley",789,1645,
"Grain","pearl barley",408.5,1646,
"Grain","pearl barley",0,1647,
"Grain","pearl barley",0,1648,
"Grain","pearl barley",0,1649,
"Grain","pearl barley",0,1650,
"Grain","pearl barley",0,1651,
"Grain","pearl barley",0,1652,
"Grain","pearl barley",0,1653,
"Grain","pearl barley",0,1654,
"Grain","pearl barley",0,1655,
"Grain","pearl barley",0,1656,
"Grain","pearl barley",0,1657,
"Grain","pearl barley",0,1658,
"Grain","pearl barley",0,1659,
"Grain","pearl barley",0,1660,
"Grain","pearl barley",0,1661,
"Grain","pearl barley",0,1662,
"Grain","pearl barley",1808,1663,
"Grain","pearl barley",48,1664,
"Grain","pearl barley",0,1665,
"Grain","pearl barley",0,1666,
"Grain","pearl barley",0,1667,
"Grain","pearl barley",172,1668,
"Grain","pearl barley",0,1669,
"Grain","pearl barley",0,1670,
"Grain","pearl barley",8,1671,
"Grain","pearl barley",0,1672,
"Grain","pearl barley",0,1673,
"Grain","pearl barley",0,1674,
"Grain","pearl barley",0,1675,
"Grain","pearl barley",0,1676,
"Grain","pearl barley",0,1677,
"Grain","pearl barley",0,1678,
"Grain","pearl barley",0,1679,
"Grain","pearl barley",0,1680,
"Grain","pearl barley",48,1681,
"Grain","pearl barley",0,1682,
"Grain","pearl barley",0,1683,
"Grain","pearl barley",0,1684,
"Grain","pearl barley",0,1685,
"Grain","pearl barley",0,1686,
"Grain","pearl barley",0,1687,
"Grain","pearl barley",0,1688,
"Grain","wheat flour",0,1640,
"Grain","wheat flour",0,1641,
"Grain","wheat flour",0,1642,
"Grain","wheat flour",0,1643,
"Grain","wheat flour",0,1644,
"Grain","wheat flour",0,1645,
"Grain","wheat flour",0,1646,
"Grain","wheat flour",0,1647,
"Grain","wheat flour",0,1648,
"Grain","wheat flour",0,1649,
"Grain","wheat flour",0,1650,
"Grain","wheat flour",0,1651,
"Grain","wheat flour",0,1652,
"Grain","wheat flour",0,1653,
"Grain","wheat flour",0,1654,
"Grain","wheat flour",0,1655,
"Grain","wheat flour",0,1656,
"Grain","wheat flour",0,1657,
"Grain","wheat flour",0,1658,
"Grain","wheat flour",0,1659,
"Grain","wheat flour",0,1660,
"Grain","wheat flour",0,1661,
"Grain","wheat flour",0,1662,
"Grain","wheat flour",0,1663,
"Grain","wheat flour",0,1664,
"Grain","wheat flour",0,1665,
"Grain","wheat flour",0,1666,
"Grain","wheat flour",0,1667,
"Grain","wheat flour",0,1668,
"Grain","wheat flour",0,1669,
"Grain","wheat flour",0,1670,
"Grain","wheat flour",0,1671,
"Grain","wheat flour",0,1672,
"Grain","wheat flour",0,1673,
"Grain","wheat flour",0,1674,
"Grain","wheat flour",0,1675,
"Grain","wheat flour",0,1676,
"Grain","wheat flour",0,1677,
"Grain","wheat flour",0,1678,
"Grain","wheat flour",168,1679,
"Grain","wheat flour",0,1680,
"Grain","wheat flour",0,1681,
"Grain","wheat flour",0,1682,
"Grain","wheat flour",0,1683,
"Grain","wheat flour",0,1684,
"Grain","wheat flour",0,1685,
"Grain","wheat flour",0,1686,
"Grain","wheat flour",0,1687,
"Grain","wheat flour",0,1688,

()

我最初开始尝试修改博斯托克的a示例,但我倾向于这样一个想法,即布局可能会更好地为我服务。我正在研究食品消费随时间的变化。例如,数据看起来类似于:

group,translation,value,date
"Grain","pearl barley",0,1640,
"Grain","pearl barley",662,1641,
"Grain","pearl barley",0,1642,
"Grain","pearl barley",0,1643,
"Grain","pearl barley",432,1644,
"Grain","pearl barley",789,1645,
"Grain","pearl barley",408.5,1646,
"Grain","pearl barley",0,1647,
"Grain","pearl barley",0,1648,
"Grain","pearl barley",0,1649,
"Grain","pearl barley",0,1650,
"Grain","pearl barley",0,1651,
"Grain","pearl barley",0,1652,
"Grain","pearl barley",0,1653,
"Grain","pearl barley",0,1654,
"Grain","pearl barley",0,1655,
"Grain","pearl barley",0,1656,
"Grain","pearl barley",0,1657,
"Grain","pearl barley",0,1658,
"Grain","pearl barley",0,1659,
"Grain","pearl barley",0,1660,
"Grain","pearl barley",0,1661,
"Grain","pearl barley",0,1662,
"Grain","pearl barley",1808,1663,
"Grain","pearl barley",48,1664,
"Grain","pearl barley",0,1665,
"Grain","pearl barley",0,1666,
"Grain","pearl barley",0,1667,
"Grain","pearl barley",172,1668,
"Grain","pearl barley",0,1669,
"Grain","pearl barley",0,1670,
"Grain","pearl barley",8,1671,
"Grain","pearl barley",0,1672,
"Grain","pearl barley",0,1673,
"Grain","pearl barley",0,1674,
"Grain","pearl barley",0,1675,
"Grain","pearl barley",0,1676,
"Grain","pearl barley",0,1677,
"Grain","pearl barley",0,1678,
"Grain","pearl barley",0,1679,
"Grain","pearl barley",0,1680,
"Grain","pearl barley",48,1681,
"Grain","pearl barley",0,1682,
"Grain","pearl barley",0,1683,
"Grain","pearl barley",0,1684,
"Grain","pearl barley",0,1685,
"Grain","pearl barley",0,1686,
"Grain","pearl barley",0,1687,
"Grain","pearl barley",0,1688,
"Grain","wheat flour",0,1640,
"Grain","wheat flour",0,1641,
"Grain","wheat flour",0,1642,
"Grain","wheat flour",0,1643,
"Grain","wheat flour",0,1644,
"Grain","wheat flour",0,1645,
"Grain","wheat flour",0,1646,
"Grain","wheat flour",0,1647,
"Grain","wheat flour",0,1648,
"Grain","wheat flour",0,1649,
"Grain","wheat flour",0,1650,
"Grain","wheat flour",0,1651,
"Grain","wheat flour",0,1652,
"Grain","wheat flour",0,1653,
"Grain","wheat flour",0,1654,
"Grain","wheat flour",0,1655,
"Grain","wheat flour",0,1656,
"Grain","wheat flour",0,1657,
"Grain","wheat flour",0,1658,
"Grain","wheat flour",0,1659,
"Grain","wheat flour",0,1660,
"Grain","wheat flour",0,1661,
"Grain","wheat flour",0,1662,
"Grain","wheat flour",0,1663,
"Grain","wheat flour",0,1664,
"Grain","wheat flour",0,1665,
"Grain","wheat flour",0,1666,
"Grain","wheat flour",0,1667,
"Grain","wheat flour",0,1668,
"Grain","wheat flour",0,1669,
"Grain","wheat flour",0,1670,
"Grain","wheat flour",0,1671,
"Grain","wheat flour",0,1672,
"Grain","wheat flour",0,1673,
"Grain","wheat flour",0,1674,
"Grain","wheat flour",0,1675,
"Grain","wheat flour",0,1676,
"Grain","wheat flour",0,1677,
"Grain","wheat flour",0,1678,
"Grain","wheat flour",168,1679,
"Grain","wheat flour",0,1680,
"Grain","wheat flour",0,1681,
"Grain","wheat flour",0,1682,
"Grain","wheat flour",0,1683,
"Grain","wheat flour",0,1684,
"Grain","wheat flour",0,1685,
"Grain","wheat flour",0,1686,
"Grain","wheat flour",0,1687,
"Grain","wheat flour",0,1688,
流图布局非常简单,可以开始:

<script>

chart("data/grains.csv", "orange");

var datearray = [];
var colorrange = [];


function chart(csvpath, color) {

  if (color == "blue") {
    colorrange = ["#045A8D", "#2B8CBE", "#74A9CF", "#A6BDDB", "#D0D1E6", "#F1EEF6"];
  }
  else if (color == "pink") {
    colorrange = ["#980043", "#DD1C77", "#DF65B0", "#C994C7", "#D4B9DA", "#F1EEF6"];
  }
  else if (color == "orange") {
    colorrange = ["#B30000", "#E34A33", "#FC8D59", "#FDBB84", "#FDD49E", "#FEF0D9"];
  }
  strokecolor = colorrange[0];

  var format = d3.time.format("%Y");

  var margin = {top: 20, right: 60, bottom: 30, left: 60};
  var width = document.body.clientWidth - margin.left - margin.right;
  var height = 400 - margin.top - margin.bottom;

  var tooltip = d3.select("body")
      .append("div")
      .attr("class", "remove")
      .style("position", "absolute")
      .style("z-index", "20")
      .style("visibility", "hidden")
      .style("top", "30px")
      .style("left", "55px");

  var x = d3.time.scale()
      .range([0, width]);

  var y = d3.scale.linear()
      .range([height-10, 0]);

  var z = d3.scale.ordinal()
      .range(colorrange);

  var xAxis = d3.svg.axis()
      .scale(x)
      .orient("bottom")
      .ticks(d3.time.years);

  var yAxis = d3.svg.axis()
      .scale(y);

  var yAxisr = d3.svg.axis()
      .scale(y);

  var stack = d3.layout.stack()
      .offset("expand")
      .values(function(d) { return d.values; })
      .x(function(d) { return d.date; })
      .y(function(d) { return d.value; });

  var nest = d3.nest()
      .key(function(d) { return d.translation; });

  var area = d3.svg.area()
      .interpolate("cardinal")
      .x(function(d) { return x(d.date); })
      .y0(function(d) { return y(d.y0) - 2; }) // mess with margin
      .y1(function(d) { return y(d.y0 + d.y) + 2; }); // mess with 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 graph = d3.csv(csvpath, function(data) {
    data.forEach(function(d) {
      d.date = format.parse(d.date);
      d.value = +d.value;
    });

    var layers = stack(nest.entries(data));

    x.domain(d3.extent(data, function(d) { return d.date; }));
    y.domain([0, d3.max(data, function(d) { return d.y0 + d.y; })]);

    svg.selectAll(".layer")
        .data(layers)
      .enter().append("path")
        .attr("class", "layer")
        .attr("d", function(d) { return area(d.values); })
        .style("fill", function(d, i) { return z(i); });


    svg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis);

    // svg.append("g")
    //     .attr("class", "y axis")
    //     .attr("transform", "translate(" + width + ", 0)")
    //     .call(yAxis.orient("right"));

    // svg.append("g")
        // .attr("class", "y axis")
        // .call(yAxis.orient("left"));

    svg.selectAll(".layer")
      .attr("opacity", 1)
      .on("mouseover", function(d, i) {
        svg.selectAll(".layer").transition()
        .duration(250)
        .attr("opacity", function(d, j) {
          return j != i ? 0.6 : 1;
      })})

      .on("mousemove", function(d, i) {
        mousex = d3.mouse(this);
        mousex = mousex[0];
        var invertedx = x.invert(mousex);
        invertedx = invertedx.getFullYear() + invertedx.getDate();
        var selected = (d.values);
        for (var k = 0; k < selected.length; k++) {
          datearray[k] = selected[k].date
          datearray[k] = datearray[k].getFullYear() + datearray[k].getDate();
        }

        mousedate = datearray.indexOf(invertedx);
        pro = d.values[mousedate].value;

        d3.select(this)
        .classed("hover", true)
        .attr("stroke", strokecolor)
        .attr("stroke-width", "0.5px"),
        tooltip.html( "<p>" + d.key + "<br>" + pro + "</p>" ).style("visibility", "visible");

      })
      .on("mouseout", function(d, i) {
       svg.selectAll(".layer")
        .transition()
        .duration(250)
        .attr("opacity", "1");
        d3.select(this)
        .classed("hover", false)
        .attr("stroke-width", "0px"), tooltip.html( "<p>" + d.key + "<br>" + pro + "</p>" ).style("visibility", "hidden");
    })

    var vertical = d3.select(".chart")
          .append("div")
          .attr("class", "remove")
          .style("position", "absolute")
          .style("z-index", "19")
          .style("width", "1px")
          .style("height", "380px")
          .style("top", "10px")
          .style("bottom", "30px")
          .style("left", "0px")
          .style("background", "#fff");

    d3.select(".chart")
        .on("mousemove", function(){
           mousex = d3.mouse(this);
           mousex = mousex[0] + 5;
           vertical.style("left", mousex + "px" )})
        .on("mouseover", function(){
           mousex = d3.mouse(this);
           mousex = mousex[0] + 5;
           vertical.style("left", mousex + "px")});
  });
}
</script>

图表(“data/grains.csv”、“橙色”);
var datearray=[];
var colorrange=[];
功能图(csvpath,彩色){
如果(颜色=“蓝色”){
颜色范围=[“045A8D”、“2B8CBE”、“74A9CF”、“A6BDDB”、“D0D1E6”、“F1EEF6”];
}
否则如果(颜色=“粉色”){
颜色范围=[“980043”、“DD1C77”、“DF65B0”、“C994C7”、“D4B9DA”、“F1EEF6”];
}
else if(颜色=“橙色”){
颜色范围=[“B30000”、“E34A33”、“FC8D59”、“FDBB84”、“FDD49E”、“FEF0D9];
}
strokecolor=颜色范围[0];
var format=d3.time.format(“%Y”);
var-margin={顶部:20,右侧:60,底部:30,左侧:60};
var width=document.body.clientWidth-margin.left-margin.right;
变量高度=400-margin.top-margin.bottom;
变量工具提示=d3。选择(“主体”)
.附加(“div”)
.attr(“类”、“删除”)
.style(“位置”、“绝对”)
.风格(“z指数”、“20”)
.style(“可见性”、“隐藏”)
.样式(“顶部”、“30px”)
.样式(“左”、“55px”);
var x=d3.time.scale()
.范围([0,宽度]);
变量y=d3.scale.linear()
.范围([高度-10,0]);
var z=d3.scale.ordinal()
.范围(颜色范围);
var xAxis=d3.svg.axis()
.比例(x)
.orient(“底部”)
.滴答声(d3.时间.年);
var yAxis=d3.svg.axis()
.比例(y);
var yAxisr=d3.svg.axis()
.比例(y);
var stack=d3.layout.stack()
.抵销(“扩大”)
.values(函数(d){返回d.values;})
.x(函数(d){返回d.date;})
.y(函数(d){返回d.value;});
var nest=d3.nest()
.key(函数(d){返回d.translation;});
var area=d3.svg.area()
.插入(“基数”)
.x(函数(d){返回x(d.date);})
.y0(函数(d){返回y(d.y0)-2;})//带边距的乱序
.y1(函数(d){返回y(d.y0+d.y)+2;});//带边距的混乱
var svg=d3。选择(“.chart”)。追加(“svg”)
.attr(“宽度”,宽度+边距。左侧+边距。右侧)
.attr(“高度”,高度+边距。顶部+边距。底部)
.附加(“g”)
.attr(“转换”、“平移”(+margin.left+)、“+margin.top+”);
变量图=d3.csv(csvpath,函数(数据){
data.forEach(函数(d){
d、 日期=format.parse(d.date);
d、 值=+d.值;
});
var层=堆栈(nest.entries(data));
x、 域(d3.extent(数据,函数(d){返回d.date;}));
y、 域([0,d3.max(数据,函数(d){返回d.y0+d.y;})];
svg.selectAll(“.layer”)
.数据(图层)
.enter().append(“路径”)
.attr(“类”、“层”)
.attr(“d”,函数(d){返回区域(d.values);})
.style(“fill”,函数(d,i){返回z(i);});
svg.append(“g”)
.attr(“类”、“x轴”)
.attr(“变换”、“平移(0)”、“高度+”)
.呼叫(xAxis);
//svg.append(“g”)
//.attr(“类”、“y轴”)
//.attr(“变换”、“平移”(+width+),0)
//.call(yAxis.orient(“右”);
//svg.append(“g”)
//.attr(“类”、“y轴”)
//.呼叫(yAxis.orient(“左”);
svg.selectAll(“.layer”)
.attr(“不透明度”,1)
.on(“鼠标悬停”,功能(d,i){
svg.selectAll(“.layer”).transition()
.持续时间(250)
.attr(“不透明度”,函数(d,j){
返回j!=i?0.6:1;
})})
.on(“mousemove”,函数(d,i){
mousex=d3.鼠标(this);
mousex=mousex[0];
var逆变器dx=x.invert(mousex);
invertedx=invertedx.getFullYear()+invertedx.getDate();
所选var=(d.值);
对于(var k=0;k“+pro+”

”)。样式(“可见性”、“可见”); }) .on(“mouseout”,函数(d,i){ svg.selectAll(“.layer”) .transition() .持续时间(250) .attr(“不透明度”、“1”); d3.选择(本) .classed(“悬停”,假) .attr(“笔划宽度”、“0px”)、tooltip.html(“可见性”、“隐藏”); }) 垂直变量=d3。选择(“.图表”) .附加(“div”) .attr(“类”、“删除”) .style(“位置”、“绝对”) .风格(“z指数”、“19”) .样式(“宽度”、“1px”) .样式(“高度”,“380px”) .样式(“顶部”、“10px”) .样式(“底部”、“30px”) .style(“左”、“0px”) .风格(“背景”、“fff”); d3.选择(“图表”) .on(“mousemove”,function(){ mousex=d3.鼠标(this); mousex=mousex[0]+5; 垂直样式(“左”,mousex+“px”)}) .on(“鼠标悬停”,函数(){ mousex=d3.鼠标(this); mousex=mousex[0]+5; 垂直样式(“左”,mousex+“px”)}); }); }

但是,我还需要的是,流的位置随着消耗量的变化而变化,如上图所示。我可以修改流布局以实现此效果吗?或者我需要写一个自定义的布局来工作吗?任何提示或想法都会很有帮助。

嗯,在我看来,您似乎需要自定义布局。总的来说,它让我想起了更多的是一个而不是一个流布局