Javascript D3 v3分组条形图,通过刷牙进行平移和缩放

Javascript D3 v3分组条形图,通过刷牙进行平移和缩放,javascript,d3.js,Javascript,D3.js,我正在尝试为分组条形图实现D3V3缩放和平移 我的尝试如下: 仅供参考:我使用的是d3版本3 var main_margin = { top: 10, right: 10, bottom: 100, left: 40 }, mini_margin = { top: 430, right: 10, bottom: 20, left: 40 }, width = 960 - main_margin.left - main_margin.right, main_height = 500 -

我正在尝试为分组条形图实现D3V3缩放和平移

我的尝试如下:

仅供参考:我使用的是d3版本3

var main_margin = { top: 10, right: 10, bottom: 100, left: 40 },
  mini_margin = { top: 430, right: 10, bottom: 20, left: 40 },
  width = 960 - main_margin.left - main_margin.right,
  main_height = 500 - main_margin.top - main_margin.bottom,
  mini_height = 500 - mini_margin.top - mini_margin.bottom;


var main_x0 = d3.scale.ordinal()
  .rangeRoundBands([0, width], .4, .2);

var mini_x0 = d3.scale.ordinal()
  .rangeRoundBands([0, width], .4, .2);

var main_x1 = d3.scale.ordinal();
var mini_x1 = d3.scale.ordinal();

var main_y = d3.scale.linear()
  .range([main_height, 0]);

var mini_y = d3.scale.linear()
  .range([mini_height, 0]);

var main_xAxis = d3.svg.axis()
  .scale(main_x0)
  .tickSize(0)
  .orient("bottom");

var mini_xAxis = d3.svg.axis()
  .scale(mini_x0)
  .tickSize(0)
  .orient("bottom");

var yAxis = d3.svg.axis()
  .scale(main_y)
  .orient("left");

var color3 = d3.scale.ordinal()
  .range(["rgb(101,154,302)", "rgb(247, 201, 38)"]);




var svg3 = d3.select('#barchart2').append("svg")
  .attr("width", width + main_margin.left + main_margin.right)
  .attr("height", main_height + main_margin.top + main_margin.bottom)
  .append("g")
  .attr("transform", "translate(" + main_margin.left + "," + main_margin.top + ")");

svg3.append("defs").append("clipPath")
  .attr("id", "clip")
  .append("rect")
  .attr("width", width)
  .attr("height", main_height);

//d3.json("../data/bardata1.json", function(error, data) {
debugger
var data = [
  {
    "categorie": "Sugarcane",
    "values": [
      {
        "value": 10,
        "rate": "Acres"
      },
      {
        "value": 4,
        "rate": "No of Farmers"
      }
    ]
  },
  {
    "categorie": "Soyabean",
    "values": [
      {
        "value": 18,
        "rate": "Acres"
      },
      {
        "value": 12,
        "rate": "No of Farmers"
      }


    ]
  },
  {
    "categorie": "Wheat",
    "values": [
      {
        "value": 11,
        "rate": "Acres"
      },
      {
        "value": 8,
        "rate": "No of Farmers"
      }
    ]
  },
  {
    "categorie": "Cotton",
    "values": [
      {
        "value": 22,
        "rate": "Acres"
      },
      {
        "value": 16,
        "rate": "No of Farmers"
      }
    ]
  },
  {
    "categorie": "Sugarcane1",
    "values": [
      {
        "value": 10,
        "rate": "Acres"
      },
      {
        "value": 4,
        "rate": "No of Farmers"
      }
    ]
  },
  {
    "categorie": "Soyabean1",
    "values": [
      {
        "value": 18,
        "rate": "Acres"
      },
      {
        "value": 12,
        "rate": "No of Farmers"
      }


    ]
  },
  {
    "categorie": "Wheat1",
    "values": [
      {
        "value": 11,
        "rate": "Acres"
      },
      {
        "value": 8,
        "rate": "No of Farmers"
      }
    ]
  },
  {
    "categorie": "Cotton1",
    "values": [
      {
        "value": 22,
        "rate": "Acres"
      },
      {
        "value": 16,
        "rate": "No of Farmers"
      }
    ]
  },
  {
    "categorie": "Sugarcane11",
    "values": [
      {
        "value": 10,
        "rate": "Acres"
      },
      {
        "value": 4,
        "rate": "No of Farmers"
      }
    ]
  },
  {
    "categorie": "Soyabean11",
    "values": [
      {
        "value": 18,
        "rate": "Acres"
      },
      {
        "value": 12,
        "rate": "No of Farmers"
      }


    ]
  },
  {
    "categorie": "Wheat11",
    "values": [
      {
        "value": 11,
        "rate": "Acres"
      },
      {
        "value": 8,
        "rate": "No of Farmers"
      }
    ]
  },
  {
    "categorie": "Cotton11",
    "values": [
      {
        "value": 22,
        "rate": "Acres"
      },
      {
        "value": 16,
        "rate": "No of Farmers"
      }
    ]
  },
  {
    "categorie": "Sugarcane111",
    "values": [
      {
        "value": 10,
        "rate": "Acres"
      },
      {
        "value": 4,
        "rate": "No of Farmers"
      }
    ]
  },
  {
    "categorie": "Soyabean111",
    "values": [
      {
        "value": 18,
        "rate": "Acres"
      },
      {
        "value": 12,
        "rate": "No of Farmers"
      }


    ]
  },
  {
    "categorie": "Wheat111",
    "values": [
      {
        "value": 11,
        "rate": "Acres"
      },
      {
        "value": 8,
        "rate": "No of Farmers"
      }
    ]
  },
  {
    "categorie": "Cotton111",
    "values": [
      {
        "value": 22,
        "rate": "Acres"
      },
      {
        "value": 16,
        "rate": "No of Farmers"
      }
    ]
  },
  {
    "categorie": "Sugarcane1111",
    "values": [
      {
        "value": 10,
        "rate": "Acres"
      },
      {
        "value": 4,
        "rate": "No of Farmers"
      }
    ]
  },
  {
    "categorie": "Soyabean1111",
    "values": [
      {
        "value": 18,
        "rate": "Acres"
      },
      {
        "value": 12,
        "rate": "No of Farmers"
      }


    ]
  },
  {
    "categorie": "Wheat1111",
    "values": [
      {
        "value": 11,
        "rate": "Acres"
      },
      {
        "value": 8,
        "rate": "No of Farmers"
      }
    ]
  },
  {
    "categorie": "Cotton1111",
    "values": [
      {
        "value": 22,
        "rate": "Acres"
      },
      {
        "value": 16,
        "rate": "No of Farmers"
      }
    ]
  }

];
var categoriesNames = data.map(function (d) { return d.categorie; });
var rateNames = data[0].values.map(function (d) { return d.rate; });

main_x0.domain(categoriesNames);
mini_x0.domain(main_x0.domain());

main_x1.domain(rateNames).rangeRoundBands([0, main_x0.rangeBand()]);
mini_x1.domain(main_x1.domain());

main_y.domain([0, d3.max(data, function (categorie) { return d3.max(categorie.values, function (d) { return d.value; }); })]);
mini_y.domain(main_y.domain());
svg3.append("g")
  .attr("class", "x axis")
  .attr("transform", "translate(0," + main_height + ")")
  .style("font-size", 14)
  .call(main_xAxis);

svg3.append("g")
  .attr("class", "x axis")
  .attr("transform", "translate(0," + main_height + ")")
  .style("font-size", 14)
  .call(mini_xAxis);

svg3.append("g")
  .attr("class", "y axis")
  .style('opacity', '0')
  .call(yAxis)
  .append("text")
  .attr("transform", "rotate(-90)")
  .attr("y", 8)
  .attr("dy", ".72em")
  .style("text-anchor", "end")
  .style('font-weight', 'bold')
  .text("Value");

svg3.select('.y').transition().duration(500).delay(1300).style('opacity', '1');

var brush = d3.svg.brush()
  .x(mini_x0)
  .on("brush", brushed);

var focus = svg3.append("g")
  .attr("class", "focus")
  .attr("transform", "translate(" + main_margin.left + "," + main_margin.top + ")");

var context = svg3.append("g")
  .attr("class", "context")
  .attr("transform", "translate(" + mini_margin.left + "," + mini_margin.top + ")");

var zoom = d3.behavior.zoom()
  .on("zoom", draw);
// Add rect cover the zoomed graph and attach zoom event.
var rect = svg3.append("svg:rect")
  .attr("class", "pane")
  .attr("width", width)
  .attr("height", main_height)
  .attr("transform", "translate(" + main_margin.left + "," + main_margin.top + ")")
  .call(zoom);

var slice = svg3.selectAll(".slice")
  .data(data)
  .enter().append("g")
  .attr("class", "g")
  .attr("transform", function (d) { return "translate(" + main_x0(d.categorie) + ",0)"; });

slice.selectAll("rect")
  .data(function (d) { return d.values; })
  .enter().append("rect")
  .attr("width", main_x1.rangeBand())
  .attr("x", function (d) { return main_x1(d.rate); })
  .style("fill", function (d) { return color3(d.rate) })
  .attr("y", function (d) { return main_y(0); })
  .attr("height", function (d) { return main_height - main_y(0); })


slice.selectAll("rect")
  .transition()
  .delay(function (d) { return Math.random() * 1000; })
  .duration(1000)
  .attr("y", function (d) { return main_y(d.value); })
  .attr("height", function (d) { return main_height - main_y(d.value); });

slice.selectAll("text")
  .data(function (d) { return d.values; })
  .enter().append("text")
  .attr("class", "barstext")
  .style("font-size", 14)
  .attr("x", function (d) { return main_x1(d.rate) + 10; })
  .attr("y", function (d) { return main_y(d.value) - 4; })
  .text(function (d) { return (d.value); })


var slice2 = svg3.selectAll(".slice")
  .data(data)
  .enter().append("g")
  .attr("class", "g")
  .attr("transform", function (d) { return "translate(" + mini_x0(d.categorie) + ",0)"; });

slice2.selectAll("rect")
  .data(function (d) { return d.values; })
  .enter().append("rect")
  .attr("width", mini_x0.rangeBand())
  .attr("x", function (d) { return mini_x1(d.rate); })
  .style("fill", function (d) { return color3(d.rate) })
  .attr("y", function (d) { return mini_y(0); })
  .attr("height", function (d) { return mini_height - mini_y(0); })


slice2.selectAll("rect")
  .transition()
  .delay(function (d) { return Math.random() * 1000; })
  .duration(1000)
  .attr("y", function (d) { return mini_y(d.value); })
  .attr("height", function (d) { return mini_height - mini_y(d.value); });

slice2.selectAll("text2")
  .data(function (d) { return d.values; })
  .enter().append("text2")
  .attr("class", "barstext")
  .style("font-size", 14)
  .attr("x", function (d) { return mini_x1(d.rate) + 10; })
  .attr("y", function (d) { return mini_y(d.value) - 4; })
  .text(function (d) { return (d.value); })

//Legend
//Legend
var legend = svg3.selectAll(".legend")
  .data(data[0].values.map(function (d) { return d.rate; }).reverse())
  .enter().append("g")
  .attr("class", "legend")
  .attr("transform", function (d, i) { return "translate(" + i * -150 + ",0)"; })
  .style("opacity", "0");

legend.append("rect")
  .attr("transform", "translate(" + width / 4 + "," + (main_height) + ")")
  .attr("x", width / 4 - 96)
  .attr("y", 24)
  .attr("width", 18)
  .attr("height", 18)
  .style("fill", function (d) { return color3(d); });


legend.append("text")
  .attr("transform", "translate(" + width / 4 + "," + (main_height) + ")")
  .attr("x", width / 4 - 72)
  .attr("y", 36)
  .attr("dy", ".20em")
  .style("font-size", 14)
  .style("text-anchor", "start")
  .text(function (d) { return d; });

legend.transition().duration(500).delay(function (d, i) { return 1300 + 100 * i; }).style("opacity", "1");
zoom.x(main_x0);
在这里,我得到了错误属性d:预期的moveto路径命令('M'或'M'),“[object SVGGElem…” focus.append(“路径”) .数据(数据) .attr(“类”、“切片”) .attr(“d”,切片)

我能知道如何解决这个问题吗?谢谢你的帮助

focus.append("g")
  .attr("class", "x axis")
  .attr("transform", "translate(0," + main_height + ")")
  .call(main_xAxis);

focus.append("g")
  .attr("class", "y axis")
  .call(yAxis);

context.append("path")
  .data(data)
  .attr("class", "slice")
  .attr("d", slice2);

context.append("g")
  .attr("class", "x axis")
  .attr("transform", "translate(0," + mini_height + ")")
  .call(mini_xAxis);

context.append("g")
  .attr("class", "x brush")
  .call(brush)
  .selectAll("rect")
  .attr("main_y", -6)
  .attr("height", mini_height + 7);


function draw() {
  focus.select(".slice").attr("d", slice);
  focus.select(".x.axis").call(main_xAxis);
  // Force changing brush range
  brush.extent(main_x0.domain());
  svg.select(".brush").call(brush);
}


function brushed() {
  main_x0.domain(brush.empty() ? mini_x0.domain() : brush.extent());
  focus.select(".slice").attr("d", slice);
  focus.select(".x.axis").call(main_xAxis);
  // Reset zoom scale's domain
  zoom.x(main_x0);
}





//});