javascript - D3js,如何根据轴值(不是像素)设置点
问题描述
我有这种情节。在那我按像素放置点。
let svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height"),
x = d3.scaleLinear().domain([20 , 20000]).range([0, width]),
y = d3.scaleLinear().domain([-18 , 18]).range([height, 0]),
axisBottom = d3.axisBottom(x),
axisLeft = d3.axisLeft(x),
points =[[100, 100], [300, 200]],
circleRadius = 10;
// How can I set points if I have data like
// points =[[5, 6000], [-10, 18500]], not pixels but axis units
svg.append('g')
.attr('class', 'axis axis--x')
.attr('transform', 'translate(0,' + height/2 + ')')
.call(axisBottom);
svg.append('g')
.attr('class', 'axis axis--y')
.call(d3.axisLeft(y));
let groupForCircles = svg.append('g').attr('id', 'groupForCircles')
points.forEach(e => {
groupForCircles.append("g")
.append("circle")
.attr("cx", e[0])
.attr("cy", height/2)
.attr("r", circleRadius)
.style("fill", "purple")
})
svg {
border: 1px solid #ccc;
display: block;
margin: auto;
overflow: visible;
margin-top: 25px;
}
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg width="500" height="300"></svg>
问题是如果我只有基于轴的值,我如何在绘图上设置点?例如,我有[5, 6000]
第一个数字是 Y 轴值,第二个数字是 X 轴值。如何根据该值而不是像素将点放在图形上?谢谢!
解决方案
x 和 y 刻度用于将您的值转换为适当的图表坐标。要添加您的坐标,您只需要使用您创建的比例来生成正确的 x 和 y 坐标:
groupForCircles
.append('circle')
.attr('cx', d => x(d[0]) ) // `x` is your x scale, `y` is the y scale
.attr('cy', d => y(d[1]) )
看起来您已经在建议的数据点中切换了 x 和 y 值,因此我稍微更改了代码以解决此问题。我还使用标准 d3 数据绑定来促进点的添加和操作,而不是forEach
循环:
const moreData = [ [5, 6000], [-10, 18500], [2, 2000], [-18, 100] ]
groupForCircles.selectAll('.dataPoint')
.data(moreData) // bind the data
.enter() // this is the new data being added to the chart
.append('circle') // add a circle element for each data element
.classed('dataPoint', true)
.attr('cx', d => x(d[1]) ) // use the second of the pair as the x coordinate
.attr('cy', d => y(d[0]) ) // and the first as the y
.attr('r', 4)
.style('fill', 'deepskyblue');
完整演示:
let svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height"),
x = d3.scaleLinear().domain([20 , 20000]).range([0, width]),
y = d3.scaleLinear().domain([-18 , 18]).range([height, 0]),
axisBottom = d3.axisBottom(x),
axisLeft = d3.axisLeft(x),
points =[[100, 100], [300, 200]],
moreData = [ [5, 6000], [-10, 18500], [2, 2000], [-18, 100] ],
circleRadius = 10;
// How can I set points if I have data like
// points =[[5, 6000], [-10, 18500]], not pixels but axis units
svg.append('g')
.attr('class', 'axis axis--x')
.attr('transform', 'translate(0,' + height/2 + ')')
.call(axisBottom);
svg.append('g')
.attr('class', 'axis axis--y')
.call(d3.axisLeft(y));
let groupForCircles = svg.append('g').attr('id', 'groupForCircles')
points.forEach(e => {
groupForCircles.append("g")
.append("circle")
.attr("cx", e[0])
.attr("cy", height/2)
.attr("r", circleRadius)
.style("fill", "purple")
})
groupForCircles.selectAll('.dataPoint')
.data(moreData)
.enter()
.append('circle')
.classed('dataPoint', true)
.attr('cx', d => x(d[1]) )
.attr('cy', d => y(d[0]) )
.attr('r', 4)
.style('fill', 'deepskyblue');
svg {
border: 1px solid #ccc;
display: block;
margin: auto;
overflow: visible;
margin-top: 25px;
}
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg width="500" height="300"></svg>
推荐阅读
- c# - Elasticsearch 6.3 - 如何对分析的字段进行排序?
- android - 一旦用户选择不同的时间间隔,如何更新倒数计时器
- javascript - 如何从 TypeScript 中的嵌套 JSON 中获取数据?
- c# - 在 C#.net GridView 中生成重复值
- exception - vertx IllegalArgumentException: No message codec for type - 如何为自定义类型创建消费者
- awk - 如何使用 awk 在行组中添加缺失的行
- c# - 拉普拉斯使用c#我哪里出错了?
- openlayers - Openlayers:确定是否设置了 precompose 处理程序
- c# - 是否可以在 WCF wsdl 中包含一个 DataContract 类,而该类不属于任何 OperationContract?
- airflow - 在 Airflow 中使用 ds_add 和宏