Highcharts - динамически модифицирующий SVG флаговых рядов - PullRequest
0 голосов
/ 13 апреля 2020

Я пытаюсь создать динамическую c серию флагов для go на моем основном графике, который является серией OHL C. Я хочу иметь возможность свободно перетаскивать каждый флаг, и когда его отпустят, он будет привязан к ближайшему значению y (либо «Высокое», либо «Низкое») текущего бара OHL C.

Я был в состоянии добиться этого поведения с помощью следующего кода:

Highcharts.getJSON('https://www.highcharts.com/samples/data/aapl-ohlc.json', function (data) {
		
    var lastDate = data[data.length - 1][0],  // Get year of last data point
        days = 24 * 36e5; // Milliseconds in a day
        
        
    // create the chart
    Highcharts.stockChart('container', {
				
        tooltip: {
        	enabled: false
        },

        rangeSelector: {
            selected: 0
        },
        
        xAxis :{
          crosshair: {
            width: 0
          }
        },

        title: {
            text: 'AAPL Stock Price'
        },

        series: [{
            type: 'ohlc',
            name: 'AAPL Stock Price',
            tooltip: {
            	visible: false
            },
            data: data,
            dataGrouping: {
                units: [[
                    'week', // unit name
                    [1] // allowed multiples
                ], [
                    'month',
                    [1, 2, 3, 4, 6]
                ]]
            }
        },
        {
        	type: 'flags',
          align: 'right',
          point: {
                      events: {
                          drop: snapFlag


                      }
                    },
          dragDrop: {
                        draggableX: false,
                        draggableY: true,
                    },
          data:[{
						x:data[data.length - 20][0],
            y: data[data.length - 20][2],
            title: "A",
            text: "1: test",
            snapto:'closest',
            title: 'A',
            
          }]
        
        }]
    });
});




function snapFlag(){
            /*
            * on drop event, find the nearest OHLC point and snap flag to that point
            * this will be the default unless "snapto" property is set to "none"
            */

            const old_x = this.x;
            const old_y = this.y;
            let new_graphic = this.graphic;
            let closest_y;
            let ohlc_point;

            // iterate x values in reverse to find matching ohlc point
            ohlc_point = this.series.chart.series[0].points.reverse().filter(function( point){
                return point.x === old_x;
            })[0];

            if(this.snapto === "closest"){
                // find the OHLC point that is closest to drop location
                closest_y = [ohlc_point.high,ohlc_point.low].reduce(function(prev, curr) {
                    return (Math.abs(curr - old_y) < Math.abs(prev - old_y) ? curr : prev);
                });

            }else if(this.snapto !== "float"){
                closest_y = ohlc_point[this.snapto]

            }else{
                closest_y = this.y

            }

            if(closest_y === ohlc_point.low){
                this.graphic.box.element.setAttribute('transform', `translate(0,${this.graphic.box.getBBox().height}) scale(1,-1) translate(0,-${this.graphic.box.getBBox().height})`);
            }else{
                this.graphic.box.element.removeAttribute('transform');

            }

            this.update({
                y: closest_y
            },true,false);

            // override the default behavior
            return false;
        }
<script src="https://code.highcharts.com/stock/highstock.js"></script>
<script src="https://code.highcharts.com/stock/modules/data.js"></script>
<script src="https://code.highcharts.com/stock/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/draggable-points.js"></script>


<div id="container" style="height: 400px; min-width: 310px"></div>

И JSFiddle здесь

У меня проблемы с преобразованием SVG. Как вы можете видеть, я успешно смог отразить путь SVG флага вокруг оси x так, чтобы он не перекрывался с полосой OHL C, к которой он прикреплен. Но у меня проблемы с получением названия флага, чтобы придерживаться того же перевода. Я пробовал аналогичные методы прямого редактирования элемента, который содержит заголовок, но не смог заставить изменения придерживаться.

Любая помощь в этом или другом направлении, которое я мог бы предпринять для достижения sh, это было бы быть оцененным Я застрял на этой маленькой детали некоторое время!

1 Ответ

0 голосов
/ 14 апреля 2020

Я думаю, что вы сможете достичь этого, переводя graphic.tex отдельно.

Часть лога c, которая была изменена:

  if (closest_y === ohlc_point.low) {
    this.graphic.box.element.setAttribute('transform', `translate(0,${this.graphic.box.getBBox().height}) scale(1,-1) translate(0,-${this.graphic.box.getBBox().height})`);

    this.graphic.text.translate(0, this.graphic.box.getBBox().height + this.graphic.text.getBBox().height)
  } else {
    this.graphic.box.element.removeAttribute('transform');
    this.graphic.text.element.removeAttribute('transform');
  }

Демонстрация: https://jsfiddle.net/BlackLabel/vy1gzwmd/

...