Whalensdad
Posts: 56
Joined: Tue Jun 01, 2021 4:14 pm

Scatter Plot with Data Labels?

Can a scatter plot have data labels like the following?
Image
hubert.k
Posts: 1164
Joined: Mon Apr 11, 2022 11:48 am

Re: Scatter Plot with Data Labels?

Hello Whalensdad,
We appreciate you reaching out to us!

You can achieve this by using the annotations module in your project. You can see the example demo below and read more about this module here: https://www.highcharts.com/docs/advance ... ons-module

Demo: https://jsfiddle.net/BlackLabel/hgjmc5b4/
API Reference: https://api.highcharts.com/highcharts/a ... ons.labels
https://api.highcharts.com/highcharts/a ... belOptions

Feel free to ask any further questions!
Regards!
Hubert Kozik
Highcharts Developer
Whalensdad
Posts: 56
Joined: Tue Jun 01, 2021 4:14 pm

Re: Scatter Plot with Data Labels?

Can you provide a .Net example? I have tried using your example in my .net app but they annotations don't display. The chart displays, but the annotations don't. FYI: I can't paste the whole page because your site prevents the posting of script tags, so I broke things up. I also have references to the following files on my page
"~/lib/highcharts/js/highcharts.js"
"~/lib/highcharts/js/highcharts-more.js"
"~/lib/highcharts/js/annotations.js"

This is in a script tag

Code: Select all

    $(function () {
        const data = [{
            id: 'A',
            label: 'This is issue #1',
            x: 4,
            y: 4
        },
        {
            id: 'B',
            label: 'This is issue #2',
            x: 6,
            y: 2
        },
        {
            id: 'C',
            label: 'This is issue #3',
            x: 2,
            y: 6
        },
        {
            id: 'D',
            label: 'This is issue #4',
            x: 1,
            y: 0
        }
        ],
            annoatationsLabels = data.map(el => ({
                point: el.id,
                text: '{point.label}'
            }));

        Highcharts.chart('container1', {
            annotations: [{
                labels: annoatationsLabels,

            }],
            chart: {
                type: 'scatter',
            },
            xAxis: {
                min: 0
            },
            series: [{
                color: 'red',
                data: data
            }]
        });

    });
and this is the rest of the document

Code: Select all

@{
    ViewData["Title"] = "Privacy Policy";
}


<div>
    <table class="table1" style="margin:auto">
        <tr>
            <td>
                <!--Bubble Chart-->
                <div id="container1"></div>
            </td>
        </tr>
    </table>
</div>

@section Scripts {


}
Whalensdad
Posts: 56
Joined: Tue Jun 01, 2021 4:14 pm

Re: Scatter Plot with Data Labels?

I switched to V10 of the js files and annotations work in general. However I need an example of how to call the following from a .Net environment.

Code: Select all

annoatationsLabels = data.map(el => ({
    point: el.id,
    text: '{point.label}'
  }));
In your example, this is put in the javascript code outside of the highcharts function. However, if you look at the example I provided in a previous post,I can't get the values for the annotations.
Whalensdad
Posts: 56
Joined: Tue Jun 01, 2021 4:14 pm

Re: Scatter Plot with Data Labels?

This is what I have so far.
1. I can't get the actual label to show using the following:

Code: Select all

 const data = @Html.Raw(Newtonsoft.Json.JsonConvert.DeserializeObject(ViewData["scatter1"].ToString())),
            annoatationsLabels = data.map(el => ({
                point: {
                    x: el.x,
                    y: el.y,
                    xAxis: 0,
                    yAxis: 0
                },
                text: '{point.label}'
            }));
I had to hard code 'Test' to create the image below. I have also tried 'el.label' without success. My model which is passed to the ViewData object is this:

Code: Select all

public class ScatterSeriesModel
    {
        public int x { get; set; }
        public int y { get; set; }
        public string label { get; set; }
        public string id { get; set; }
    }
2. Can you jitter the annotations? In the image below you can see I have a significant number of points. The annotation is fixed, and not tied to the actual jittered point. If not, other than annotations, is there a way to do what I asked in my first question in this thread?


Image
Whalensdad
Posts: 56
Joined: Tue Jun 01, 2021 4:14 pm

Re: Scatter Plot with Data Labels?

Here is the dataset being passed with the label data.
Image
Whalensdad
Posts: 56
Joined: Tue Jun 01, 2021 4:14 pm

Re: Scatter Plot with Data Labels?

(Please read the previous 2 posts first) If I can't do what I want with annotations, is there a way to modify the position of the data labels so they don't overlap. I know you can set the dataLabel.x and dataLabel.y properties, but is there a way to do it based on the jittered point and the other data labels?
Image
hubert.k
Posts: 1164
Joined: Mon Apr 11, 2022 11:48 am

Re: Scatter Plot with Data Labels?

Hello Whalensdad, sorry for the late reply.

You have to create two lists. One with data, and the second with labels. If these labels overlap you have to set them individually for each point. I am attaching a URL to download a file with an example demo here: https://www17.zippyshare.com/v/se7TNecl/file.html

Regards!
Hubert Kozik
Highcharts Developer
Whalensdad
Posts: 56
Joined: Tue Jun 01, 2021 4:14 pm

Re: Scatter Plot with Data Labels?

While your simple example worked, my more complex example is not. Here are the issues:
1. Not all data points are showing the annotations.
2. Not all annotations are separate from the data point
3. The Style syntax for the Titles are not being applied.
4. The formatter function for the DataLabels is not being applied
5. I cannot figure out how to add a javascript function call (or a way to do this call) in this code snippet:

Code: Select all

labels: {
                    formatter: function () {
                        return bcyAxislabelFormatter(this.value);
                    },
                    rotation: -45,
                }
6. I can't figure out how to add Events and responsive to the code:

Code: Select all

chart: {
                 type: 'scatter',
                 zoomType: 'xy',
                 width: 1650,
                 height: 800,
                 events: {
                     load: function () {
                         StaggerDataLabels(this.series);
                     },
                     redraw: function () {
                         var series = this.series;
                         setTimeout(function () {
                             StaggerDataLabels(series);
                         }, 1000);
                     }
                 },
             },
             responsive: {
                 rules: [{
                     condition: {
                         maxWidth: 600
                     },
                     chartOptions: {
                         series: {
                             //dataLabels: {
                             //    enabled: false
                             //}
                         },
                     }
                 }

                 ]
             },
Here is my controller code:

Code: Select all

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using Highsoft.Web.Mvc.Charts;
using Highsoft.Web.Mvc.Charts.Rendering;

namespace ScatterPlotSample.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult About()
        {
            //based on model that you use you need to create two different lists: one with data and second with labels

            var data = new List<ScatterSeriesData>();
            data.Add(new ScatterSeriesData { X = 1, Y = 2, Name = "Second Issue Title", Id = "20-002" });
            data.Add(new ScatterSeriesData { X = 1, Y = 2, Name = "Lee Test Not Admin", Id = "20-017" });
            data.Add(new ScatterSeriesData { X = 1, Y = 2, Name = "Commit Quarter Test", Id = "20-019" });
            data.Add(new ScatterSeriesData { X = 1, Y = 2, Name = "this is a test 1", Id = "21-006" });
            data.Add(new ScatterSeriesData { X = 1, Y = 2, Name = "Security Marking Test 2", Id = "21-021" });
            data.Add(new ScatterSeriesData { X = 1, Y = 3, Name = "Create Commit Quarter History 3", Id = "20-021" });
            data.Add(new ScatterSeriesData { X = 1, Y = 3, Name = "Test of TinyMCE", Id = "21-002" });
            data.Add(new ScatterSeriesData { X = 1, Y = 4, Name = "TPPI Test", Id = "21-018" });
            data.Add(new ScatterSeriesData { X = 2, Y = 2, Name = "Test LMPI #2", Id = "21-017" });
            data.Add(new ScatterSeriesData { X = 2, Y = 2, Name = "Test TinyMCE Changes", Id = "21-003" });
            data.Add(new ScatterSeriesData { X = 2, Y = 2, Name = "Lee Test Affected programs #1", Id = "20-018" });
            data.Add(new ScatterSeriesData { X = 2, Y = 2, Name = "Lee Test Edge", Id = "20-015" });
            data.Add(new ScatterSeriesData { X = 2, Y = 3, Name = "Testing IssueID Loading", Id = "20-011" });
            data.Add(new ScatterSeriesData { X = 2, Y = 3, Name = "Third Test of Issue ID Creation", Id = "20-013" });
            data.Add(new ScatterSeriesData { X = 2, Y = 3, Name = "This is the title of the 1st issue which is a little longer than normal", Id = "20-001" });
            data.Add(new ScatterSeriesData { X = 2, Y = 3, Name = "This is a test", Id = "21-004" });
            data.Add(new ScatterSeriesData { X = 2, Y = 3, Name = "DELETED", Id = "21-013" });
            data.Add(new ScatterSeriesData { X = 2, Y = 3, Name = "Test", Id = "21-015" });
            data.Add(new ScatterSeriesData { X = 2, Y = 4, Name = "Yet another issue yup", Id = "20-003" });
            data.Add(new ScatterSeriesData { X = 2, Y = 4, Name = "Testing of Create an Issue page", Id = "20-005" });
            data.Add(new ScatterSeriesData { X = 3, Y = 1, Name = "Second test of IssueID Creation", Id = "20-012" });
            data.Add(new ScatterSeriesData { X = 3, Y = 2, Name = "New Issue on 10/19", Id = "20-004" });
            data.Add(new ScatterSeriesData { X = 3, Y = 3, Name = "this is a test ", Id = "21-005" });
            data.Add(new ScatterSeriesData { X = 3, Y = 3, Name = "Testing New IssueID Creation", Id = "20-010" });
            data.Add(new ScatterSeriesData { X = 3, Y = 3, Name = "Testing Root Cause Issues", Id = "21-023" });
            data.Add(new ScatterSeriesData { X = 3, Y = 4, Name = "DELETED", Id = "21-009" });
            data.Add(new ScatterSeriesData { X = 3, Y = 4, Name = "DELETED", Id = "21-012" });
            data.Add(new ScatterSeriesData { X = 3, Y = 4, Name = "test", Id = "20-006" });
            data.Add(new ScatterSeriesData { X = 3, Y = 5, Name = "DELETED", Id = "21-008" });
            data.Add(new ScatterSeriesData { X = 3, Y = 5, Name = "Security Marking Test 3", Id = "21-022" });
            data.Add(new ScatterSeriesData { X = 4, Y = 1, Name = "Testing of Issue ID4", Id = "20-014" });
            data.Add(new ScatterSeriesData { X = 4, Y = 2, Name = "Create Commit Quarter History 2", Id = "20-020" });
            data.Add(new ScatterSeriesData { X = 4, Y = 2, Name = "Lifecycle and Impact test", Id = "22-001" });
            data.Add(new ScatterSeriesData { X = 4, Y = 3, Name = "This is a test", Id = "21-014" });
            data.Add(new ScatterSeriesData { X = 4, Y = 3, Name = "New Functional Area Test", Id = "21-001" });
            data.Add(new ScatterSeriesData { X = 4, Y = 3, Name = "this is a test 1", Id = "21-007" });
            data.Add(new ScatterSeriesData { X = 4, Y = 3, Name = "DELETED", Id = "21-011" });
            data.Add(new ScatterSeriesData { X = 4, Y = 3, Name = "Test4", Id = "20-009" });
            data.Add(new ScatterSeriesData { X = 4, Y = 5, Name = "Name Test", Id = "21-010" });
            data.Add(new ScatterSeriesData { X = 4, Y = 5, Name = "Test of LMPI", Id = "21-016" });
            data.Add(new ScatterSeriesData { X = 5, Y = 2, Name = "test1", Id = "20-007" });
            data.Add(new ScatterSeriesData { X = 5, Y = 3, Name = "Lee Edge Test 2", Id = "20-016" });
            data.Add(new ScatterSeriesData { X = 5, Y = 3, Name = "TPPI Test", Id = "21-019" });
            data.Add(new ScatterSeriesData { X = 5, Y = 3, Name = "Security Marking Test", Id = "21-020" });
            data.Add(new ScatterSeriesData { X = 5, Y = 5, Name = "Test2", Id = "20-008" });



            var dataLabels = new List<AnnotationsLabels>();
            dataLabels.Add(new AnnotationsLabels { Point = "20-002", Text = "Second Issue Title", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "20-017", Text = "Lee Test Not Admin", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "20-019", Text = "Commit Quarter Test", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "21-006", Text = "this is a test 1", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "21-021", Text = "Security Marking Test 2", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "20-021", Text = "Create Commit Quarter History 3", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "21-002", Text = "Test of TinyMCE", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "21-018", Text = "TPPI Test", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "21-017", Text = "Test LMPI #2", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "21-003", Text = "Test TinyMCE Changes", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "20-018", Text = "Lee Test Affected programs #1", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "20-015", Text = "Lee Test Edge", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "20-011", Text = "Testing IssueID Loading", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "20-013", Text = "Third Test of Issue ID Creation", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "20-001", Text = "This is the title of the 1st issue which is a little longer than normal", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "21-004", Text = "This is a test", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "21-013", Text = "DELETED", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "21-015", Text = "Test", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "20-003", Text = "Yet another issue yup", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "20-005", Text = "Testing of Create an Issue page", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "20-012", Text = "Second test of IssueID Creation", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "20-004", Text = "New Issue on 10/19", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "21-005", Text = "this is a test ", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "20-010", Text = "Testing New IssueID Creation", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "21-023", Text = "Testing Root Cause Issues", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "21-009", Text = "DELETED", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "21-012", Text = "DELETED", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "20-006", Text = "test", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "21-008", Text = "DELETED", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "21-022", Text = "Security Marking Test 3", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "20-014", Text = "Testing of Issue ID4", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "20-020", Text = "Create Commit Quarter History 2", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "22-001", Text = "Lifecycle and Impact test", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "21-014", Text = "This is a test", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "21-001", Text = "New Functional Area Test", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "21-007", Text = "this is a test 1", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "21-011", Text = "DELETED", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "20-009", Text = "Test4", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "21-010", Text = "Name Test", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "21-016", Text = "Test of LMPI", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "20-007", Text = "test1", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "20-016", Text = "Lee Edge Test 2", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "21-019", Text = "TPPI Test", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "21-020", Text = "Security Marking Test", X = -80, Y = 30 });
            dataLabels.Add(new AnnotationsLabels { Point = "20-008", Text = "Test2", X = -80, Y = 30 });


            var chartOptions = new Highcharts
            {
                ID = "chart",
                Annotations = new List<Annotations>
                {
                    new Annotations {
                        LabelOptions = new AnnotationsLabelOptions { X = -80, Y = 30 }, //general positioning but inside the chart
                        Labels = dataLabels
                    }
                },
                Chart = new Chart
                {
                    Type = ChartType.Scatter,
                    ZoomType = ChartZoomType.Xy,
                    Width = "1650",
                    Height = 800
                },
                Credits = new Credits
                {
                    Enabled = false
                },
                Legend = new Legend
                {
                    Enabled = false
                },
                Title = new Title
                {
                    Text = "Impact vs Life Cycle Root Cause",
                    Style = { { "fontSize:", "50px" }, { "color:", "black" } }
                },
                Series = new List<Series>
                {
                    new ScatterSeries
                    {
                        Data = data,
                        Color = "red"

                    }
                },
                XAxis = new List<XAxis>
                {
                    new XAxis
                    {
                        GridLineWidth = 1,
                        Title = new XAxisTitle
                        {
                            Text = "Impact",
                            Style = { { "fontSize:", "50px" }, { "color:", "black" } }
                        },
                        Min = 0,
                        TickInterval = 0,
                        Max = 6,
                        ShowFirstLabel = false,
                        ShowLastLabel = false,

                    }
                },
                YAxis = new List<YAxis>
                {
                    new YAxis
                    {
                        GridLineWidth = 1,
                        Title = new YAxisTitle
                        {
                            Text = "Life Cycle Root Cause",
                            Style = { { "fontSize:", "50px" }, { "color:", "black" } }
                        },
                        Min = 0,
                        TickInterval = 0,
                        Max = 6,
                        ShowFirstLabel = false,
                        ShowLastLabel = false,
                    }
                },
                PlotOptions = new PlotOptions
                {
                    Series = new PlotOptionsSeries
                    {
                        DataLabels = new PlotOptionsSeriesDataLabels
                        {
                            AllowOverlap = true,
                            Shape = "connector",
                            Enabled = true,
                            Formatter = "function() {return (this.point.label)}"
                        }
                    },
                    Scatter = new PlotOptionsScatter
                    {
                        Jitter = new PlotOptionsScatterJitter
                        {
                            X = 0.24,
                            Y = 0.24,
                        },
                        Marker = new PlotOptionsScatterMarker
                        {
                            Radius = 5,
                            States = new PlotOptionsScatterMarkerStates
                            {
                                Hover = new PlotOptionsScatterMarkerStatesHover
                                {
                                    Enabled = true,
                                    LineColor = "rgb(100,100,100)"
                                }
                            }
                        },
                        States = new PlotOptionsScatterStates
                        {
                            Hover = new PlotOptionsScatterStatesHover
                            {
                                Enabled = true,
                            }
                        }
                    }
                },
                Tooltip = new Tooltip
                {
                    PointFormat = "{point.x} , {point.y}, {point.label}"
                },
            };

            var renderer = new HighchartsRenderer(chartOptions);
            ViewData["renderer"] = renderer;

            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }
    }
}
hubert.k
Posts: 1164
Joined: Mon Apr 11, 2022 11:48 am

Re: Scatter Plot with Data Labels?

Hello Whalensdad,
We are very sorry, but for reasons beyond our control, an answer for you takes an exceptionally long time for you to respond.

I will be back with your answer as soon as it is possible.
Best regards!
Hubert Kozik
Highcharts Developer
hubert.k
Posts: 1164
Joined: Mon Apr 11, 2022 11:48 am

Re: Scatter Plot with Data Labels?

Whalensdad,
Here are answers to your questions from our .NET developer. I would like to apologize again for such a long response time.

1. That's because annotation logic is hiding some annotations if there is no place for them. If you zoom to a point, the annotation will show up.
2. That's the same reason as from the first point. The algorithm is looking for a place. If it is not located where it has been positioned, they will check if it fits without positioning, and if not, it does not appear.
3. You should do it using Hashtable object.
4. You are setting the formatted function in the right way, but I don't know what do you want to show in dataLabels. this is pointing to the series.point, so you have access to all properties from the point, like x, y, color etc. and all custom properties, which you can add individually to the point.
5. You are right with calling the JS function, but remember that dataLabels.formatter needs a callback function, so bcyAxislabelFormatter function has to return something also.
6. You are properly setting functions to chart.events. To see how to use responsive property take a look at this demo: https://jsfiddle.net/gh/get/library/pur ... sive/axis/ and you can find more about this in the documentation.

API Reference: https://api.highcharts.com/highcharts/s ... .formatter
https://api.highcharts.com/highcharts/chart.events
https://api.highcharts.com/highcharts/responsive

Kind regards!
Hubert Kozik
Highcharts Developer
Whalensdad
Posts: 56
Joined: Tue Jun 01, 2021 4:14 pm

Re: Scatter Plot with Data Labels?

Thanks for the info. I think I'm going to stick with doing things in JS. It seems to be better supported.
hubert.k
Posts: 1164
Joined: Mon Apr 11, 2022 11:48 am

Re: Scatter Plot with Data Labels?

If you need a hand with our .NET wrapper, then feel free to ask. But yes, Highcharts is written in JS so writing directly in JS is more convenient than through the wrapper.
Hubert Kozik
Highcharts Developer

Return to “Highcharts Usage”