{
  "name": "chart",
  "dependencies": [
    "@unovis/vue",
    "@unovis/ts"
  ],
  "registryDependencies": [],
  "files": [
    {
      "name": "ChartCrosshair.vue",
      "content": "<script setup lang=\"ts\">\nimport { VisCrosshair, VisTooltip } from '@unovis/vue';\nimport type { BulletLegendItemInterface } from '@unovis/ts';\nimport { omit } from '@unovis/ts';\nimport { type Component, createApp } from 'vue';\nimport { ChartTooltip } from '.';\n\nconst props = withDefaults(defineProps<{\n  colors: string[];\n  index: string;\n  items: BulletLegendItemInterface[];\n  customTooltip?: Component;\n}>(), {\n  colors: () => [],\n});\n\nconst wm = new WeakMap();\n\nfunction template(d: any) {\n  if (wm.has(d)) {\n    return wm.get(d);\n  } else {\n    const componentDiv = document.createElement('div');\n    const omittedData = Object.entries(omit(d, [props.index])).map(([key, value]) => {\n      const legendReference = props.items.find(i => i.name === key);\n      return { ...legendReference, value };\n    });\n    const TooltipComponent = props.customTooltip ?? ChartTooltip;\n    createApp(TooltipComponent, { title: d[props.index].toString(), data: omittedData }).mount(componentDiv);\n    wm.set(d, componentDiv.innerHTML);\n    return componentDiv.innerHTML;\n  }\n}\n\nfunction color(d: unknown, i: number) {\n  return props.colors[i] ?? 'transparent';\n}\n</script>\n\n<template>\n  <VisTooltip\n    :horizontal-shift=\"20\"\n    :vertical-shift=\"20\"\n  />\n  <VisCrosshair\n    :template=\"template\"\n    :color=\"color\"\n  />\n</template>\n"
    },
    {
      "name": "ChartLegend.vue",
      "content": "<script setup lang=\"ts\">\nimport { VisBulletLegend } from '@unovis/vue';\nimport type { BulletLegendItemInterface } from '@unovis/ts';\nimport { BulletLegend } from '@unovis/ts';\nimport { nextTick, onMounted, ref } from 'vue';\nimport { buttonVariants } from '@ui/registry/css/ui/button';\n\nconst props = withDefaults(defineProps<{ items: BulletLegendItemInterface[] }>(), {\n  items: () => [],\n});\n\nconst emits = defineEmits<{\n  'legendItemClick': [d: BulletLegendItemInterface, i: number];\n  'update:items': [payload: BulletLegendItemInterface[]];\n}>();\n\nconst elRef = ref<HTMLElement>();\n\nonMounted(() => {\n  const selector = `.${BulletLegend.selectors.item}`;\n  nextTick(() => {\n    const elements = elRef.value?.querySelectorAll(selector);\n    const classes = buttonVariants({ variant: 'ghost', size: 'xs' }).split(' ');\n    elements?.forEach(el => el.classList.add(...classes, 'sigma-ui-chart-legend__item'));\n  });\n});\n\nfunction onLegendItemClick(d: BulletLegendItemInterface, i: number) {\n  emits('legendItemClick', d, i);\n  const isBulletActive = !props.items[i].inactive;\n  const isFilterApplied = props.items.some(i => i.inactive);\n\n  if (isFilterApplied && isBulletActive) {\n    // reset filter\n    emits('update:items', props.items.map(item => ({ ...item, inactive: false })));\n  } else {\n    // apply selection, set other item as inactive\n    emits('update:items', props.items.map(item => item.name === d.name ? ({ ...d, inactive: false }) : { ...item, inactive: true }));\n  }\n}\n</script>\n\n<template>\n  <div\n    ref=\"elRef\"\n    class=\"sigma-ui-chart-legend\"\n  >\n    <VisBulletLegend\n      :items=\"items\"\n      :on-legend-item-click=\"onLegendItemClick\"\n    />\n  </div>\n</template>\n\n<style>\n.sigma-ui-chart-legend {\n  width: max-content;\n}\n\n.sigma-ui-chart-legend__item {\n  display: inline-flex !important;\n  margin-right: 0.5rem;\n}\n</style>\n"
    },
    {
      "name": "ChartSingleTooltip.vue",
      "content": "<script setup lang=\"ts\">\nimport { VisTooltip } from '@unovis/vue';\nimport type { BulletLegendItemInterface } from '@unovis/ts';\nimport { omit } from '@unovis/ts';\nimport { type Component, createApp } from 'vue';\nimport { ChartTooltip } from '.';\n\nconst props = withDefaults(defineProps<{\n  selector: string;\n  index: string;\n  items?: BulletLegendItemInterface[];\n  valueFormatter?: (tick: number, i?: number, ticks?: number[]) => string;\n  customTooltip?: Component;\n}>(), {\n  valueFormatter: (tick: number) => `${tick}`,\n});\n\nconst wm = new WeakMap();\n\nfunction template(d: any, i: number, elements: (HTMLElement | SVGElement)[]) {\n  if (props.index in d) {\n    if (wm.has(d)) {\n      return wm.get(d);\n    } else {\n      const componentDiv = document.createElement('div');\n      const omittedData = Object.entries(omit(d, [props.index])).map(([key, value]) => {\n        const legendReference = props.items?.find(i => i.name === key);\n        return { ...legendReference, value: props.valueFormatter(value) };\n      });\n      const TooltipComponent = props.customTooltip ?? ChartTooltip;\n      createApp(TooltipComponent, { title: d[props.index], data: omittedData }).mount(componentDiv);\n      wm.set(d, componentDiv.innerHTML);\n      return componentDiv.innerHTML;\n    }\n  } else {\n    const data = d.data;\n\n    if (wm.has(data)) {\n      return wm.get(data);\n    } else {\n      const style = getComputedStyle(elements[i]);\n      const omittedData = [{ name: data.name, value: props.valueFormatter(data[props.index]), color: style.fill }];\n      const componentDiv = document.createElement('div');\n      const TooltipComponent = props.customTooltip ?? ChartTooltip;\n      createApp(TooltipComponent, { title: d[props.index], data: omittedData }).mount(componentDiv);\n      wm.set(d, componentDiv.innerHTML);\n      return componentDiv.innerHTML;\n    }\n  }\n}\n</script>\n\n<template>\n  <VisTooltip\n    :horizontal-shift=\"20\"\n    :vertical-shift=\"20\"\n    :triggers=\"{\n      [selector]: template,\n    }\"\n  />\n</template>\n"
    },
    {
      "name": "ChartTooltip.vue",
      "content": "<script setup lang=\"ts\">\nimport { Card, CardContent, CardHeader, CardTitle } from '@ui/registry/css/ui/card';\n\ndefineProps<{\n  title?: string;\n  data: {\n    name: string;\n    color: string;\n    value: any;\n  }[];\n}>();\n</script>\n\n<template>\n  <Card class=\"sigma-ui-chart-tooltip\">\n    <CardHeader\n      v-if=\"title\"\n      class=\"sigma-ui-chart-tooltip__header\"\n    >\n      <CardTitle>\n        {{ title }}\n      </CardTitle>\n    </CardHeader>\n    <CardContent class=\"sigma-ui-chart-tooltip__content\">\n      <div\n        v-for=\"(item, key) in data\"\n        :key=\"key\"\n        class=\"sigma-ui-chart-tooltip__item\"\n      >\n        <div class=\"sigma-ui-chart-tooltip__item-label\">\n          <span class=\"sigma-ui-chart-tooltip__item-dot\">\n            <svg\n              width=\"100%\"\n              height=\"100%\"\n              viewBox=\"0 0 30 30\"\n            >\n              <path\n                d=\" M 15 15 m -14, 0 a 14,14 0 1,1 28,0 a 14,14 0 1,1 -28,0\"\n                :stroke=\"item.color\"\n                :fill=\"item.color\"\n                stroke-width=\"1\"\n              />\n            </svg>\n          </span>\n          <span>{{ item.name }}</span>\n        </div>\n        <span class=\"sigma-ui-chart-tooltip__item-value\">{{ item.value }}</span>\n      </div>\n    </CardContent>\n  </Card>\n</template>\n\n<style>\n.sigma-ui-chart-tooltip {\n  font-size: 0.875rem;\n}\n\n.sigma-ui-chart-tooltip__header {\n  padding: 0.75rem;\n  border-bottom: 1px solid hsl(var(--border));\n}\n\n.sigma-ui-chart-tooltip__content {\n  padding: 0.75rem;\n  min-width: 180px;\n  display: flex;\n  flex-direction: column;\n  gap: 0.25rem;\n}\n\n.sigma-ui-chart-tooltip__item {\n  display: flex;\n  justify-content: space-between;\n}\n\n.sigma-ui-chart-tooltip__item-label {\n  display: flex;\n  align-items: center;\n}\n\n.sigma-ui-chart-tooltip__item-dot {\n  width: 0.625rem;\n  height: 0.625rem;\n  margin-right: 0.5rem;\n}\n\n.sigma-ui-chart-tooltip__item-value {\n  font-weight: 600;\n  margin-left: 1rem;\n}\n</style>\n"
    },
    {
      "name": "index.ts",
      "content": "export { default as ChartTooltip } from './ChartTooltip.vue';\nexport { default as ChartSingleTooltip } from './ChartSingleTooltip.vue';\nexport { default as ChartLegend } from './ChartLegend.vue';\nexport { default as ChartCrosshair } from './ChartCrosshair.vue';\n\nexport function defaultColors(count: number = 3) {\n  const quotient = Math.floor(count / 2);\n  const remainder = count % 2;\n\n  const primaryCount = quotient + remainder;\n  const secondaryCount = quotient;\n  return [\n    ...Array.from(Array(primaryCount).keys()).map(i => `hsl(var(--vis-primary-color) / ${1 - (1 / primaryCount) * i})`),\n    ...Array.from(Array(secondaryCount).keys()).map(i => `hsl(var(--vis-secondary-color) / ${1 - (1 / secondaryCount) * i})`),\n  ];\n}\n\nexport * from './interface';\n"
    },
    {
      "name": "interface.ts",
      "content": "import type { Spacing } from '@unovis/ts';\n\ntype KeyOf<T extends Record<string, any>> = Extract<keyof T, string>;\n\nexport interface BaseChartProps<T extends Record<string, any>> {\n  /**\n   * The source data, in which each entry is a dictionary.\n   */\n  data: T[];\n  /**\n   * Select the categories from your data. Used to populate the legend and toolip.\n   */\n  categories: KeyOf<T>[];\n  /**\n   * Sets the key to map the data to the axis.\n   */\n  index: KeyOf<T>;\n  /**\n   * Change the default colors.\n   */\n  colors?: string[];\n  /**\n   * Margin of each the container\n   */\n  margin?: Spacing;\n  /**\n   * Change the opacity of the non-selected field\n   * @default 0.2\n   */\n  filterOpacity?: number;\n  /**\n   * Function to format X label\n   */\n  xFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string;\n  /**\n   * Function to format Y label\n   */\n  yFormatter?: (tick: number | Date, i: number, ticks: number[] | Date[]) => string;\n  /**\n   * Controls the visibility of the X axis.\n   * @default true\n   */\n  showXAxis?: boolean;\n  /**\n   * Controls the visibility of the Y axis.\n   * @default true\n   */\n  showYAxis?: boolean;\n  /**\n   * Controls the visibility of tooltip.\n   * @default true\n   */\n  showTooltip?: boolean;\n  /**\n   * Controls the visibility of legend.\n   * @default true\n   */\n  showLegend?: boolean;\n  /**\n   * Controls the visibility of gridline.\n   * @default true\n   */\n  showGridLine?: boolean;\n}\n"
    }
  ],
  "type": "components:ui"
}