过去几天,我一直在尝试基于this block制作静态d3 v5版本。我已经绘制了坐标平面,但是在使绘图逻辑适应静态变量时遇到了麻烦。这是我的进度:
var margins = {top:50, bottom:50, left:50, right:50};
var height = 900;
var width = 900;
var totalWidth = width+margins.left+margins.right;
var totalHeight = height+margins.top+margins.bottom;
var side = 700;
var axis_labels = ['Journalist','Developer','Designer'];
var axis_ticks = [0,20,40,60,80,100];
var tickLabelMargin = 10;
var axisLabelMargin = 40;
var minor_axis_ticks = d3.range(0, 101, 5);
console.log(minor_axis_ticks)
var w = side;
var h = Math.sqrt( side*side - (side/2)*(side/2));
var corners = [
[margins.left, h + margins.top], // a
[ w + margins.left, h + margins.top], //b
[(w/2) + margins.left, margins.top] ]; //c
var svg = d3.select('body')
.append('svg')
.attr('width', totalWidth)
.attr('height', totalHeight);
var graphGroup = svg.append('g')
.attr('transform', "translate("+margins.left+","+margins.top+")");
var axes = graphGroup.append('g').attr('class','axes');
var plot = {
dataset:[]
};
var data = [
{journalist:75,developer:25,designer:0,label:'point 1'},
{journalist:70,developer:10,designer:20,label:'point 2'},
{journalist:75,developer:20,designer:5,label:'point 3'},
{journalist:5,developer:60,designer:35,label:'point 4'},
{journalist:10,developer:80,designer:10,label:'point 5'},
{journalist:10,developer:90,designer:0,label:'point 6'},
{journalist:20,developer:70,designer:10,label:'point 7'},
{journalist:10,developer:20,designer:70,label:'point 8'},
{journalist:15,developer:5,designer:80,label:'point 9'},
{journalist:10,developer:10,designer:80,label:'point 10'},
{journalist:20,developer:10,designer:70,label:'point 11'},
];
function lineAttributes(p1, p2){
return { x1:p1[0], y1:p1[1],
x2:p2[0], y2:p2[1] };
}
axes.selectAll('.axis-title')
.data(axis_labels)
.enter()
.append('g')
.attr('class', 'axis-title')
.attr('transform',function(d,i){
return 'translate('+corners[i][0]+','+corners[i][1]+')';
})
.append('text')
.text(function(d){ return d; })
.attr('text-anchor', function(d,i){
if(i===0) return 'end';
if(i===2) return 'middle';
return 'start';
})
.attr('transform', function(d,i){
var theta = 0;
if(i===0) theta = 120;
if(i===1) theta = 60;
if(i===2) theta = -90;
var x = axisLabelMargin * Math.cos(theta * 0.0174532925),
y = axisLabelMargin * Math.sin(theta * 0.0174532925);
return 'translate('+x+','+y+')'
});
var n = axis_ticks.length;
if(minor_axis_ticks){
minor_axis_ticks.forEach(function(v) {
var coord1 = coord( [v, 0, 100-v] );
var coord2 = coord( [v, 100-v, 0] );
var coord3 = coord( [0, 100-v, v] );
var coord4 = coord( [100-v, 0, v] );
axes.append("line")
.attr('x1', lineAttributes(coord1, coord2).x1 )
.attr('x2', lineAttributes(coord1, coord2).x2 )
.attr('y1', lineAttributes(coord1, coord2).y1 )
.attr('y2', lineAttributes(coord1, coord2).y2 )
.classed('a-axis minor-tick', true);
axes.append("line")
.attr('x1', lineAttributes(coord2, coord3).x1 )
.attr('x2', lineAttributes(coord2, coord3).x2 )
.attr('y1', lineAttributes(coord2, coord3).y1 )
.attr('y2', lineAttributes(coord2, coord3).y2 )
.classed('b-axis minor-tick', true);
axes.append("line")
.attr('x1', lineAttributes(coord3, coord4).x1 )
.attr('x2', lineAttributes(coord3, coord4).x2 )
.attr('y1', lineAttributes(coord3, coord4).y1 )
.attr('y2', lineAttributes(coord3, coord4).y2 )
.classed('c-axis minor-tick', true);
});
}
axis_ticks.forEach(function(v) {
var coord1 = coord( [v, 0, 100-v] );
var coord2 = coord( [v, 100-v, 0] );
var coord3 = coord( [0, 100-v, v] );
var coord4 = coord( [100-v, 0, v] );
axes.append("line")
.attr('x1', lineAttributes(coord1, coord2).x1 )
.attr('x2', lineAttributes(coord1, coord2).x2 )
.attr('y1', lineAttributes(coord1, coord2).y1 )
.attr('y2', lineAttributes(coord1, coord2).y2 )
.classed('a-axis tick', true);
axes.append("line")
.attr('x1', lineAttributes(coord2, coord3).x1 )
.attr('x2', lineAttributes(coord2, coord3).x2 )
.attr('y1', lineAttributes(coord2, coord3).y1 )
.attr('y2', lineAttributes(coord2, coord3).y2 )
.classed('b-axis tick', true);
axes.append("line")
.attr('x1', lineAttributes(coord3, coord4).x1 )
.attr('x2', lineAttributes(coord3, coord4).x2 )
.attr('y1', lineAttributes(coord3, coord4).y1 )
.attr('y2', lineAttributes(coord3, coord4).y2 )
.classed('c-axis tick', true);
//tick labels
axes.append('g')
.attr('transform',function(d){
return 'translate(' + coord1[0] + ',' + coord1[1] + ')'
})
.append("text")
.attr('transform','rotate(60)')
.attr('text-anchor','end')
.attr('x',-tickLabelMargin)
.text( function (d) { return v; } )
.classed('a-axis tick-text', true );
axes.append('g')
.attr('transform',function(d){
return 'translate(' + coord2[0] + ',' + coord2[1] + ')'
})
.append("text")
.attr('transform','rotate(-60)')
.attr('text-anchor','end')
.attr('x',-tickLabelMargin)
.text( function (d) { return (100- v); } )
.classed('b-axis tick-text', true);
axes.append('g')
.attr('transform',function(d){
return 'translate(' + coord3[0] + ',' + coord3[1] + ')'
})
.append("text")
.text( function (d) { return v; } )
.attr('x',tickLabelMargin)
.classed('c-axis tick-text', true);
})
function coord(arr){
var a = arr[0], b=arr[1], c=arr[2];
var sum, pos = [0,0];
sum = a + b + c;
if(sum !== 0) {
a /= sum;
b /= sum;
c /= sum;
pos[0] = corners[0][0] * a + corners[1][0] * b + corners[2][0] * c;
pos[1] = corners[0][1] * a + corners[1][1] * b + corners[2][1] * c;
}
return pos;
}
function scale(p, factor) {
return [p[0] * factor, p[1] * factor];
}
plot.data = function(data, accessor, bindBy){ //bind by is the dataset property used as an id for the join
plot.dataset = data;
console.log(data)
var circles = graphGroup.selectAll("circle")
.data( data.map( function(d){ return coord(accessor(d)); }), function(d,i){
if(bindBy){
return plot.dataset[i][bindBy];
}
return i;
} );
circles.enter().append("circle");
circles.transition().attr("cx", function (d) { return d[0]; })
.attr("cy", function (d) { return d[1]; })
.attr("r", 6);
return this;
}
plot.getPosition = coord;
plot.getTripple = function(x, y){
//TODO, get percentages for a give x, y
}
plot.data(data);
line.tick {
stroke-width: 0.5;
}
line.minor-tick {
stroke-width: 1;
stroke-opacity:0.1;
}
.a-axis{
stroke: #333;
}
.b-axis{
stroke: #333;
}
.c-axis{
stroke: #333;
}
.axis-title{
font-family: TW Cen MT;
font-size: 1.5rem;
}
text.tick-text {
font-family: TW Cen MT;
font-weight: lighter;
font-size: 1rem;
fill: #333;
stroke:none;
}
circle {
fill: #fff1e0;
stroke: #DB7365;
stroke-width: 2px;
}
<script src="https://d3js.org/d3.v5.min.js"></script>
目前,我正试图保持与原始代码接近,并使用plot.data(data);
绘制图形。同样,我的目标是制作图表的静态版本,而我不必调用任何函数来“绘制”图表。我只希望绘制图表,而不必大惊小怪地将不同的参数传递给不同的函数。我再也没有进步了,而在所有交叉的功能中迷路了。
在这一点上我被错误打了
未捕获的TypeError:访问器不是函数
引用第257行:
.data( data.map( function(d){ return coord(accessor(d)); }), function(d,i){
鉴于我希望制作静态图像,当我调用plot.data()
时,“访问器”的合适选择是什么?一旦弄清“访问器”的确切含义,我将寻求重新编码以消除将值传递给函数的必要性。
访问者的上下文与此功能有关(第252行):
plot.data = function(data, accessor, bindBy){
答案 0 :(得分:1)
好吧,您的真实问题是一个很大的问题:在bl.ocks中存在巨大的重构。
因此,在这里我仅解决您的 strict 问题。此参数列表中的accessor
...
plot.data = function(data, accessor, bindBy)
...是这个功能:
function(d){
return [d.journalist, d.developer, d.designer]
};
也就是说,它只是在数据数组的每个对象中创建一个包含三个变量的数组。
您可能知道,该数组将由coord()
使用:
function coord(arr) {
var a = arr[0],
b = arr[1],
c = arr[2];
var sum, pos = [0, 0];
sum = a + b + c;
if (sum !== 0) {
a /= sum;
b /= sum;
c /= sum;
pos[0] = corners[0][0] * a + corners[1][0] * b + corners[2][0] * c;
pos[1] = corners[0][1] * a + corners[1][1] * b + corners[2][1] * c;
}
return pos;
}