- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在我的 D3 图表中,放大和缩小功能未按 D3 图表中的预期工作。
它正在缩放整个图形,而不仅仅是绘制的线条和区域。预期的行为应该只是放大和缩小图表,而不是 x 轴和 y 轴。
当我使用以下代码使用 d3.zoom()
时 -
.call(d3.zoom().on("zoom", function () {
svg.attr("transform", d3.event.transform)
}));
但是上面的代码也会更新轴。所以我尝试添加剪辑路径并尝试使用它,但它不起作用。
// A function that updates the chart when the user zoom and thus new boundaries are available
const updateChart = () => {
// recover the new scale
var newX = d3.event.transform.rescaleX(xScale);
var newY = d3.event.transform.rescaleY(yScale);
// update axes with these new boundaries
xAxis.call(d3.axisBottom(newX));
yAxis.call(d3.axisLeft(newY));
// update circle position
scatter
.selectAll("circle")
.attr("cx", function(d) {
return newX(d.Sepal_Length);
})
.attr("cy", function(d) {
return newY(d.Petal_Length);
});
};
var zoom = d3
.zoom()
.scaleExtent([0.5, 20]) // This control how much you can unzoom (x0.5) and zoom (x20)
.extent([[0, 0], [containerWidth, containerHeight]])
.on("zoom", updateChart);
var svg = d3
.select(this.refs.chart)
.append("svg")
.attr("width", containerWidth)
.attr("height", containerHeight)
.call(zoom);
// Create the scatter variable: where both the circles and the brush take place
var scatter = svg.append("g").attr("clip-path", "url(#clip)");
这种散布应该移动圆圈以进行放大和缩小。我的工作代码沙箱here -
谢谢。
最佳答案
我尝试在react之外重新制作这个,你必须遵循d3 Zoom hierarki,
绘制定义,
绘制剪辑,
在剪辑中绘制要移动的项目,
缩放后请记住比例正在更改,请使用新比例来更新所有元素,如果不这样做,它将跟随缩放而下降。
var data = [
{
startTime: "1567765320049",
magnitude: 0,
startupMagnitude: 0,
startupRunningStatus: "IN_SYNC"
},
{
startTime: "1567851720049",
magnitude: 0,
startupMagnitude: 0,
startupRunningStatus: "IN_SYNC"
},
{
startTime: "1568024520049",
magnitude: 10,
startupMagnitude: 10,
startupRunningStatus: "IN_SYNC"
},
{
startTime: "1568283720049",
magnitude: 10,
startupMagnitude: 0,
startupRunningStatus: "OUT_OF_SYNC"
},
{
startTime: "1568629320049",
magnitude: 0,
startupMagnitude: 10,
startupRunningStatus: "OUT_OF_SYNC"
},
{
startTime: "1569061320049",
magnitude: 0,
startupMagnitude: 0,
startupRunningStatus: "IN_SYNC"
},
{
startTime: "1569579720049",
magnitude: -20,
startupMagnitude: 0,
startupRunningStatus: "OUT_OF_SYNC"
},
{
startTime: "1570184520049",
magnitude: -20,
startupMagnitude: -10,
startupRunningStatus: "OUT_OF_SYNC"
},
{
startTime: "1570875720049",
magnitude: 0,
startupMagnitude: 0,
startupRunningStatus: "IN_SYNC"
},
{
startTime: "1571653320049",
magnitude: 10,
startupMagnitude: -0,
startupRunningStatus: "OUT_OF_SYNC"
},
{
startTime: "1572517320049",
magnitude: 0,
startupMagnitude: -10,
startupRunningStatus: "OUT_OF_SYNC"
},
{
startTime: "1573467720049",
magnitude: 0,
startupMagnitude: -10,
startupRunningStatus: "OUT_OF_SYNC"
},
{
startTime: "1574504520049",
magnitude: 10,
startupMagnitude: -10,
startupRunningStatus: "OUT_OF_SYNC"
},
{
startTime: "1575627720049",
magnitude: 10,
startupMagnitude: -10,
startupRunningStatus: "OUT_OF_SYNC"
}
];
var drawLineGraph = function(containerHeight, containerWidth, data, yLabel, warnLine) {
// A function that updates the chart when the user zoom and thus new boundaries are available
var newX = ''
const updateChart = () => {
d3.select("#focusCircle").style('display', 'none')
// recover the new scale
newX = d3.event.transform.rescaleX(xScale);
var newY = yScale;
// update axes with these new boundaries
d3.select("#axisX").call(d3.axisBottom(newX));
//d3.select('#axisY').call(d3.axisLeft(newY));
// update circle position
scatter
.selectAll("circle")
.attr("cx", function(d) {
if (d) {
return newX(d.startTime);
}
})
.attr("cy", function(d) {
if (d) {
return newY(d.magnitude);
}
});
var line2 = d3
.line()
.x(function(d) {
return newX(d.startTime);
})
.y(function(d) {
return newY(d.startupMagnitude);
});
var area = d3
.area()
.x(function(d) {
return newX(d.startTime);
})
.y0(function(d) {
return yScale(d.startupMagnitude);
})
.y1(height);
var line = d3
.line()
.x(function(d) {
return newX(d.startTime);
})
.y(function(d) {
return newY(d.magnitude);
});
svg.on("mousemove", function() {
d3.select("#focusCircle").style('display', 'block')
var mouse = d3.mouse(this);
var mouseDate = newX.invert(mouse[0]);
var i = bisectDate(data, mouseDate); // returns the index to the current data item
var d0 = data[i - 1];
var d1 = data[i];
let d;
// work out which date value is closest to the mouse
if (typeof d1 !== "undefined") {
d = mouseDate - d0.startTime > d1.startTime - mouseDate ? d1 : d0;
} else {
d = d0;
}
div
.html(
`<span>${parseDate(d.startTime)}</span>
<span>Magnitude: ${d.magnitude} </span>`
)
.style("left", d3.event.pageX + "px")
.style("top", d3.event.pageY - 28 + "px");
var x = newX(d.startTime);
var y = yScale(d.magnitude);
focus
.select("#focusCircle")
.attr("cx", x)
.attr("cy", y);
focus
.select("#focusLineX")
.attr("x1", x)
.attr("y1", yScale(yDomain[0]))
.attr("x2", x)
.attr("y2", yScale(yDomain[1]));
focus
.select("#focusLineY")
.attr("x1", xScale(xDomain[0]))
.attr("y1", y)
.attr("x2", xScale(xDomain[1]))
.attr("y2", y);
});
scatter.select("#line2").attr("d", line2);
scatter.select(".line").attr("d", line);
scatter.select("#area").attr("d", area);
};
var zoom = d3
.zoom()
.scaleExtent([0.5, 20]) // This control how much you can unzoom (x0.5) and zoom (x20)
.extent([[0, 0], [containerWidth, containerHeight]])
.on("zoom", updateChart);
var svg = d3
.select('#chart')
.append("svg")
.attr("width", containerWidth)
.attr("height", containerHeight);
var clip = svg
.append("defs")
.append("SVG:clipPath")
.attr("id", "clip")
.append("SVG:rect")
.attr("width", containerWidth)
.attr("height", containerHeight)
.attr("x", 50)
.attr("y", 0);
// Create the scatter variable: where both the circles and the brush take place
var scatter = svg.append("g").attr("clip-path", "url(#clip)");
var margin = { top: 50, left: 50, right: 50, bottom: 80 };
var height = containerHeight - margin.top - margin.bottom;
var width = containerWidth - margin.left - margin.right;
var xDomain = d3.extent(data, function(d) {
return d.startTime;
});
var yDomain = d3.extent(data, function(d) {
return d.magnitude;
});
var xScale = d3
.scaleTime()
.range([0, width])
.domain(xDomain);
var yScale = d3
.scaleLinear()
.range([height, 0])
.domain(yDomain);
var xAxis = d3.axisBottom(xScale);
var yAxis = d3.axisLeft(yScale);
var line = d3
.line()
.x(function(d) {
return xScale(d.startTime);
})
.y(function(d) {
return yScale(d.magnitude);
});
var line2 = d3
.line()
.x(function(d) {
return xScale(d.startTime);
})
.y(function(d) {
return yScale(d.startupMagnitude);
});
var area = d3
.area()
.x(function(d) {
return xScale(d.startTime);
})
// .x0(function(d) {
// return xScale(d.startTime);
// })
// .x1(function(d) {
// return xScale(d.magnitude);
// })
.y0(function(d) {
return yScale(d.startupMagnitude);
})
.y1(height);
// .y0(height)
// .y1(function(d) { return yScale(d.magnitude); });
// var area = d3
// .area()
// .x0(function(d) {
// return xScale(d.startTime);
// })
// .x1(function(d) {
// return xScale(d.startTime);
// })
// .y0(function(d) {
// return yScale(d.magnitude);
// })
// .y1(function(d) {
// return yScale(0);
// });
// var area = d3
// .area()
// .x(function(d) {
// return xScale(d.startTime);
// })
// .y0(function(d) {
// return yScale(d.magnitude);
// })
// .y1(yScale(0));
// Define the div for the tooltip
var div = d3
.select("body")
.append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var g = scatter
.append("g")
.attr("transform", "translate(" + margin.left + ", " + margin.top + ")");
var g2 = svg
.append("g")
.attr("transform", "translate(" + margin.left + ", " + margin.top + ")");
g.append("path")
.datum(data)
.attr("class", "area")
.attr("id", "area")
.attr("d", area);
g.append("g")
.attr("class", "x axis")
.attr("id", "axisX")
.attr("transform", "translate(0, " + height + ")")
.call(xAxis);
g2.append("g")
.attr("class", "y axis")
.attr("id", "axisY")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.attr("text-anchor", "end")
.text(yLabel);
g.append("path")
.datum(data)
.attr("class", "line")
.attr("d", line);
g.append("path")
.datum(data)
.attr("class", "line2")
.attr("id", "line2")
.attr("d", line2);
g.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx", function(d) {
return xScale(d.startTime);
})
.attr("cy", function(d) {
return yScale(d.magnitude);
})
.attr("r", function(d) {
if (d.startupRunningStatus === "OUT_OF_SYNC") {
return 5;
}
})
.attr("class", "circle");
//legend code
svg
.append("circle")
.attr("cx", 40)
.attr("cy", 380)
.attr("r", 6)
.style("fill", "#1391d8");
svg
.append("circle")
.attr("cx", 40)
.attr("cy", 400)
.attr("r", 6)
.style("fill", "red");
svg
.append("text")
.attr("x", 60)
.attr("y", 380)
.text("Startup Config")
.style("font-size", "15px")
.attr("alignment-baseline", "middle");
svg
.append("text")
.attr("x", 60)
.attr("y", 400)
.text("Running Config")
.style("font-size", "15px")
.attr("alignment-baseline", "middle");
// focus tracking
var focus = g.append("g").style("display", "none");
focus
.append("line")
.attr("id", "focusLineX")
.attr("class", "focusLine");
focus
.append("line")
.attr("id", "focusLineY")
.attr("class", "focusLine");
focus
.append("circle")
.attr("id", "focusCircle")
.attr("r", 5)
.attr("class", "circle focusCircle");
//grid line
const make_x_axis = () => {
return d3.axisBottom(xScale);
};
scatter
.append("g")
.attr("class", "grid")
.attr("transform", "translate(50," + (height + 50) + ")")
.call(
make_x_axis()
.tickSize(-height, 0, 0)
.tickFormat("")
);
var bisectDate = d3.bisector(function(d) {
return d.startTime;
}).left;
var parseDate = d3.timeFormat("%Y-%m-%d %H:%M:%S");
g.selectAll("dot")
.data(data)
.enter()
.append("rect")
.attr("class", "overlay")
.attr("width", width)
.attr("height", height)
svg.on("mouseover", function(d) {
console.log('ok')
focus.style("display", null);
div
.transition()
.duration(200)
.style("opacity", 0.9);
})
.on("mouseout", function() {
focus.style("display", "none");
div
.transition()
.duration(300)
.style("opacity", 0);
})
.on("mousemove", function() {
var mouse = d3.mouse(this);
var mouseDate = xScale.invert(mouse[0]);
var i = bisectDate(data, mouseDate); // returns the index to the current data item
var d0 = data[i - 1];
var d1 = data[i];
let d;
// work out which date value is closest to the mouse
if (typeof d1 !== "undefined") {
d = mouseDate - d0.startTime > d1.startTime - mouseDate ? d1 : d0;
} else {
d = d0;
}
div
.html(
`<span>${parseDate(d.startTime)}</span>
<span>Magnitude: ${d.magnitude} </span>`
)
.style("left", d3.event.pageX + "px")
.style("top", d3.event.pageY - 28 + "px");
var x = xScale(d.startTime);
var y = yScale(d.magnitude);
focus
.select("#focusCircle")
.attr("cx", x)
.attr("cy", y);
focus
.select("#focusLineX")
.attr("x1", x)
.attr("y1", yScale(yDomain[0]))
.attr("x2", x)
.attr("y2", yScale(yDomain[1]));
focus
.select("#focusLineY")
.attr("x1", xScale(xDomain[0]))
.attr("y1", y)
.attr("x2", xScale(xDomain[1]))
.attr("y2", y);
});
svg
.append("rect")
.attr("width", containerWidth)
.attr("height", containerHeight)
.style("fill", "none")
.style("pointer-events", "all")
.call(zoom);
// warn line
// if (
// warnLine &&
// yDomain[0] < warnLine.lineValue &&
// yDomain[1] > warnLine.lineValue
// ) {
// g.append("line")
// .attr("x1", xScale(xDomain[0]))
// .attr("y1", yScale(warnLine.lineValue))
// .attr("x2", xScale(xDomain[1]))
// .attr("y2", yScale(warnLine.lineValue))
// .attr("class", "zeroline");
// g.append("text")
// .attr("x", xScale(xDomain[1]))
// .attr("y", yScale(warnLine.lineValue))
// .attr("dy", "1em")
// .attr("text-anchor", "end")
// .text(warnLine.label)
// .attr("class", "zerolinetext");
// }
}
drawLineGraph(410, 700, data, "Magnitude", {
lineValue: 0,
label: "Startup Config!"
});
.axis path,
.axis line {
fill: none;
stroke: #e0e0e0;
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
.line {
fill: none;
stroke: red;
stroke-width: 2px;
}
.line2 {
fill: none;
stroke: #2e59cf;
stroke-width: 0.3px;
}
.circle {
/* fill: white;
stroke: steelblue;
stroke-width: 2px; */
fill: steelblue;
stroke: steelblue;
/* stroke-width: 2px; */
}
.area {
fill: #2e59cf;
stroke: none;
opacity: 0.1;
}
.zeroline {
fill: none;
stroke: #1391d8;
stroke-width: 1px;
stroke-dasharray: 8 8;
}
.zerolinetext {
fill: #1391d8;
}
.overlay {
fill: none;
stroke: none;
pointer-events: all;
}
.focusLine {
fill: none;
stroke: steelblue;
stroke-width: 0.5px;
}
.focusCircle {
fill: red;
}
div.tooltip {
position: absolute;
text-align: center;
width: 150px;
height: 38px;
padding: 2px;
font: 12px sans-serif;
background: lightsteelblue;
border: 0px;
border-radius: 8px;
pointer-events: none;
}
.grid .tick {
stroke: lightgrey;
stroke-width: 0.7px;
stroke-dasharray: 8 8;
opacity: 0.3;
}
.grid path {
stroke-width: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div className="App">
<h1>Chart</h1>
</div>
<div id="chart"></div>
关于javascript - 放大和缩小功能在 D3 图表中未按预期工作并使用react,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57849225/
我在Windows 10中使用一些简单的Powershell代码遇到了这个奇怪的问题,我认为这可能是我做错了,但我不是Powershell的天才。 我有这个: $ix = [System.Net.Dn
var urlsearch = "http://192.168.10.113:8080/collective-intellegence/StoreClicks?userid=" + userId +
我有一个非常奇怪的问题,过去两天一直让我抓狂。 我有一个我试图控制的串行设备(LS 100 光度计)。使用设置了正确参数的终端(白蚁),我可以发送命令(“MES”),然后是定界符(CR LF),然后我
我目前正试图让无需注册的 COM 使用 Excel 作为客户端,使用 .NET dll 作为服务器。目前,我只是试图让概念验证工作,但遇到了麻烦。 显然,当我使用 Excel 时,我不能简单地使用与可
我开发了简单的 REST API - https://github.com/pavelpetrcz/MandaysFigu - 我的问题是在本地主机上,WildFly 16 服务器的应用程序运行正常。
我遇到了奇怪的情况 - 从 Django shell 创建一些 Mongoengine 对象是成功的,但是从 Django View 创建相同的对象看起来成功,但 MongoDB 中没有出现任何数据。
我是 flask 的新手,只编写了一个相当简单的网络应用程序——没有数据库,只是一个航类搜索 API 的前端。一切正常,但为了提高我的技能,我正在尝试使用应用程序工厂和蓝图重构我的代码。让它与 pus
我的谷歌分析 JavaScript 事件在开发者控制台中运行得很好。 但是当从外部 js 文件包含在页面上时,它们根本不起作用。由于某种原因。 例如; 下面的内容将在包含在控制台中时运行。但当包含在单
这是一本名为“Node.js 8 the Right Way”的书中的任务。你可以在下面看到它: 这是我的解决方案: 'use strict'; const zmq = require('zeromq
我正在阅读文本行,并创建其独特单词的列表(在将它们小写之后)。我可以使它与 flatMap 一起工作,但不能使它与 map 的“子”流一起工作。 flatMap 看起来更简洁和“更好”,但为什么 di
我正在编写一些 PowerShell 脚本来进行一些构建自动化。我发现 here echo $? 根据前面的语句返回真或假。我刚刚发现 echo 是 Write-Output 的别名。 写主机 $?
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 4年前关闭。 Improve thi
我将一个工作 View Controller 类从另一个项目复制到一个新项目中。我无法在新项目中加载 View 。在旧项目中我使用了presentModalViewController。在新版本中,我
我对 javascript 很陌生,所以很难看出我哪里出错了。由于某种原因,我的功能无法正常工作。任何帮助,将不胜感激。我尝试在外部 js 文件、头部/主体中使用它们,但似乎没有任何效果。错误要么出在
我正在尝试学习Flutter中的复选框。 问题是,当我想在Scaffold(body :)中使用复选框时,它正在工作。但我想在不同的地方使用它,例如ListView中的项目。 return Cente
我们当前使用的是 sleuth 2.2.3.RELEASE,我们看不到在 http header 中传递的 userId 字段没有传播。下面是我们的代码。 BaggageField REQUEST_I
我有一个组合框,其中包含一个项目,比如“a”。我想调用该组合框的 Action 监听器,仅在手动选择项目“a”完成时才调用。我也尝试过 ItemStateChanged,但它的工作原理与 Action
你能看一下照片吗?现在,一步前我执行了 this.interrupt()。您可以看到 this.isInterrupted() 为 false。我仔细观察——“这个”没有改变。它具有相同的 ID (1
我们当前使用的是 sleuth 2.2.3.RELEASE,我们看不到在 http header 中传递的 userId 字段没有传播。下面是我们的代码。 BaggageField REQUEST_I
我正在尝试在我的网站上设置一个联系表单,当有人点击发送时,就会运行一个作业,并在该作业中向所有管理员用户发送通知。不过,我在失败的工作表中不断收到此错误: Illuminate\Database\El
我是一名优秀的程序员,十分优秀!