Skip to content

Scatterplot chart

TIP

For core principles, concept description, API and changelog, refer to the D3 chart.

Basic usage

tsx
import { Chart } from '@semcore/ui/d3-chart';
import React from 'react';

import ScatterplotMockData from './mock';

const Demo = () => {
  return (
    <Chart.ScatterPlot
      data={data}
      plotWidth={500}
      plotHeight={300}
      groupKey='x'
      aria-label='ScatterPlot chart'
    />
  );
};

const data = ScatterplotMockData.Default;

export default Demo;

TIP

For all the following examples, scale is calculated taking into account synthetic data. You can see the mathematics, used in Change.Scatterplot to calculate common scale, in our GitHub repository.

Advanced usage

tsx
import { Plot, ScatterPlot, XAxis, YAxis, minMax } from '@semcore/ui/d3-chart';
import { Text } from '@semcore/ui/typography';
import { scaleLinear } from 'd3-scale';
import React from 'react';

import ScatterplotMockData from './mock';

const Demo = () => {
  const MARGIN = 40;
  const width = 500;
  const height = 300;

  const xScale = scaleLinear()
    .range([MARGIN, width - MARGIN])
    .domain([-1, 21]);

  const yScale = scaleLinear()
    .range([height - MARGIN, MARGIN])
    .domain([-1, 11]);

  return (
    <Plot scale={[xScale, yScale]} width={width} height={height} data={data}>
      <YAxis>
        <YAxis.Ticks />
        <YAxis.Grid />
      </YAxis>
      <XAxis>
        <XAxis.Ticks />
      </XAxis>
      <ScatterPlot x='x' y='y' />
      <ScatterPlot.Tooltip>
        {({ index }) => {
          return {
            children: (
              <>
                <ScatterPlot.Tooltip.Title>Data</ScatterPlot.Tooltip.Title>
                <Text tag='div'>
                  X axis
                  {data[index].x}
                </Text>
                <Text tag='div'>
                  Y axis
                  {data[index].y}
                </Text>
              </>
            ),
          };
        }}
      </ScatterPlot.Tooltip>
    </Plot>
  );
};

const data = ScatterplotMockData.Default;

export default Demo;

Color customization

If required, you can assign your own color to Scatter plot.

tsx
import { Plot, ScatterPlot, XAxis, YAxis, minMax } from '@semcore/ui/d3-chart';
import { Text } from '@semcore/ui/typography';
import { scaleLinear } from 'd3-scale';
import React from 'react';

import ScatterplotMockData from './mock';

const Demo = () => {
  const MARGIN = 40;
  const width = 500;
  const height = 300;

  const xScale = scaleLinear()
    .range([MARGIN, width - MARGIN])
    .domain([-1, 21]);

  const yScale = scaleLinear()
    .range([height - MARGIN, MARGIN])
    .domain([-1, 11]);

  return (
    <Plot scale={[xScale, yScale]} width={width} height={height} data={data}>
      <YAxis>
        <YAxis.Ticks />
        <YAxis.Grid />
      </YAxis>
      <XAxis>
        <XAxis.Ticks />
      </XAxis>
      <ScatterPlot x='x' y='y1' color='#2BB3FF' />
      <ScatterPlot x='x' y='y2' color='#59DDAA' />
      <ScatterPlot.Tooltip>
        {({ index, x, y, color }) => {
          return {
            children: (
              <>
                <ScatterPlot.Tooltip.Dot color={color}>Data</ScatterPlot.Tooltip.Dot>
                <Text tag='div'>
                  X axis
                  {/* @ts-ignore */}
                  {data[index][x]}
                </Text>
                <Text tag='div'>
                  Y axis
                  {/* @ts-ignore */}
                  {data[index][y]}
                </Text>
              </>
            ),
          };
        }}
      </ScatterPlot.Tooltip>
    </Plot>
  );
};

const data = ScatterplotMockData.TwoSetsWithValue;

export default Demo;

Displaying values in dots

tsx
import { Plot, ScatterPlot, XAxis, YAxis, minMax } from '@semcore/ui/d3-chart';
import { Text } from '@semcore/ui/typography';
import { scaleLinear } from 'd3-scale';
import React from 'react';

import ScatterplotMockData from './mock';

const Demo = () => {
  const MARGIN = 40;
  const width = 500;
  const height = 300;

  const xScale = scaleLinear()
    .range([MARGIN, width - MARGIN])
    .domain([-1, 21]);

  const yScale = scaleLinear()
    .range([height - MARGIN, MARGIN])
    .domain([-1, 11]);

  return (
    <Plot scale={[xScale, yScale]} width={width} height={height} data={data}>
      <YAxis>
        <YAxis.Ticks />
        <YAxis.Grid />
      </YAxis>
      <XAxis>
        <XAxis.Ticks />
      </XAxis>
      <ScatterPlot x='x' y='y' value='value' />
      <ScatterPlot.Tooltip>
        {({ index, x, y, value }) => {
          return {
            children: (
              <>
                <ScatterPlot.Tooltip.Title>Data</ScatterPlot.Tooltip.Title>
                <Text tag='div'>
                  X axis
                  {/* @ts-ignore */}
                  {data[index][x]}
                </Text>
                <Text tag='div'>
                  Y axis
                  {/* @ts-ignore */}
                  {data[index][y]}
                </Text>
                <Text tag='div'>
                  Value
                  {/* @ts-ignore */}
                  {data[index][value]}
                </Text>
              </>
            ),
          };
        }}
      </ScatterPlot.Tooltip>
    </Plot>
  );
};

const data = ScatterplotMockData.DefaultWithValue;

export default Demo;

Legend and pattern fill

Note that for ChartLegend patterns property works only with default shape={'Checkbox'}.

tsx
import { Plot, ScatterPlot, XAxis, YAxis, minMax, ChartLegend } from '@semcore/ui/d3-chart';
import { scaleLinear } from 'd3-scale';
import React from 'react';

import ScatterplotMockData from './mock';

const getDegaultLegendItems = () => {
  return Object.keys(data[0])
    .filter((name) => name !== 'x' && name !== 'value')
    .map((item, index) => {
      return {
        id: item,
        label: `Dataset ${index + 1}`,
        checked: true,
        color: `chart-palette-order-${index + 1}`,
      };
    });
};

const Demo = () => {
  const [legendItems, setLegendItems] = React.useState(getDegaultLegendItems);

  const handleChangeVisible = React.useCallback((id: string, isVisible: boolean) => {
    setLegendItems((prevItems) => {
      const newItems = prevItems.map((item) => {
        if (item.id === id) {
          item.checked = isVisible;
        }

        return item;
      });

      return newItems;
    });
  }, []);

  const MARGIN = 40;
  const width = 500;
  const height = 300;

  const xScale = scaleLinear()
    .range([MARGIN, width - MARGIN])
    .domain([-1, 11]);

  const yScale = scaleLinear()
    .range([height - MARGIN, MARGIN])
    .domain([-1, 11]);

  return (
    <>
      <ChartLegend
        items={legendItems}
        shape='Checkbox'
        patterns
        onChangeVisibleItem={handleChangeVisible}
        aria-label='Scatterplot legend'
      />
      <Plot scale={[xScale, yScale]} width={width} height={height} data={data} patterns={true}>
        <YAxis>
          <YAxis.Ticks />
          <YAxis.Grid />
        </YAxis>
        <XAxis>
          <XAxis.Ticks />
        </XAxis>
        {legendItems
          .filter((item) => item.checked)
          .map((item) => {
            return (
              <ScatterPlot key={item.id} x='x' y={item.id} value='value' color={item.color} />
            );
          })}
      </Plot>
    </>
  );
};

const data = ScatterplotMockData.ThreeSetsWithValue;

export default Demo;

Dot values and custom colors

If required, you can assign your own color to Scatter plot.

tsx
import { Plot, ScatterPlot, XAxis, YAxis } from '@semcore/ui/d3-chart';
import { Text } from '@semcore/ui/typography';
import { scaleLinear } from 'd3-scale';
import React from 'react';

import ScatterplotMockData from './mock';

const Demo = () => {
  const MARGIN = 40;
  const width = 500;
  const height = 300;

  const xScale = scaleLinear()
    .range([MARGIN, width - MARGIN])
    .domain([-1, 21]);

  const yScale = scaleLinear()
    .range([height - MARGIN, MARGIN])
    .domain([-1, 11]);

  return (
    <Plot scale={[xScale, yScale]} width={width} height={height} data={data}>
      <YAxis>
        <YAxis.Ticks />
        <YAxis.Grid />
      </YAxis>
      <XAxis>
        <XAxis.Ticks />
      </XAxis>
      <ScatterPlot x='x' y='y1' value='value' color='#2BB3FF' valueColor='#008ff8' />
      <ScatterPlot x='x' y='y2' value='value' color='#59DDAA' valueColor='#00C192' />
      <ScatterPlot.Tooltip>
        {({ index, x, y, value }) => {
          return {
            children: (
              <>
                <ScatterPlot.Tooltip.Title>Data</ScatterPlot.Tooltip.Title>
                <Text tag='div'>
                  X axis
                  {/* @ts-ignore */}
                  {data[index][x]}
                </Text>
                <Text tag='div'>
                  Y axis
                  {/* @ts-ignore */}
                  {data[index][y]}
                </Text>
                <Text tag='div'>
                  Value
                  {/* @ts-ignore */}
                  {data[index][value]}
                </Text>
              </>
            ),
          };
        }}
      </ScatterPlot.Tooltip>
    </Plot>
  );
};

const data = ScatterplotMockData.TwoSetsWithValue;

export default Demo;

Initial data loading

Use ScatterPlotChartSkeleton for the initial chart loading.

tsx
import { ScatterPlotChartSkeleton } from '@semcore/ui/skeleton';
import React from 'react';

const Demo = () => (
  <React.Fragment>
    <ScatterPlotChartSkeleton />
  </React.Fragment>
);

export default Demo;

Released under the MIT License.

Released under the MIT License.