需要使用 css3 从气泡图绘制箭头线到另一个 div

Need to draw arrow line from bubble chart to another div using css3

我需要使用 jquery/javascript html5、css3 制作某种动画。不确定是否可能。我用三个气泡图创建了三个 div。我需要从一个 div(从气泡到下一个 div)动态绘制箭头线。

而我的期望是需要动态绘制从一个气泡到另一个气泡的箭头线。

我正在使用 Highcharts.js 气泡图。

我的代码:

    <script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/highcharts-more.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>
<script src="https://code.highcharts.com/modules/accessibility.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<figure class="highcharts-figure">
<div class="container">
  <div class="row">
        <div class="col-sm-4 mt-4">
            <div id="container1" class="blinking-points"></div>
            
        </div> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    
        <div class="col-sm-4 mt-4">
            <div id="container2"></div>
       </div>
   </div>
   </div>
</figure>




<style>

.highcharts-figure,
.highcharts-data-table table {
    min-width: 310px;
    max-width: 800px;
    margin: 1em auto;
}

#container1 {

height: 500px;
    height: 300px;
    width:300px;
    border: 1px solid black;
}

#container2 {
    height: 300px;
    width:300px;
    border: 1px solid black;
}

.highcharts-tooltip h3 {
    margin: 0.3em 0;
}

.highcharts-data-table table {
    font-family: Verdana, sans-serif;
    border-collapse: collapse;
    border: 1px solid #ebebeb;
    margin: 10px auto;
    text-align: center;
    width: 100%;
    max-width: 500px;
}

.highcharts-data-table caption {
    padding: 1em 0;
    font-size: 1.2em;
    color: #555;
}

.highcharts-data-table th {
    font-weight: 600;
    padding: 0.5em;
}

.highcharts-data-table td,
.highcharts-data-table th,
.highcharts-data-table caption {
    padding: 0.5em;
}

.highcharts-data-table thead tr,
.highcharts-data-table tr:nth-child(even) {
    background: #f8f8f8;
}

.highcharts-data-table tr:hover {
    background: #f1f7ff;
}

</style>
<script>


Highcharts.chart('container1', {

    chart: {
        type: 'bubble',
        plotBorderWidth: 0,
        //zoomType: 'xy',
        height: '100%'
    },
    legend: {
        enabled: false
    },

    title: {
        text: 'first'
    },
    xAxis: {
        
        lineWidth: 0,
           minorGridLineWidth: 0,
           lineColor: 'transparent',
           gridLineColor: 'transparent',
           labels: {
               enabled: false
           },
           minorTickLength: 0,
           tickLength: 0,
           title: {
            text: ''
            },
    },
    yAxis: {
        
        lineWidth: 0,
           minorGridLineWidth: 0,
           lineColor: 'transparent',
           gridLineColor: 'transparent',
           labels: {
               enabled: false
           },
           minorTickLength: 0,
           tickLength: 0,
           title: {
            text: ''
            },
    },

   accessibility: {
    point: {
            valueDescriptionFormat: '{point.name}'
     }
   },

    

    tooltip: {
        useHTML: true,
        //headerFormat: '<table>',
        formatter: function() {
            return '<b>' + (this.point ? this.point.days : this.series.name) + '</b><br/>';
        },
        //footerFormat: '</table>',
        followPointer: true
    },

    plotOptions: {
        series: {
            dataLabels: {
                enabled: true,
                format: '{point.name}'
            },
            
        }
    },

    series: [{
        data: [
            { days: 95, y: 82.9, z: 3.7, name: 'A1', appName: 'A1' },
            { days: 86.5, y: 102.9, z: 14.7, name: 'B1', appName: 'B1' },
            { days: 80.8, y: 91.5, z: 15.8, name: 'C1', appName: 'C1' },
            { days: 80.4, y: 102.5, z: 12, name: 'D1', appName: 'D1' },
            { days: 80.3, y: 86.1, z: 11.8, name: 'E1', appName: 'E1'},
            { days: 78.4, y: 70.1, z: 16.6, name: 'F1', appName: 'F1' },
            { days: 74.2, y: 68.5, z: 14.5, name: 'G1', appName: 'G1' },
            { days: 73.5, y: 83.1, z: 10, name: 'H1', appName: 'H1' }
        ],
        className: "first"
    }]

});

Highcharts.chart('container2', {

    chart: {
        type: 'bubble',
        //plotBorderWidth: 0,
        //zoomType: 'xy',
        height: '100%'
    },
    legend: {
        enabled: false
    },

    title: {
        text: 'second'
    },

   // subtitle: {
  //      text: 'Source: <a href="http://www.euromonitor.com/">Euromonitor</a> and <a href="https://data.oecd.org/">OECD</a>'
   // },

    accessibility: {
    point: {
            valueDescriptionFormat: '{point.name}'
     }
   },
    
    xAxis: {
        
        lineWidth: 0,
           minorGridLineWidth: 0,
           lineColor: 'transparent',
           gridLineColor: 'transparent',
           labels: {
               enabled: false
           },
           minorTickLength: 0,
           tickLength: 0,
           title: {
            text: ''
            },
    },
    yAxis: {
        
        lineWidth: 0,
           minorGridLineWidth: 0,
           lineColor: 'transparent',
           gridLineColor: 'transparent',
           labels: {
               enabled: false
           },
           minorTickLength: 0,
           tickLength: 0,
           title: {
            text: ''
            },
    },
    tooltip: {
        useHTML: true,
        //headerFormat: '<table>',
        //pointFormat: '<tr><th colspan="2"><h3>{point.appName}</h3></th></tr>' +
        //    '<tr><th>No of Days:</th><td>{point.days} days</td></tr>',
        //footerFormat: '</table>',
        
        //headerFormat: '<table>',
        formatter: function() {
            return '<b>' + (this.point ? this.point.days : this.series.name) + '</b><br/>';
        },
        //footerFormat: '</table>',
        followPointer: true
    },

    plotOptions: {
        series: {
            dataLabels: {
                enabled: true,
                format: '{point.name}'
            }
        }
    },

    series: [{
        data: [
             { days: 21, y: 102.9, z: 14.7, name: 'A2', appName: 'A2' },
            { days: 12, y: 102.9, z: 14.7, name: 'B2', appName: 'B2' },
            { days: 8, y: 91.5, z: 15.8, name: 'C2', appName: 'C2'},
            { days: 2, y: 102.5, z: 12, name: 'D2', appName: 'D2' },
            { days: 43, y: 86.1, z: 11.8, name: 'E2', appName: 'E2' },
            { days: 1, y: 70.1, z: 8.6, name: 'F2', appName: 'F2' },
            { days: 6, y: 68.5, z: 14.5, name: 'G2', appName: 'G2' },
            { days: 73.5, y: 83.1, z: 10, name: 'H2', appName: 'H2' }
        ],
        
        className: "second"
    }]

});


</script>

您可以只使用一个 Highcharts 图表来创建图表。每个部分可以是一个单独的x轴和y轴:

  yAxis: [{
    ...
  }, {
    ...
  }, {
    offset: 0,
    lineWidth: 1,
    height: '40%',
    top: '60%',
    left: '20%',
    width: '60%',
    title: null
  }],
  xAxis: [{
    ...
  }, {
    ...
  }, {
    offset: 0,
    width: '60%',
    left: '20%',
    height: '40%',
    top: '60%'
  }]

然后,在render事件中Highcharts.SVGRendererclass的帮助下,使用存储在图表中的值绘制所需的连接。

  chart: {
    type: 'bubble',
    events: {
      render: function() {
        const chart = this;
        const series = chart.series;
        const yAxis3 = chart.yAxis[2];
        const p1 = series[0].points[0];

        if (!p1.customLink) {
          // create the connection only at first render
          p1.customLink = chart.renderer.path().attr({
            ...
          }).add();
        }
        // update the connection dimensions on each render
        p1.customLink.attr({
          d: [
            ...
          ]
        });
      }
    }
  }

现场演示: http://jsfiddle.net/BlackLabel/r7p2t4j6/

文档: https://www.highcharts.com/docs/advanced-chart-features/freeform-drawing

API参考:

https://api.highcharts.com/highcharts/yAxis

https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#path