6

for ngx-charts line chart, it show the line chart, but there is no dot for the data point. enter image description here

If you hover the data point, it show a dot for the data pint and also with a label tooltip.

enter image description here

I like to have the line chart to show all the data point with a dot all the time like this.

enter image description here

I need your help on how to show a dot at the data point in ngx-charts line chart

Here is the sample for ngx-chart https://github.com/kedmenecr/cinnamon-angular5-with-ngx-charts

Here is the source code for ngx-chart libary . https://github.com/swimlane/ngx-charts

thanks.

Steve
  • 256
  • 5
  • 12

3 Answers3

4

if anyone still needs this feature I workaround this feature with a non-super clean solution but it works with no side effect so far :

enter image description here

custom service to draw the points over liner chart:

import { Injectable } from '@angular/core';
@Injectable()
export class CustomLinerChartService {
    /**
     * custom: override SVG to have the dots display all the time over the liner chart
     * since it's not supported anymore from ngx chart
     */

    showDots(chart) {
        let index = 0;
        const paths = chart.chartElement.nativeElement.getElementsByClassName(
            'line-series'
        );
        const color = chart.chartElement.nativeElement.getElementsByClassName(
            'line-highlight'
        );

        for (let path of paths) {
            const chrtColor = color[index].getAttribute('ng-reflect-fill');
            const pathElement = path.getElementsByTagName('path')[0];
            const pathAttributes = {
                'marker-start': `url(#dot${index})`,
                'marker-mid': `url(#dot${index})`,
                'marker-end': `url(#dot${index})`
            };
            this.createMarker(chart, chrtColor, index);
            this.setAttributes(pathElement, pathAttributes);
            index += 1;
        }
    }

    /**
     * create marker
     *
     */

    createMarker(chart, color, index) {
        const svg = chart.chartElement.nativeElement.getElementsByTagName('svg');
        var marker = document.createElementNS(
            'http://www.w3.org/2000/svg',
            'marker'
        );
        var circle = document.createElementNS(
            'http://www.w3.org/2000/svg',
            'circle'
        );
        svg[0].getElementsByTagName('defs')[0].append(marker);
        marker.append(circle);
        const m = svg[0].getElementsByTagName('marker')[0];
        const c = svg[0].getElementsByTagName('circle')[0];

        const markerAttributes = {
            id: `dot${index}`,
            viewBox: '0 0 10 10',
            refX: 5,
            refY: 5,
            markerWidth: 5,
            markerHeight: 5
        };

        const circleAttributes = {
            cx: 5,
            cy: 5,
            r: 5,
            fill: color
        };
        m.append(circle);

        this.setAttributes(m, markerAttributes);
        this.setAttributes(c, circleAttributes);
    }

    /**
     * set multiple attributes
     */
    setAttributes(element, attributes) {
        for (const key in attributes) {
            element.setAttribute(key, attributes[key]);
        }
    }
}

and after your view init and the data is set to the chart call :

@ViewChild('chart') chart: any;

ngAfterViewInit() {
    this.customLinerChartService.showDots(this.chart);
}

make sure to have the reference on your chart :

<ngx-charts-line-chart #chart>

UPDATE

you can't rely on ng-reflect-fill class since it just added in development mood so insted provide your colors as array and chose it based on index for example

Hasan Daghash
  • 1,681
  • 1
  • 17
  • 29
  • 3
    this worked great, except one issue is that with multiple charts it only draws the dots on one chart. I fixed it by adding the index in the marker and circle get elements: "const m = svg[0].getElementsByTagName('marker')[index]; const c = svg[0].getElementsByTagName('circle')[index];" – WtFudgE Jul 24 '20 at 09:12
  • Is there any way to redraw the dots once the dataset of the chart changes? – Gereon99 Jul 29 '20 at 01:39
  • I actually just found a way, calling 'service.showDots()' manually after changing the dataset doesn't work. However doing 'setTimeout(() => { this.service.showDots(this.chart); }, 0);' works. Is there a way of doing this without using 'setTimeout()'? – Gereon99 Jul 29 '20 at 01:47
  • 1
    @WtFudgE in my project I'm considering each chart as a stand-alone component in this case you are good – Hasan Daghash Aug 05 '20 at 10:29
  • @Gereon99 just call this guy each time you update the data : this.customLinerChartService.showDots(this.chart); – Hasan Daghash Aug 05 '20 at 10:30
1

This simpler approach first posted here also works well:

https://github.com/swimlane/ngx-charts/issues/462#issuecomment-783237600

I suggest first getting a reference to the chart, and looping through the series:

@ViewChild("numberChart", {read: ElementRef, static: false})
numberChartRef: ElementRef;
...
chartRef.nativeElement.querySelectorAll("g.line-series path").forEach((el) => {
     el.setAttribute("stroke-width", "10");
     el.setAttribute("stroke-linecap", "round");
});

I test the length of the series, and only apply these changes if the length is 1. Also make sure to return the attributes to the defaults though if you don't want extra thick lines for all your charts-

chrismarx
  • 11,488
  • 9
  • 84
  • 97
-1

I have a way simpler solution to this, just adding a single field will do the trick for you:

In your component class, set the "dot" property of the series to true:

this.data = [
  {
    name: 'Series 1',
    series: [
      {
        name: 'Point 1',
        value: 9,
      },
      {
        name: 'Point 2',
        value: 7,
      },
      {
        name: 'Point 3',
        value: 5,
      }
    ],
    dot: true
  },
  {
    name: 'Series 2',
    series: [
      {
        name: 'Point 1',
        value: 8,
      },
      {
        name: 'Point 2',
        value: 6,
      },
      {
        name: 'Point 3',
        value: 4,
      }
    ],
    dot: true
  }
];

This will show dots on the line chart on the respective data points as shown below:

Data points Highlight Single Point