d3 drag не работает в приложении Angular 6? - PullRequest
0 голосов
/ 03 сентября 2018

Я создал датчик с ванильным JavaScript и d3:

var planeStringImage = "M 439.48098,95.969555 L 393.34268,142.46481 L 305.91233,133.41187 L 324.72376,114.58551 L 308.61525,98.464215 L 276.15845,130.94677 L 185.25346,123.08136 L 201.15145,107.27643 L 186.46085,92.574165 L 158.32,120.73735 L 45.386032,112.12042 L 15.000017,131.66667 L 221.20641,192.48691 L 298.26133,237.01135 L 191.91028,345.62828 L 152.82697,408.6082 L 41.549634,393.05411 L 21.037984,413.58203 L 109.25334,470.93369 L 166.38515,558.95725 L 186.8968,538.42933 L 171.35503,427.06371 L 234.28504,387.94939 L 342.81586,281.51396 L 387.305,358.63003 L 448.07703,565.00001 L 467.60778,534.58989 L 458.99769,421.56633 L 487.16033,393.38134 L 473.14247,379.35235 L 456.6139,395.97492 L 448.79636,303.63439 L 481.25315,271.15184 L 465.14464,255.03055 L 446.33321,273.8569 L 436.04766,185.1164 L 482.35108,138.7864 C 501.1942,119.92833 560.62425,61.834815 564.99998,14.999985 C 515.28999,23.707295 476.1521,61.495405 439.48098,95.969555 z ";
var planeStyleElement = "opacity:1;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible";

var tickDataLabel = ['S', '210', '240', 'W', '300', '330', 'N', '030', '060', 'E', '120', '150', 'S'];

var drag = d3.drag().on("drag", function() {
    var width = 115;
    var height = 115;
    var rect = d3.select(this);
    var theta = Math.atan2(d3.event.y - height/2, d3.event.x - width/2) * 180 / Math.PI;

    console.log('what is the angle?');
    console.log(theta);

    theta = Math.round(theta / 10) * 10;

    if (theta === 0 ||
        theta === 30 ||
        theta === 60 ||
        theta === 90 ||
        theta === 120 ||
        theta === 150 ||
        theta === 180 ||
        theta === -30 ||
        theta === -60 ||
        theta === -90 ||
        theta === -120 ||
        theta === -150 ||
        theta === 330) {

        document.getElementById('output').innerHTML = 'You have an airport facing at ' + theta + ' degrees';

        rect
            .attr("x", d3.event.x)
            .attr("y", d3.event.y)
            .attr('transform', `rotate(${theta}, 350, 240)`)
    }

    // rect
    //     .attr("x", d3.event.x)
    //     .attr("y", d3.event.y)
    //     .attr('transform', `rotate(${theta}, 350, 240)`)
        // .attr('transform', `rotate(${theta}, ${d3.event.x}, ${d3.event.y})`)
});

function gauge(container, configuration, config) {
    var that = {};
    var range = undefined;
    var r = undefined;
    var pointerHeadLength = undefined;

    var minAngle = 0;
    var maxAngle = 0;

    var counter = 0;

    var svg = undefined;
    var arc = undefined;
    // a linear scale that maps domain values to a percent from 0..1
    var scale = d3.scaleLinear()
        .range([0, 1])
        .domain([config.minValue, config.maxValue]);
    var ticks = undefined;
    var tickData = undefined;
    var pointer = undefined;
    var plane = undefined;

    function deg2rad(deg) {
        return deg * Math.PI / 180;
    }

    function testDraw(arcs, lowestGustAngle, highestGustAngle) {
        range = config.maxAngle - config.minAngle;
        r = config.size / 2;
        pointerHeadLength = Math.round(r * config.pointerHeadLengthPercent);

        ticks = scale.ticks(config.majorTicks);
        tickData = d3.range(config.majorTicks).map(function() {
            return 1 / config.majorTicks;
        });

        var newArc = d3.arc()
            .innerRadius(r - config.ringWidth - config.ringInset)
            .outerRadius(r - config.ringInset)
            .startAngle(deg2rad(lowestGustAngle))
            .endAngle(deg2rad(highestGustAngle));

        var width = 600;
        var height = 400;

        // stop duplication
        if (document.getElementsByClassName('newarc').length > 0) {
            arcs.selectAll('g')
                //animation
                .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
                .transition()
                .duration(4000);
        }

        d3.select("body")
            .append("svg")
            .attr("width", width)
            .attr("height", height)
            .attr('class', 'newarc')
            .append("g")
            .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
            .transition()
            .duration(4000);

        arcs.selectAll('d')
            .data(tickData)
            .enter()
            .append('g')
            .append('path')
            .attr('fill', 'green')
            .transition()
            .duration(4000)
            .attr('d', newArc);
    }

    function configure(configuration) {
        for (var prop in configuration) {
            config[prop] = configuration[prop];
        }

        range = config.maxAngle - config.minAngle;
        r = config.size / 2;
        pointerHeadLength = Math.round(r * config.pointerHeadLengthPercent);

        ticks = scale.ticks(config.majorTicks);
        tickData = d3.range(config.majorTicks).map(function() {
            return 1 / config.majorTicks;
        });

        arc = d3.arc()
            .innerRadius(r - config.ringWidth - config.ringInset)
            .outerRadius(r - config.ringInset)
            .startAngle(function(d, i) {
                var ratio = d * i;
                return deg2rad(config.minAngle + (ratio * range));
            })
            .endAngle(function(d, i) {
                var ratio = d * (i + 1);
                return deg2rad(config.minAngle + (ratio * range));
            });

        var width = 600;
        var height = 400;

        var svg = d3.select("body")
            .append("svg")
            .attr("width", width)
            .attr("height", height)
            .append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
    }

    that.configure = configure;

    function centerTranslation() {
        return 'translate(' + r + ',' + r + ')';
    }

    function isRendered() {
        return (svg !== undefined);
    }

    that.isRendered = isRendered;

    var arcs = undefined;

    function render(newValue) {
        svg = d3.select(container)
            .append('svg:svg')
            .attr('id', 'gauge')
            .attr('width', config.clipWidth)
            .attr('height', config.clipHeight);

        var centerTx = centerTranslation();

        arcs = svg.append('g')
            .attr('class', 'arc')
            .attr('transform', centerTx);

        arcs.selectAll('path')
            .data(tickData)
            .enter().append('path')
            .attr('fill', function(d, i) {
                return config.arcColorFn(d * i);
            })
            .attr('d', arc);

        var lg = svg.append('g')
            .attr('class', 'label')
            .attr('transform', centerTx);
        lg.selectAll('text')
            .data(ticks)
            .enter().append('text')
            .text('hi')
            .attr('transform', function(d) {
                var ratio = scale(d);
                var newAngle = config.minAngle + (ratio * range);
                console.log('index is');
                console.log(ticks);
                return 'rotate(' + newAngle + ') translate(0,' + (config.labelInset - r) + ')';
            })
            .text(function(d) {
                return tickDataLabel[d];
            });

        var planeData = [[config.pointerWidth / 2, 0],
            [4, -pointerHeadLength],
            [-(config.pointerWidth * 4), 0],
            [0, config.pointerTailLength],
            [config.pointerWidth / 2, 0]];

        var lineData = [[config.pointerWidth / 2, 0],
            [0, -pointerHeadLength],
            [-(config.pointerWidth / 2), 0],
            [0, config.pointerTailLength],
            [config.pointerWidth / 2, 0]];


        var pointerLine = d3.line().curve(d3.curveMonotoneX);

        var pgplane = svg.append('g').data([planeData])
            .attr('id', 'svgplane')
            .attr('transform', ' rotate(-45 100 100)');

        var pg = svg.append('g').data([lineData])
            .attr('class', 'pointer')
            .attr('id', 'pointer')
            .attr('transform', centerTx);

        plane = pgplane.append('path')
            .attr('d', planeStringImage)
            .attr('style', planeStyleElement)
            .attr('transform', 'rotate(' + config.minAngle + ')');

        pointer = pg.append('path')
            .attr('d', pointerLine)
            .attr('transform', 'rotate(' + config.minAngle + ')');

        update(newValue === undefined ? 0 : newValue);
    }

    that.render = render;

    function update(newValue, newConfiguration) {
        counter++;

        var randomAngle = Math.random() * 90;

        testDraw(arcs, randomAngle - 50, randomAngle);

        if (newConfiguration !== undefined) {
            configure(newConfiguration);
        }
        var ratio = scale(newValue);
        var newAngle = config.minAngle + (ratio * range);
        pointer.transition()
            .duration(config.transitionMs)
            .ease(d3.easeElastic)
            .attr('transform', 'rotate(' + newAngle + ')');

        if (minAngle >= newAngle) {
            minAngle = newAngle;
        }

        if (maxAngle <= newAngle) {
            maxAngle = newAngle;
        }

        if (counter === 5) {
            maxAngle = newAngle + 5;
            minAngle = newAngle - 5;
            counter = 1;
        }
    }

    that.update = update;

    configure(configuration);

    return that;
}

function onDocumentReady() {
    var config = {
        size: 200,
        clipWidth: 200,
        clipHeight: 110,
        ringInset: 20,
        ringWidth: 20,

        pointerWidth: 10,
        pointerTailLength: 5,
        pointerHeadLengthPercent: 0.9,

        minValue: 0,
        maxValue: 12,

        minAngle: -90 - 45 - 45,
        maxAngle: 90 + 45 + 45,

        transitionMs: 750,

        majorTicks: 10,
        labelFormat: d3.format(',g'),
        labelInset: 10,

        arcColorFn: d3.interpolateHsl(d3.rgb('#ffffff'), d3.rgb('#ffffff'))
    };

    var powerGauge = gauge('#power-gauge', {
        size: 300,
        clipWidth: 300,
        clipHeight: 300,
        ringWidth: 60,
        maxValue: 10,
        transitionMs: 4000
    }, config);
    powerGauge.render();

    function updateReadings() {

        var randomValue = Math.random() * 10;
        config.minAngle = randomValue * 10;

        powerGauge.update(randomValue);
    }

    updateReadings();
    setInterval(function() {
        updateReadings();
    }, 5 * 1000);
}

if (!window.isLoaded) {
    window.addEventListener("load", function() {
        onDocumentReady();

        d3.select("#planepath").call(drag);

        // Very dodge way of doing this!
        document.getElementById('pointer').append(document.getElementById('plane'));



        // .call(drag)
    }, false);
} else {
    onDocumentReady();
}
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
	<meta name="viewport" content="width=320" />
	<meta name="apple-mobile-web-app-capable" content="yes" />
	<title>Gauge</title>
	<!--<script type="text/javascript" src="http://d3js.org/d3.v2.min.js"></script>-->
	<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.js"></script>
	<script src="http://bernii.github.io/gauge.js/dist/gauge.min.js"></script>
	<style>
	body {
		font-family:  Helvetica, Arial, sans-serif;
		margin: 32px;
	}

	#power-gauge g.arc {
		fill: steelblue;
	}

	#power-gauge g.pointer {
		fill: #3ed850;
		stroke: #32ad40;
	}

	#power-gauge g.minpointer {
		fill: #4593f9;
		stroke: steelblue;
	}

	#power-gauge g.maxpointer {
		fill: #e85116;
		stroke: #b64011;
	}
	
	#power-gauge g.label text {
		text-anchor: middle;
		font-size: 14px;
		font-weight: bold;
		fill: #666;
	}
	</style>
</head>
<body >
  <h3 id="output">You have an airport facing at 0 degrees</h3>
<div id="power-gauge"></div>
<br>
<svg width="1200" height="600" viewBox="0 0 900 350">
	<g id="plane" style="" transform="translate(-55) scale(0.15, 0.15) rotate(-45 100 100)">
		<defs id="defs0"></defs>
		<path id="planepath" d="M 439.48098,95.969555 L 393.34268,142.46481 L 305.91233,133.41187 L 324.72376,114.58551 L 308.61525,98.464215 L 276.15845,130.94677 L 185.25346,123.08136 L 201.15145,107.27643 L 186.46085,92.574165 L 158.32,120.73735 L 45.386032,112.12042 L 15.000017,131.66667 L 221.20641,192.48691 L 298.26133,237.01135 L 191.91028,345.62828 L 152.82697,408.6082 L 41.549634,393.05411 L 21.037984,413.58203 L 109.25334,470.93369 L 166.38515,558.95725 L 186.8968,538.42933 L 171.35503,427.06371 L 234.28504,387.94939 L 342.81586,281.51396 L 387.305,358.63003 L 448.07703,565.00001 L 467.60778,534.58989 L 458.99769,421.56633 L 487.16033,393.38134 L 473.14247,379.35235 L 456.6139,395.97492 L 448.79636,303.63439 L 481.25315,271.15184 L 465.14464,255.03055 L 446.33321,273.8569 L 436.04766,185.1164 L 482.35108,138.7864 C 501.1942,119.92833 560.62425,61.834815 564.99998,14.999985 C 515.28999,23.707295 476.1521,61.495405 439.48098,95.969555 z " style="opacity:1;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible" id="path1"></path>
	</g>
</svg>



<br>

<svg id="test" width="1200" height="600" viewBox="0 0 900 350">
	<g style="" transform="translate(-55) scale(0.15, 0.15) rotate(-45 100 100)">
		<defs id="defs0"></defs>
		<path d="M 439.48098,95.969555 L 393.34268,142.46481 L 305.91233,133.41187 L 324.72376,114.58551 L 308.61525,98.464215 L 276.15845,130.94677 L 185.25346,123.08136 L 201.15145,107.27643 L 186.46085,92.574165 L 158.32,120.73735 L 45.386032,112.12042 L 15.000017,131.66667 L 221.20641,192.48691 L 298.26133,237.01135 L 191.91028,345.62828 L 152.82697,408.6082 L 41.549634,393.05411 L 21.037984,413.58203 L 109.25334,470.93369 L 166.38515,558.95725 L 186.8968,538.42933 L 171.35503,427.06371 L 234.28504,387.94939 L 342.81586,281.51396 L 387.305,358.63003 L 448.07703,565.00001 L 467.60778,534.58989 L 458.99769,421.56633 L 487.16033,393.38134 L 473.14247,379.35235 L 456.6139,395.97492 L 448.79636,303.63439 L 481.25315,271.15184 L 465.14464,255.03055 L 446.33321,273.8569 L 436.04766,185.1164 L 482.35108,138.7864 C 501.1942,119.92833 560.62425,61.834815 564.99998,14.999985 C 515.28999,23.707295 476.1521,61.495405 439.48098,95.969555 z " style="opacity:1;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible" id="path1"></path>
	</g>
</svg>


<br>
<svg width='650' height='600' viewBox='0 0 650 600' id="drag">
	<desc>
		You may click and drag the ellipse.
		Make the ellipse rotate by grabbing the small circle and dragging.
	</desc>
	<defs>
		<pattern id="trama" patternUnits="objectBoundingBox" width="2.5%" height="2.5%" patternTransform="rotate(25)" >
			<line id="linea" y2="1%" />
		</pattern>
	</defs>

	<!--<polygon id="box" points ="" stroke-width='1' stroke-dasharray='5,5' fill="none"></polygon>
      <path id='ellipse'
          d=''
          fill='url(#trama)'
          stroke-width='3' />
    <circle cx =""  cy ="" r ="6" id="LT" />-->

</svg>

<div id="foo"></div>


<script src="app.js">

</script>
<!--<script src="test.js">-->

<!--</script>-->
</body>
</html>

И я пытаюсь добавить его в компонент Angular 6:

Вот фрагмент кода:


import * as d3 from 'd3';

function dragFunction() {
  return function() {
    console.log('hit????');
    const width = 115;
    const height = 115;
    const rect = d3.select('#planepath');
    let theta = Math.atan2(d3.event.y - height / 2, d3.event.x - width / 2) * 180 / Math.PI;

    console.log('what is the angle?');
    console.log(theta);

theta = Math.round(theta / 10) * 10;

if (theta === 0 ||
  theta === 30 ||
  theta === 60 ||
  theta === 90 ||
  theta === 120 ||
  theta === 150 ||
  theta === 180 ||
  theta === -30 ||
  theta === -60 ||
  theta === -90 ||
  theta === -120 ||
  theta === -150 ||
  theta === 330) {

  rect
    .attr('x', d3.event.x)
    .attr('y', d3.event.y)
    .attr('transform', `rotate(${theta}, 350, 240)`);
}
  };
}

export class Drag {
  dragComponent() {
    d3.drag().on('drag', dragFunction());
  }

  constructor() {
    d3.select('#planepath').call(this.dragComponent);
  }
}

Как мне совместить датчик с угловым компонентом?

В настоящее время датчик загружается нормально и отображается нормально, но вы не можете использовать интерактивное событие d3 drag с ним. Нет ошибок консоли и даже при добавлении журналов консоли функция dragFunction не вызывается.

Буду весьма признателен за любые советы и рекомендации по взаимодействию d3 с Angular.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...