Karthick A.S
Karthick A.S

Reputation: 185

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

I need to do some kind of animation using jquery/javascript html5, css3. Not sure it is possible or not. I have created three divs with three bubble charts. I need to draw arrow line from one div(from bubble to next div) dynamically. enter image description here

And my expectation is need to draw arrow line dynamically from one bubble to another.

enter image description here

I am using Highcharts.js bubble chart.

My code:

    <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>

Upvotes: 1

Views: 240

Answers (1)

ppotaczek
ppotaczek

Reputation: 39099

You can create the diagram by using only one Highcharts chart. Each section can be a separate x-axis and y-axis:

  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%'
  }]

Then, with the help of Highcharts.SVGRenderer class in render event, draw the required connections by using values stored in the chart.

  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: [
            ...
          ]
        });
      }
    }
  }

Live demo: http://jsfiddle.net/BlackLabel/r7p2t4j6/

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

API Reference:

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

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

Upvotes: 1

Related Questions