{"id":15998036,"url":"https://github.com/z3ut/interpolated-charts","last_synced_at":"2026-05-05T07:31:32.734Z","repository":{"id":57275283,"uuid":"92687936","full_name":"z3ut/interpolated-charts","owner":"z3ut","description":"Configurable d3 v4 charts with interpolation and missing data range","archived":false,"fork":false,"pushed_at":"2018-10-25T11:07:16.000Z","size":1237,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-17T08:20:20.825Z","etag":null,"topics":["charts","d3","interpolation"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/z3ut.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-05-28T21:24:03.000Z","updated_at":"2018-10-25T11:07:34.000Z","dependencies_parsed_at":"2022-09-15T19:10:28.897Z","dependency_job_id":null,"html_url":"https://github.com/z3ut/interpolated-charts","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/z3ut/interpolated-charts","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/z3ut%2Finterpolated-charts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/z3ut%2Finterpolated-charts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/z3ut%2Finterpolated-charts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/z3ut%2Finterpolated-charts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/z3ut","download_url":"https://codeload.github.com/z3ut/interpolated-charts/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/z3ut%2Finterpolated-charts/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32640533,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-04T10:08:07.713Z","status":"online","status_checked_at":"2026-05-05T02:00:06.033Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["charts","d3","interpolation"],"created_at":"2024-10-08T08:06:43.221Z","updated_at":"2026-05-05T07:31:32.710Z","avatar_url":"https://github.com/z3ut.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Interpolated Charts\n\nConfigurable [d3 v4](https://github.com/d3/d3) charts with interpolation and missing data range. Inspired by [Britecharts](https://github.com/eventbrite/britecharts)\n\nAngular component [here](https://github.com/z3ut/ng-interpolated-charts)\n\n[![npm version](https://badge.fury.io/js/interpolated-charts.svg)](https://badge.fury.io/js/interpolated-charts)\n\n[Live demo](https://z3ut.github.io/interpolated-charts)\n\n![default-interpolated-chart](https://raw.githubusercontent.com/z3ut/interpolated-charts/master/img/default-interpolated-chart.gif)\n\n## Description\n\n- Configurable line chart with tooltip and markers\n- Gasps between data points (missing data range)\n- Compute and display interpolated values between data points\n\nIterpolation values are calculated on svg path element using the binary search method. It means that after changing chart curve type (d3.curveBasis, d3.curveCatmullRom, ...) computed values can change. Do not rely on this data if you need high accuracy.\n\n## Installation\n\n1. Install with [npm](https://www.npmjs.com)\n\n```\nnpm install interpolated-charts --save\n```\n\n2. Import JS dependencies\n\n```javascript\nimport * as d3 from 'd3';\nimport { line, stackBar, chartEvents, verticalDivider, markers, tooltip } from 'interpolated-charts';\n```\n\n3. Import CSS\n\n```\n@import 'interpolated-charts/src/index.css'\n```\n\n## Usage\n\nPackage include line chart and three plugins: vertical divider, markers highlight, tooltip information. Line chart dispatch mouse events (chartMouseEnter, chartMouseLeave, chartMouseMove, chartMouseClick), defined in chartEvents. Default configuration for chart with plugins:\n\n```javascript\nconst verticalDividerPlugin = verticalDivider();\nconst markersPlugin = markers();\nconst tooltipPlugin = tooltip();\n\nconst lineChart = line()\n  // subscribe plugins to chart events\n  .on(chartEvents.chartMouseEnter, () =\u003e {\n    verticalDividerPlugin.show();\n  })\n  .on(chartEvents.chartMouseLeave, () =\u003e {\n    verticalDividerPlugin.remove();\n    markersPlugin.remove();\n    tooltipPlugin.remove();\n  })\n  .on(chartEvents.chartMouseMove, (options) =\u003e {\n    verticalDividerPlugin.update(options);\n    markersPlugin.show(options);\n    tooltipPlugin.show(options);\n  });\n\n// create chart with data\nconst chartContainer = d3.select('.default-chart');\nchartContainer.datum(lineChartData).call(lineChart);\n\n// bind plugins to chart\nconst metadataContainer = d3.select('.default-chart .metadata-container');\nmetadataContainer.datum([]).call(verticalDividerPlugin);\nmetadataContainer.datum([]).call(markersPlugin);\nmetadataContainer.datum([]).call(tooltipPlugin);\n```\n\nChart data example:\n\n```javascript\nconst lineChartData = [\n  // each object represent chart line dataset\n  {\n    'name': 'Minsk',\n    // optional color\n    'color': 'darkblue',\n    'data': [\n      { 'date': new Date('2015-01-01T00:00:00'), 'value': 20 },\n      { 'date': new Date('2015-01-02T00:00:00'), 'value': 16 }\n    ]\n  }\n]\n```\n\nDefault chart is first example on [demo page](https://z3ut.github.io/interpolated-charts).\n\nSource code for examples - /demo.\n\nPackage include internal @types for Typescript.\n\n## Documentation\n\n### Line Chart\n\n#### Usage\n\n```javascript\n// create chart with custom config\nconst lineChart = line({ width: 900 });\n// set property on existing chart\nlineChart.curve(d3.curveCatmullRom);\n// get d3 selection for chart container\nconst chartContainer = d3.select('.default-chart');\nconst lineChartData = [/* PathDataSet[] */];\n// bind selection with data and call chart creation\nchartContainer.datum(lineChartData).call(lineChart);\n\n```\n\n#### Chart data format\n```typescript\ninterface PathDataSet {\n  name: string;\n  color?: string;\n  data: { date: Date, value: number }[];\n}\n```\n\n#### Events\n\nchartEvents.chartMouseEnter - mouse entered chart boundary. Arguments - mouse coordinates x, y relative to chart;\n\nchartEvents.chartMouseLeave - mouse leaved chart boundary. Arguments - mouse coordinates x, y relative to chart;\n\nchartEvents.chartMouseMove - mouse moved inside chart boundary. Event treshhold (mouseMoveTimeTreshold, ms) - min time between events. Arguments - { x: number, y: number, selectedDate: Date, data: PointData[] }. data - array of closest chart points data based on mouse current position:\n\n```typescript\ninterface PointData {\n  // concrete values from PathDataSet and their coordinates on graph\n  date: Date;\n  value: number;\n  x: number;\n  y: number;\n  // interpolated values, closest to mouse position\n  interpolatedX: number;\n  interpolatedY: number;\n  interpolatedDate: Date;\n  interpolatedValue: number;\n\n  name: string;\n  color: string;\n}\n```\n\nchartEvents.chartMouseClick - mouse click inside chart boundary. Arguments - { x: number, y: number, selectedDate: Date, data: PointData[] }.\n\n#### CSS\n\nChart grid lines css classes:\n\n.line-chart .horizontal-grid-line, .line-chart .vertical-grid-line\n\n#### Options\n\nName | Description | Type | Default\n--- | --- | --- | ---\nwidth | Chart total width | Number | 700\nheight | Chart total height | Number | 500\nmargin | Chart graph margin to outer bounds | { top: number, right: number, bottom: number, left: number } | { top: 20, right: 30, bottom: 40, left: 40 }\nmaxTimeRangeDifferenceToDraw | Max time in milliseconds to treat dataset points without breaking | Number | 1000 * 60 * 60 * 24 * 1.5 (1.5 days)\nxAxisTimeFormat | Date tick format for chart X Axis | d3.tickFormat | undefined\nyAxisValueFormat | Value tick format for chart Y Axis | d3.tickFormat | undefined\ncurve | Curve type for line interpolation. **Important**: value interpolation compute on chart resulted line and depend on this config value | d3.curve | d3.curveBasis\nchartHeight | Chart graph actual heigth getter. Total height - (margin.top + margin.bottom) | Number |\nchartWidth | Chart graph actual width getter. Total width - (margin.left + margin.right | Number |\ninterpolationMaxIterationCount | Interpolation cycle count. Computing will stop after N cycle or when Δx \u003c accuracy **Important**: high value can slow preformance | Number | 50\ninterpolationAccuracy | Interpolation Δx accuracy for searching y value on svg path. Computing will stop after N cycle or when Δx \u003c accuracy | Number | 0.005\nmouseMoveTimeTreshold | Minimum time in milliseconds between chartMouseMove events | Number | 20\nxAxisDateFrom | Chart X Axis start date | Date | undefined\nxAxisDateTo | Chart X Axis end date | Date | undefined\n\n### Bar chart\n\n#### Usage\n\n```javascript\n// create bar chart\nconst barChart = bar();\n\nconst barChartContainer = d3.select('.bar-bar');\nconst barChartData = [/* PathDataSet[] */];\n// bind selection with data and call chart creation\nbarChartContainer.datum(barChartData).call(barChart);\n```\n\n#### Chart data format\nArray of\n```typescript\ninterface StackBarData {\n  name: string;\n  backgroundColor?: string;\n  data: {\n    date: Date,\n    color?: string,\n    value: any\n  }[];\n}\n```\n\n#### Events\n\nchartEvents.chartMouseEnter - mouse entered chart boundary. Arguments - mouse coordinates x, y relative to chart;\n\nchartEvents.chartMouseLeave - mouse leaved chart boundary. Arguments - mouse coordinates x, y relative to chart;\n\nchartEvents.chartMouseMove - mouse moved inside chart boundary. Event treshhold (mouseMoveTimeTreshold, ms) - min time between events. Arguments - { x: number, y: number, selectedDate: Date, data: MouseEventBarChartData[] }. data - array of closest chart points data based on mouse current position:\n\nchartEvents.chartMouseClick - mouse click inside chart boundary. Arguments - { x: number, y: number, selectedDate: Date, data: MouseEventBarChartData[] }.\n\n#### Options\n\nName | Description | Type | Default\n--- | --- | --- | ---\nwidth | Chart total width | Number | 700\nheight | Chart total height | Number | 120\nmargin | Chart graph margin to outer bounds | { top: number, right: number, \nsetStackWidth | Function to compute stack width | Function | (chartWidth, numberOfBars) =\u003e chartWidth / numberOfBars - 20\nmaxTimeRangeDifferenceToDraw | Max time in milliseconds to treat dataset points without breaking | Number | 1000 * 60 * 60 * 24 * 1.5 (1.5 days)\nstackTimeDiapason | Time diapason for one stack | Number | 1000 * 60 * 60 * 24\nxAxisTimeFormat | Date tick format for chart X Axis | d3.tickFormat | undefined\nyAxisValueFormat | Value tick format for chart Y Axis | d3.tickFormat | undefined\nxAxisDateFrom | Chart X Axis start date | Date | undefined\nxAxisDateTo | Chart X Axis end date | Date | undefined\nyAxisValueFrom | Chart Y Axis start value | Number | undefined\nyAxisValueTo | Chart Y Axis end value | Number | undefined\n\n### Stack bar\n\n#### Usage\n\n```javascript\n// create stack bar\nconst stackBarChart = stackBar();\n\nconst stackBarContainer = d3.select('.stack-bar');\nconst stackBarData = [/* StackBarData[] */];\n// bind selection with data and call chart creation\nstackBarContainer.datum(stackBarData).call(stackBarChart);\n```\n\n#### Chart data format\nArray of\n```typescript\ninterface PathDataSet {\n  name: string;\n  color?: string;\n  data: { date: Date, value: number }[];\n}\n```\n\n#### Events\n\nchartEvents.chartMouseEnter - mouse entered chart boundary. Arguments - mouse coordinates x, y relative to chart;\n\nchartEvents.chartMouseLeave - mouse leaved chart boundary. Arguments - mouse coordinates x, y relative to chart;\n\nchartEvents.chartMouseMove - mouse moved inside chart boundary. Event treshhold (mouseMoveTimeTreshold, ms) - min time between events. Arguments - { x: number, y: number, selectedDate: Date, diapasonStart: Date, diapasonEnd: Date, data: MouseEventBarChartData[] }. data - array of closest chart points data based on mouse current position:\n\nchartEvents.chartMouseClick - mouse click inside chart boundary. Arguments - { x: number, y: number, selectedDate: Date, data: StackBarEventData[] }.\n\n#### Options\n\nName | Description | Type | Default\n--- | --- | --- | ---\nwidth | Chart total width | Number | 700\nheight | Chart total height | Number | 120\nmargin | Chart graph margin to outer bounds | { top: number, right: number, \nmarginBetweenStacks | Vertical margin between multiple stack bars | Number | 0\nbackgroundColor | Chart background color | String | '#CCCCCC'\nmaxTimeRangeDifferenceToDraw | Max time in milliseconds to treat dataset points without breaking | Number | 1000 * 60 * 60 * 24 * 1.5 (1.5 days)\nmouseMoveTimeTreshold | Minimum time in milliseconds between chartMouseMove events | Number | 20\nxAxisTimeFormat | Date tick format for chart X Axis | d3.tickFormat | undefined\nxAxisDateFrom | Chart X Axis start date | Date | undefined\nxAxisDateTo | Chart X Axis end date | Date | undefined\n\n### Plugins\n\n#### Vertical divider\n\nDisplay vertical line on chart.\n\n##### Usage\n\n```javascript\nconst lineChart = line({ height: 1000 });\n// create plugin\nconst verticalDividerPlugin = verticalDivider();\n// set divider height if chart height not default\nverticalDividerPlugin\n  .height(lineChart.chartHeight());\n// subscribe plugin to chart events\nlineChart\n  .on(chartEvents.chartMouseEnter, (x, y) =\u003e verticalDividerPlugin.show())\n  .on(chartEvents.chartMouseLeave, (x, y) =\u003e verticalDividerPlugin.remove())\n  .on(chartEvents.chartMouseMove, (options) =\u003e verticalDividerPlugin.update(options));\n// create line chart\nd3.select('.interpolated-chart').datum([/* chart data */]).call(lineChart);\n// select metadata container inside chart\nconst metadataContainer = d3.select('.interpolated-chart .metadata-container');\n// call plugin creation\nmetadataContainer.datum([]).call(verticalDividerPlugin);\n```\n\n##### CSS\n\nDivider line css class:\n\n.line-chart .divider\n\n##### Options\n\nName | Description | Type | Default\n--- | --- | --- | ---\nheight | Divider line height | Number | 440\n\n##### Methods\n\nName | Description | Arguments\n--- | --- | ---\nremove | Hide divider | None\nshow | Show divider | None\nupdate | Set divider position | { x: number }\n\n#### Markers\n\n##### Usage\n\n```javascript\n\nconst lineChart = line({ height: 1000 });\n// create plugin with options\nconst markersPlugin = markers()\n  .fill(data =\u003e {\n    return data.interpolatedValue \u003e 10 ? data.color : 'white'\n  });\n// set options\nmarkersPlugin\n  .radius(data =\u003e {\n    return data.interpolatedValue \u003e 10 ? 10 : 5\n  })\n// subscribe plugin to chart events\nlineChart\n  .on(chartEvents.chartMouseEnter, (x, y) =\u003e markersPlugin.show())\n  .on(chartEvents.chartMouseLeave, (x, y) =\u003e markersPlugin.remove())\n  .on(chartEvents.chartMouseMove, (options) =\u003e markersPlugin.update(options));\n// create line chart\nd3.select('.interpolated-chart').datum([/* chart data */]).call(lineChart);\n// select metadata container inside chart\nconst metadataContainer = d3.select('.interpolated-chart .metadata-container');\n// call plugin creation\nmetadataContainer.datum([]).call(markersPlugin);\n```\n\n##### Options\n\nName | Description | Type | Default\n--- | --- | --- | ---\ncx | Marker X position calculator | Function | data =\u003e data.interpolatedX || data.x\ncy | Marker Y position calculator | Function | data =\u003e data.interpolatedY || data.y\nradius | Marker radius calculator | Function | data =\u003e 5\nfill | Marker fill color calculator | Function | data =\u003e 'white'\nstroke | Marker stroke color calculator | Function | data =\u003e data.color || 'red'\nstrokeWidth | Marker stroke width calculator | Function | data =\u003e 2\nsort | Marker sorting function. First value will be displayed on top of others | Function | (a, b) =\u003e 0\n\n##### Methods\n\nName | Description | Arguments\n--- | --- | ---\nremove | Hide markers | None\nshow | Show markers | { data: ChartLinePointData[] }\n\n#### Tooltip\n\nTooltip - html foreignObject in svg chart.\n\n##### Usage\n\n```javascript\nconst lineChart = line({ height: 1000 });\n// create plugin with options\nconst verticalDividerPlugin = verticalDivider({ chartHeight: lineChart.chartheight() });\n// set options\ntooltipPlugin\n  .chartWidth(lineChart.chartWidth())\n  .valueFormatter(({ interpolatedValue }) =\u003e `${interpolatedValue.toFixed(1)}°C`);\n// subscribe plugin to chart events\nlineChart\n  .on(chartEvents.chartMouseEnter, (x, y) =\u003e tooltipPlugin.show())\n  .on(chartEvents.chartMouseLeave, (x, y) =\u003e tooltipPlugin.remove())\n  .on(chartEvents.chartMouseMove, (options) =\u003e tooltipPlugin.update(options));\n// create line chart\nd3.select('.interpolated-chart').datum([/* chart data */]).call(lineChart);\n// select metadata container inside chart\nconst metadataContainer = d3.select('.interpolated-chart .metadata-container');\n// call plugin creation\nmetadataContainer.datum([]).call(tooltipPlugin);\n```\n\n##### CSS\n\n.line-chart .tooltip\n\n.line-chart .tooltip rect\n\n.line-chart .tooltip .tooltip-container\n\n.line-chart .tooltip .tooltip-header\n\n.line-chart .tooltip .tooltip-header p\n\n.line-chart .tooltip .circle\n\n.line-chart .tooltip .topic\n\n.line-chart .tooltip .topic-name\n\n.line-chart .tooltip .topic-value\n\n##### Options\n\nName | Description | Type | Default\n--- | --- | --- | ---\nchartHeight | Chart height (used to compute tooltip boundaries) | Number | 440\nchartWidth | Chart width (used to compute tooltip boundaries) | Numner | 700\ntooltipWidth | Tooltip fixed width | Number | 220\nhorizontalMouseMargin | Tooltip horizontal distance from mouse pointer | Number | 40\nverticalBorderMargin | Tooltip min distance from chart top and bottom borders | Number | 10\nheaderFormatter | Tooltip header formatter function. Arguments - selected interpolated date and chart dataset values | Function | (selectedDate, data) =\u003e d3.timeFormat('%Y-%d-%m %H:%M:%S')(selectedDate)\ntopicFormatter | Tooltip path data description formatter | Function | (data) =\u003e data.name\nvalueFormatter | Tooltip path data value formatter | Function | (data) =\u003e d3.format('.1f')(data.interpolatedValue)\nsort | Tooltip path data sorting function. First value will be displayed on top of tooltip | Function | (a, b) =\u003e 0\n\n##### Methods\n\nName | Description | Arguments\n--- | --- | ---\nremove | Hide tooltip | None\nshow | Show tooltip | { x: number, y: number, selectedDate: Date, data: ChartLinePointData[] }\n\n## TODO\n\n- [x] Tests\n- [ ] JSDoc\n- [x] Documentation\n- [ ] Display curve single points in missing data range and add them to tooltip\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fz3ut%2Finterpolated-charts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fz3ut%2Finterpolated-charts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fz3ut%2Finterpolated-charts/lists"}