Steve
Steve

Reputation: 266

ngx-charts line chart, how to show the line chart with dot for the data point all the time

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.

Upvotes: 7

Views: 9622

Answers (3)

Pratik Prajapati
Pratik Prajapati

Reputation: 71

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

Upvotes: -1

chrismarx
chrismarx

Reputation: 12545

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-

Upvotes: 1

Hasan Daghash
Hasan Daghash

Reputation: 1691

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

Upvotes: 5

Related Questions