import { Spec } from 'vega';

export const spec: Spec = {
  $schema: 'https://vega.github.io/schema/vega/v5.json',
  width: 500,
  height: 100,
  padding: 5,

  signals: [
    { name: 'binOffset', value: 0, bind: { input: 'range', min: -0.1, max: 0.1 } },
    { name: 'binStep', value: 0.1, bind: { input: 'range', min: 0.001, max: 0.4, step: 0.001 } }
  ],

  data: [
    {
      name: 'points',
      url: 'data/normal-2d.json'
    },
    {
      name: 'binned',
      source: 'points',
      transform: [
        {
          type: 'bin',
          field: 'u',
          extent: [-1, 1],
          anchor: { signal: 'binOffset' },
          step: { signal: 'binStep' },
          nice: false
        },
        {
          type: 'aggregate',
          key: 'bin0',
          groupby: ['bin0', 'bin1'],
          fields: ['bin0'],
          ops: ['count'],
          as: ['count']
        }
      ]
    }
  ],

  scales: [
    {
      name: 'xscale',
      type: 'linear',
      range: 'width',
      domain: [-1, 1]
    },
    {
      name: 'yscale',
      type: 'linear',
      range: 'height',
      round: true,
      domain: { data: 'binned', field: 'count' },
      zero: true,
      nice: true
    }
  ],

  axes: [
    { orient: 'bottom', scale: 'xscale', zindex: 1 },
    { orient: 'left', scale: 'yscale', tickCount: 5, zindex: 1 }
  ],

  marks: [
    {
      type: 'rect',
      from: { data: 'binned' },
      encode: {
        update: {
          x: { scale: 'xscale', field: 'bin0' },
          x2: { scale: 'xscale', field: 'bin1', offset: { signal: 'binStep > 0.02 ? -0.5 : 0' } },
          y: { scale: 'yscale', field: 'count' },
          y2: { scale: 'yscale', value: 0 },
          fill: { value: 'steelblue' }
        },
        hover: { fill: { value: 'firebrick' } }
      }
    },
    {
      type: 'rect',
      from: { data: 'points' },
      encode: {
        enter: {
          x: { scale: 'xscale', field: 'u' },
          width: { value: 1 },
          y: { value: 25, offset: { signal: 'height' } },
          height: { value: 5 },
          fill: { value: 'steelblue' },
          fillOpacity: { value: 0.4 }
        }
      }
    }
  ]
};
