javascript - D3 v3 分组条形图,通过刷涂进行平移和缩放
问题描述
我正在尝试为分组条形图实现 d3 v3 缩放和平移。
我正在尝试如下:
仅供参考:我正在使用 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: Expected moveto path command ('M' or 'm'), "[object SVGGElem..." focus.append("path") .data(data) .attr("class", "切片") .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);
}
//});
我可以知道如何解决这个问题,任何帮助表示赞赏
解决方案
推荐阅读
- python - 如何在 Paho-MQTT python 中并行订阅和发布?
- javascript - 弹出窗口 - 一个接一个
- python - 读取、操作和保存文本文件
- css - 在列表中居中弹性项目
- scala - Apache Spark将多行连接成一行中的列表
- php - 如何使用唯一键递归合并数组?
- angular - Angular PWA - 在用户更新应用程序之前,新路线不起作用
- c# - 有没有办法通过 appsettings.json 设置 Serilog 格式化程序变量?
- r - Dplyr:使用唯一名称匿名化多达一百万行的值
- python - 如何将用户包部署到共享文件夹“repo”?