我必须在SVG中做类似的事情:
如您所见,它基本上是一个表。 我认为可以使用d3.js,并且可以缩放并绘制每个元素的位置,但是我需要一些帮助。 我不知道如何开始。
假设我有一个线性标尺,用于水平放置项目,另一个用于垂直放置元素:
const myDomainH = ?
const myRangeH = ?
const scaleHorizontally = d3.scaleLinear().domain(myDomainH).range(myRangeH)
const myDomainV = ?
const myRangeV = ?
const scaleVertically = d3.scaleLinear().domain(myDomainV).range(myRangeV)
我的数据集是:
[
[
{
"category": "Category 1",
"color": 1,
"value": 73.55989924542436,
"objects": [
{
"object": "Object 11",
"value": 70.77137994021379
},
{
"object": "Object 12",
"value": 81.4082571028975
},
{
"object": "Object 13",
"value": 70.77137994021379
}
]
},
{
"category": "Category 1",
"color": 2,
"value": 22.2597985833491,
"objects": [
{
"object": "Object 11",
"value": 15.853930976590469
},
{
"object": "Object 12",
"value": 56.56972660299733
},
{
"object": "Object 13",
"value": 70.77137994021379
}
]
},
{
"category": "Category 1",
"color": 3,
"value": 22.709698156338032,
"objects": [
{
"object": "Object 11",
"value": 74.99319041632756
},
{
"object": "Object 12",
"value": 68.41322493812694
},
{
"object": "Object 13",
"value": 70.77137994021379
}
]
},
{
"category": "Category 1",
"color": 4,
"value": 23.66413869920101,
"objects": [
{
"object": "Object 11",
"value": 17.61500366859401
},
{
"object": "Object 12",
"value": 11.147400814940344
},
{
"object": "Object 13",
"value": 70.77137994021379
}
]
},
{
"category": "Category 1",
"color": 5,
"value": 45.82962655452327,
"objects": [
{
"object": "Object 11",
"value": 9.967028966701474
},
{
"object": "Object 12",
"value": 13.944328943444905
},
{
"object": "Object 13",
"value": 70.77137994021379
}
]
},
{
"category": "Category 1",
"color": 6,
"value": 24.865266198819302,
"objects": [
{
"object": "Object 11",
"value": 37.45282918258137
},
{
"object": "Object 12",
"value": 62.40512982903728
},
{
"object": "Object 13",
"value": 70.77137994021379
}
]
}
],
[
{
"category": "Category 2",
"color": 1,
"value": 35.30633472871503,
"objects": [
{
"object": "Object 21",
"value": 32.017889605115336
},
{
"object": "Object 22",
"value": 22.600901269005913
},
]
},
{
"category": "Category 2",
"color": 2,
"value": 15.763575845434152,
"objects": [
{
"object": "Object 21",
"value": 32.017889605115336
},
{
"object": "Object 22",
"value": 22.600901269005913
},
]
},
{
"category": "Category 2",
"color": 3,
"value": 65.66932804750859,
"objects": [
{
"object": "Object 21",
"value": 32.017889605115336
},
{
"object": "Object 22",
"value": 22.600901269005913
},
]
},
{
"category": "Category 2",
"color": 4,
"value": 35.79326347817449,
"objects": [
{
"object": "Object 21",
"value": 32.017889605115336
},
{
"object": "Object 22",
"value": 22.600901269005913
},
]
},
{
"category": "Category 2",
"color": 5,
"value": 91.79806542930078,
"objects": [
{
"object": "Object 21",
"value": 32.017889605115336
},
{
"object": "Object 22",
"value": 22.600901269005913
},
]
},
{
"category": "Category 2",
"color": 6,
"value": 34.574064983647766,
"objects": [
{
"object": "Object 21",
"value": 32.017889605115336
},
{
"object": "Object 22",
"value": 22.600901269005913
},
]
}
],
[
{
"category": "Category 3",
"color": 1,
"value": 57.64950041773291,
"objects": [
{
"object": "Object 31",
"value": 42.86818415221803
},
{
"object": "Object 32",
"value": 42.86818415221803
},
{
"object": "Object 33",
"value": 42.86818415221803
},
{
"object": "Object 34",
"value": 42.86818415221803
}
]
},
{
"category": "Category 3",
"color": 2,
"value": 17.76033855108046,
"objects": [
{
"object": "Object 31",
"value": 89.52070065904911
},
{
"object": "Object 32",
"value": 42.86818415221803
},
{
"object": "Object 33",
"value": 42.86818415221803
},
{
"object": "Object 34",
"value": 42.86818415221803
}
]
},
{
"category": "Category 3",
"color": 3,
"value": 11.845610356899815,
"objects": [
{
"object": "Object 31",
"value": 54.76278304243267
},
{
"object": "Object 32",
"value": 42.86818415221803
},
{
"object": "Object 33",
"value": 42.86818415221803
},
{
"object": "Object 34",
"value": 42.86818415221803
}
]
},
{
"category": "Category 3",
"color": 4,
"value": 80.55423937728892,
"objects": [
{
"object": "Object 31",
"value": 63.74492886059537
},
{
"object": "Object 32",
"value": 42.86818415221803
},
{
"object": "Object 33",
"value": 42.86818415221803
},
{
"object": "Object 34",
"value": 42.86818415221803
}
]
},
{
"category": "Category 3",
"color": 5,
"value": 3.6629102311577455,
"objects": [
{
"object": "Object 31",
"value": 63.260999161538535
},
{
"object": "Object 32",
"value": 42.86818415221803
},
{
"object": "Object 33",
"value": 42.86818415221803
},
{
"object": "Object 34",
"value": 42.86818415221803
}
]
},
{
"category": "Category 3",
"color": 6,
"value": 66.08487065166841,
"objects": [
{
"object": "Object 31",
"value": 70.16436770369718
},
{
"object": "Object 32",
"value": 42.86818415221803
},
{
"object": "Object 33",
"value": 42.86818415221803
},
{
"object": "Object 34",
"value": 42.86818415221803
}
]
}
]
]
(忽略暂时不使用的字段value
)。
然后呢?
使用这些数据,我必须创建并放置单元格(svg矩形),并使用d3.js进行编写。 想法是要创建一个响应页面,然后单元格的宽度将根据页面的宽度进行调整。
然后我认为水平刻度的范围可以是window.innerwidht
的宽度,但是我不知道它是否正确。
svg矩形的高度必须固定为15px
。
无论如何,我都不知道如何进行。有人可以帮我吗?
谢谢。
答案 0 :(得分:0)
您正在绘制一个嵌套结构,这里的窍门是,对于外层,您使用.data(dataSet)
;对于内层,您必须通过使用一个函数从已经映射的外层元素中提取其数据来进行处理。 ,例如当外层是列,内层是单元格时:.data(function(d) { return d.objects; }
。
就定位本身而言,我建议大量使用具有g
属性的transform
元素。这样,当您位于内层内部时,不必担心其外层元素的位置(因此,例如,当绘制单元格时,您不需要知道x
的偏移量列)。对于计算位置,在这种情况下,pointScale可能更有意义,尽管它并不重要。
然后我以为水平刻度的范围可以是window.innerwidht的宽度),但我不知道它是否正确。
是的,这是正确的方法。您最有可能希望通过将其放入单个方法中来完成渲染(这意味着它是调用渲染的唯一公开点;当然,它将并且应该将其的一部分委托给私有方法),然后您将调用调整大小事件侦听器中的该方法。
这里有一些代码可以帮助您入门;它为单个类别创建一个表。要创建多个类别,您必须应用相同的逻辑-在类别内嵌套表格逻辑,方法是通过函数从传递的类别数据中提取其数据。
var dataSet = [{
"category": "Category 1",
"color": 1,
"value": 73.55989924542436,
"objects": [{
"object": "Object 11",
"value": 70.77137994021379
},
{
"object": "Object 12",
"value": 81.4082571028975
},
{
"object": "Object 13",
"value": 70.77137994021379
}
]
},
{
"category": "Category 1",
"color": 2,
"value": 22.2597985833491,
"objects": [{
"object": "Object 11",
"value": 15.853930976590469
},
{
"object": "Object 12",
"value": 56.56972660299733
},
{
"object": "Object 13",
"value": 70.77137994021379
}
]
}
];
var svg = d3.select('svg');
var winWidth = 300;
var colScale = d3.scalePoint()
.domain(dataSet.map(function(d) {
return d.color;
}))
.range([0, winWidth]);
var objects = dataSet[0].objects.map(function(o) {
return o.object;
});
var cellScale = d3.scalePoint()
.domain(objects)
.range([0, objects.length * 15]);
var columns = svg.selectAll('g.column')
.data(dataSet);
columns = columns.enter()
.append('g')
.classed('column', true)
.merge(columns)
.attr('transform', function(d, i) {
return 'translate(' + colScale(d.color) + ',0)';
});
var cells = columns
.selectAll('g.cell')
.data(function(d) {
return d.objects;
});
cells = cells.enter()
.append('g')
.classed('cell', true)
.merge(cells)
.attr('transform', function(d, i) {
return 'translate(0,' + cellScale(d.object) + ')';
});
cells.append('rect')
//Styles should be in CSS
.style('fill', 'none')
.style('stroke', 'black')
.attr('width', colScale.step())
.attr('height', cellScale.step());
cells.append('text')
.style('dominant-baseline', 'text-before-edge')
.text(function(d) {
return d.value;
});