我尝试过尝试缩放范围,但无法防止不必要的行为。有什么建议吗?
var zoom = d3.zoom()
.scaleExtent([1, 500])
.translateExtent([[0, 0], [width, height]])
.extent([[0, 0], [2000, height]])
.on("zoom", zoomed);
请参见示例https://jsfiddle.net/sjp700/v1986fkt/或github上的项目
https://github.com/Steve-Pegg/Visual-Planning-Tool
谢谢
答案 0 :(得分:0)
这里最简单,最常见的解决方案是使用clipPath。
首先,添加<clipPath>
元素:
var clip = svg.append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", graphW)
.attr("height", graphH);
在不包含轴的<g>
元素内绘制矩形非常方便:因此,只需在该选择中引用<clipPath>
:
var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.attr("clip-path", "url(#clip)");
这是您所做的更改的代码:
var flatDatar = [{
group: "group1",
label: "label1",
start: "2018-09-01",
finish: "2018-10-01",
timeRange: "",
val: "Func 1",
labelVal: "A",
description: "Activity 1",
clas: "x1"
},
{
group: "group1",
label: "label2",
start: "2018-07-01",
finish: "2018-08-01",
timeRange: "",
val: "Func 2",
labelVal: "B",
description: "Activity 2",
clas: "x2"
},
{
group: "group1",
label: "label3",
start: "2018-01-01",
finish: "2018-02-01",
timeRange: "",
val: "Func 1",
labelVal: "A",
description: "Activity 3",
clas: "x3"
},
{
group: "group1",
label: "label4",
start: "2018-04-01",
finish: "2018-06-01",
timeRange: "",
val: "Func 2",
labelVal: "A",
description: "Activity 4",
clas: "x4"
},
{
group: "group1",
label: "label5",
start: "2018-11-01",
finish: "2018-12-01",
timeRange: "",
val: "Func 3",
labelVal: "A",
description: "Activity 5",
clas: "x5"
},
{
group: "group2",
label: "label6",
start: "2018-01-01",
finish: "2018-02-01",
timeRange: "",
val: "Func 4",
labelVal: "C",
description: "Activity 6",
clas: "x6"
},
{
group: "group2",
label: "label7",
start: "2018-03-27",
finish: "2018-04-01",
timeRange: "",
val: "Func 5",
labelVal: "A",
description: "Activity 7",
clas: "x7"
},
{
group: "group2",
label: "label8",
start: "2018-05-01",
finish: "2018-07-01",
timeRange: "",
val: "Func 4",
labelVal: "E",
description: "Activity 8",
clas: "x8"
},
{
group: "group2",
label: "label9",
start: "2018-09-01",
finish: "2018-10-01",
timeRange: "",
val: "Func 2",
labelVal: "A",
description: "Activity 9",
clas: "x9"
},
{
group: "group2",
label: "label10",
start: "2018-11-01",
finish: "2018-12-01",
timeRange: "",
val: "Func 3",
labelVal: "B",
description: "Activity 10",
clas: "x10"
},
{
group: "group2",
label: "label11",
start: "2018-06-01",
finish: "2018-07-01",
timeRange: "",
val: "Func 5",
labelVal: "C",
description: "Activity 11",
clas: "x11"
},
{
group: "group3",
label: "label12",
start: "2018-08-01",
finish: "2018-09-01",
timeRange: "",
val: "Func 4",
labelVal: "D",
description: "Activity 12",
clas: "x12"
},
{
group: "group3",
label: "label13",
start: "2018-10-01",
finish: "2018-11-01",
timeRange: "",
val: "Func 2",
labelVal: "E",
description: "Activity 13",
clas: "x13"
},
{
group: "group3",
label: "label14",
start: "2018-07-01",
finish: "2018-08-01",
timeRange: "",
val: "Func 5",
labelVal: "F",
description: "Activity 14",
clas: "x14"
},
{
group: "group3",
label: "label15",
start: "2018-02-01",
finish: "2018-04-01",
timeRange: "",
val: "Func 4",
labelVal: "D",
description: "Activity 12",
clas: "x15"
},
{
group: "group3",
label: "label16",
start: "2018-10-01",
finish: "2019-01-01",
timeRange: "",
val: "Func 2",
labelVal: "E",
description: "Activity 13",
clas: "x16"
},
{
group: "group3",
label: "label17",
start: "2019-03-01",
finish: "2019-05-01",
timeRange: "",
val: "Func 5",
labelVal: "F",
description: "Activity 14",
clas: "x17"
}
];
var flatData = [{
group: "group1",
label: "label1",
start: "2018-09-01",
finish: "2018-10-01",
timeRange: "",
val: "Func 1",
labelVal: "A",
lines: ["label1", "label2", "label3", "label4", "label5"],
description: "Activity 1",
cost: 1000
},
{
group: "group2",
label: "label6",
start: "2018-01-01",
finish: "2018-02-01",
timeRange: "",
val: "Func 4",
labelVal: "C",
lines: ["label6", "label7", "label8", "label9", "label10", "label11"],
description: "Activity 6",
cost: 1000
},
{
group: "group3",
label: "label12",
start: "2018-07-01",
finish: "2018-08-01",
timeRange: "",
val: "Func 5",
labelVal: "F",
lines: ["label12", "label13", "label14", "label15", "label16", "label17"],
description: "Activity 14"
}
];
var timeParse = d3.timeParse("%Y-%m-%d");
for (var i = 0, ilen = flatDatar.length; i < ilen; i++) {
flatDatar[i].start = timeParse(flatDatar[i].start)
flatDatar[i].finish = timeParse(flatDatar[i].finish)
};
var width = 1000,
height = 600,
graphW = 1000,
xTickFormat = {},
graphH = 600,
nLines = flatDatar.length,
minLabelFont = 10,
maxLineHeight = 13,
maxHeight = 640
var margin = {
top: 26,
right: 100,
bottom: 30,
left: 90
}
graphW = width - margin.left - margin.right;
graphH = d3.min([nLines * maxLineHeight, maxHeight - margin.top - margin.bottom]);
height = graphH + margin.top + margin.bottom;
var labels = getlabels()
function getlabels() {
var labels = [];
var _loop4 = function _loop4(i, len) {
labels = labels.concat(flatData[i].lines.map(function(d) {
return flatData[i].group + '+&+' + d;
}));
};
for (var i = 0, len = flatData.length; i < len; i++) {
_loop4(i, len);
}
labels = labels.filter((v, i, a) => a.indexOf(v) === i);
return labels
}
var border = 1;
var bordercolor = 'black';
var svg = d3.select("body")
.append("svg")
.attr("border", border)
.attr("width", width)
.attr("height", height);
var clip = svg.append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", graphW)
.attr("height", graphH);
var borderPath = svg.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("height", height)
.attr("width", width)
.style("stroke", bordercolor)
.style("fill", "none")
.style("stroke-width", border);
svg.transition().duration(100).attr('width', width).attr('height', height);
var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.attr("clip-path", "url(#clip)");
var yScale = d3.scalePoint()
.domain(labels)
.range([graphH / labels.length * 0.5, graphH * (1 - 0.5 / labels.length)]);
var grpScale = d3.scaleOrdinal()
var xScale = d3.scaleTime()
.domain([d3.min(flatDatar, function(d) {
return d.start;
}), d3.max(flatDatar, function(d) {
return d.finish;
})])
.range([0, graphW]);
var xGrid = d3.axisTop()
.scale(xScale)
.tickSize(graphH);
var yAxis = d3.axisRight()
.scale(yScale)
.tickSize(0);
var grpAxis = d3.axisLeft()
.scale(grpScale)
.tickSize(0)
var axises = svg.append('g').attr('class', 'axises');
axises.append('g').attr('class', 'x-grid');
axises.append('g').attr('class', 'y-axis');
axises.append('g').attr('class', 'grp-axis');
svg.select('.axises').attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
svg.select('g.x-grid')
.attr('transform', 'translate(0,' + graphH + ')')
.transition().duration(100)
.call(xGrid);
var fontVerticalMargin = 0.6;
var fontSize = Math.min(12, graphH / flatDatar.length * fontVerticalMargin * Math.sqrt(2));
yAxis.tickValues(labels);
svg.select('g.y-axis')
.transition().duration(100)
.attr('transform', 'translate(' + graphW + ', 0)')
.style('font-size', fontSize + 'px')
.call(yAxis);
var minHeight = d3.min(grpScale.range(), function(d, i) {
return i > 0 ? d - grpScale.range()[i - 1] : d * 2;
});
grpAxis.tickFormat(function(d) {
return d
})
.ticks(0);
grpScale.domain(flatData.map(function(d) {
return d.group;
}));
var cntLines = 0;
grpScale.range(flatData.map(function(d) {
var pos = (cntLines + d.lines.length / 2) / nLines * graphH;
cntLines += d.lines.length;
return pos;
}));
svg.select('g.grp-axis')
.transition()
.duration(100)
.style('font-size', fontSize + 'px')
.call(grpAxis);
var lineHeight = graphH / nLines * 0.8;
function zoomed() {}
console.log(flatDatar)
var zoom = d3.zoom()
// .scaleExtent([1, 500])
// .translateExtent([[0, 0], [width, height]])
// .extent([[0, 0], [2000, height]])
.on("zoom", zoomed);
var group = g.selectAll(".rectangle")
.data(flatDatar);
var gEnter = group.enter()
.append("g")
.attr("class", "rectangle")
.attr("fill", "yellow")
.attr("transform", function(d) {
console.log("label " + d.label)
return "translate(" + xScale(d.start) + "," + (yScale(d.group + '+&+' + d.label) - lineHeight / 2) + ")";
})
.append("svg")
.attr("height", lineHeight)
.attr("class", "interval")
.attr("width", function(d) {
return xScale(d.finish) - xScale(d.start)
});
gEnter.append("rect")
.attr("class", "rectband " + function(d) {
return d.clas;
})
.attr("width", function(d) {
return xScale(d.finish) - xScale(d.start)
})
.attr("height", lineHeight)
.style("opacity", .5) // set the element opacity
.style("stroke", "black");
gEnter.append("text")
.attr("class", "interval")
.attr("x", 6)
.attr("y", 9)
.style("pointer-events", "none")
.style("fill", "black")
.attr("font-size", 11)
.attr("font-family", "Cambria")
.text(function(d) {
return (d.description);
});
function sjp() {
console.log("clicked")
flatDatar.push({
group: "group4",
start: "2019-04-01",
finish: "2019-08-01",
description: "Temp"
})
console.log(flatDatar)
group = group.merge(gEnter);
zoomed()
}
//---------------
svg.call(zoom).on("dblclick.zoom", sjp);
var xt;
function zoomed() {
xt = xScale;
var t = d3.event.transform
if (typeof t !== 'undefined') {
xt = t.rescaleX(xScale);
}
svg.select('.x-grid').call(xGrid.scale(xt));
svg.selectAll(".rectangle, .circle").remove();
svg.selectAll(".interval").remove();
svg.selectAll(".clas").remove();
var group = g.selectAll(".rectangle")
.data(flatDatar);
var gEnter = group.enter()
.append("g")
.attr("class", "rectangle")
.attr("fill", "yellow")
.attr("transform", function(d) {
console.log(d.label)
return "translate(" + xt(d.start) + "," + (yScale(d.group + '+&+' + d.label) - lineHeight / 2) + ")";
})
.append("svg")
.attr("height", lineHeight)
.attr("class", "interval")
.attr("width", function(d) {
return xt(d.finish) - xt(d.start)
});
gEnter.append("rect")
.attr("class", "rectband " + function(d) {
return d.clas;
})
// .merge(gEnter)
.attr("width", function(d) {
return xt(d.finish) - xt(d.start)
})
.attr("height", lineHeight)
.style("opacity", .5) // set the element opacity
.style("stroke", "black");
gEnter.append("text")
.attr("class", "interval")
.attr("x", 6)
.attr("y", 9)
.style("pointer-events", "none")
.style("fill", "black")
.attr("font-size", 11)
.attr("font-family", "Cambria")
.text(function(d) {
return (d.description);
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>