静态三角图的逻辑

时间:2019-05-31 06:15:45

标签: javascript d3.js

过去几天,我一直在尝试基于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){

1 个答案:

答案 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;
}