{"id":22012480,"url":"https://github.com/patmartin/dexjs","last_synced_at":"2025-05-06T21:43:19.775Z","repository":{"id":141670175,"uuid":"54803807","full_name":"PatMartin/dexjs","owner":"PatMartin","description":"A reusable component framework for visualization and data manipulation.","archived":false,"fork":false,"pushed_at":"2019-03-02T08:54:53.000Z","size":27983,"stargazers_count":19,"open_issues_count":2,"forks_count":8,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-03-31T03:13:06.739Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://dexjs.net","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PatMartin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-03-26T23:15:20.000Z","updated_at":"2021-12-23T12:18:34.000Z","dependencies_parsed_at":"2024-07-14T16:18:04.179Z","dependency_job_id":null,"html_url":"https://github.com/PatMartin/dexjs","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PatMartin%2Fdexjs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PatMartin%2Fdexjs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PatMartin%2Fdexjs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PatMartin%2Fdexjs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PatMartin","download_url":"https://codeload.github.com/PatMartin/dexjs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252776175,"owners_count":21802458,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-11-30T03:13:05.087Z","updated_at":"2025-05-06T21:43:19.762Z","avatar_url":"https://github.com/PatMartin.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Introduction\n\nDex.js is a javascript framework for visual components.  Dex.js is a child\nproject of Dex for the purpose of achieving visuals which were easily\nembedded in other javascript and non-javascript projects.\n\nDex.js takes many of the best open source visual frameworks and wraps them in a consistent\ninterface while also extending their capabilities and creating a way for them to\ncommunicate and interoperate with one another.\n\nAdditionally, dex.js offers powerful filters for sifting through the noise\nand gui controls for controling the finer details of how the data is presented.\n\n# Examples\n\n## C3\n\n\u003ca href=\"https://dexjs.net/examples/charts/c3/AreaChart.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/c3_area_chart.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/c3/BarChart.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/c3_bar_chart.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/c3/DonutChart.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/c3_donut_chart.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/c3/LineChart.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/c3_line_chart.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/c3/PieChart.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/c3_pie_chart.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/c3/ScatterPlot.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/c3_scatter_plot.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\n## D3\n\n\u003ca href=\"https://dexjs.net/examples/charts/d3/BumpChart.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/d3_bump_chart.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/d3/Chord.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/d3_chord.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/d3/ClusteredForce.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/d3_clustered_force.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/d3/Dendrogram.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/d3_dendrogram.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/d3/Map.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/d3_map.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/d3/MotionBarChart.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/d3_motion_bar_chart.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/d3/OrbitalLayout.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/d3_orbital_layout.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/d3/ParallelCoordinates.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/d3_parallel_coordinates.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/d3/RadarChart.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/d3_radar_chart.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/d3/RadialTree.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/d3_radial_tree.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/d3/Sankey.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/d3_sankey.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/d3/Sunburst.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/d3_sunburst.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/d3/Treemap.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/d3_treemap.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/d3/TreemapBarChart.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/d3_treemap_barchart.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\n## ECharts\n\n\u003ca href=\"https://dexjs.net/examples/charts/echarts/CircularNetwork.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/echarts_circular_network.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/echarts/ForceNetwork.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/echarts_force_network.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/echarts/HeatMap.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/echarts_heatmap.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/echarts/LineChart.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/echarts_linechart.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/echarts/PieChart.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/echarts_piechart.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/echarts/PolarPlot.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/echarts_polar_barchart.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/echarts/PolarPlot.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/echarts_polar_categorical_scatterplot.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/echarts/PolarPlot.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/echarts_polar_linechart.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/echarts/PolarPlot.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/echarts_polar_scatterplot.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/echarts/SteamGraph.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/echarts_steamgraph.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/echarts/Timeline.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/echarts_timeline.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\n## Miscellaneous\n\n\u003ca href=\"https://dexjs.net/examples/charts/d3plus/RingNetwork.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/d3plus_ring_network.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/elegans/ScatterPlot.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/elegans_scatter_plot.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/nvd3/BubbleChart.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/nvd3_bubble_chart.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/nvd3/StackedAreaChart.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/nvd3_stacked_area_chart.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\u003ca href=\"https://dexjs.net/examples/charts/visjs/Network.html\"\u003e\u003cimg src=\"https://github.com/PatMartin/dexjs-site/blob/master/static/images/charts/visjs_network.png?raw=true\" style=\"border: 0;\"\u003e\u003c/a\u003e\n\n# Tutorial\n\nThe best tutorials are probably the included examples.  However, here we will touch\non some of the high points of dex.js.\n\n## Data\n\nAll dex components operate upon a csv object. The csv object can be created a variety of ways.\nHere are a few:\n\n### Creating a CSV from local data\n\n#### From a local json object:\n\n```javascript\n// From JSON\nvar json = {\n  'header' : [ 'Name', 'Gender', 'Age' ],\n  'data'   : [[ 'Miles', 'M', 40 ],[ 'Jane', 'F', 34 ]]};\nvar csv = new dex.csv(json);\n```\n\n#### From local header and data arrays\n```javascript\nvar csv = new dex.csv(['Name', 'Gender', 'Age'],\n  [['Miles', 'M', 40],['Jane','F',34]]);\n```\n\n#### Create csv with header and load as we go:\n\n```javascript\nvar csv = new dex.csv(['Name', 'Gender', 'Age']);\ncsv.data.push(['Miles', 'M', 40]);\ncsv.data.push(['Jane','F',32]);\n```\n\n#### Create everything as we go:\n\n```javascript\nvar csv = new dex.csv();\ncsv.header = ['Name', 'Gender', 'Age'];\ncsv.data.push(['Miles', 'M', 40]);\ncsv.data.push(['Jane','F',32]);\n```\n\n### Acquiring data\n\nDue to the asynchronous nature of JavaScript, dex.js leverages bluebird\npromises in order to provide versatile ways for loading data.\n\n#### Reading from csv:\n\n```javascript\nvar dataPromise = dex.io.readCsv('/dexjs/data/io/presidents.csv')\n  .then(function(csv) { renderChart(csv)});\n\nfunction renderChart(csv) {\n  var chart = new dex.charts.d3.ParallelCoordinates({\n    parent: \"#Chart\",\n    csv: csv.include([\"Party\", \"Home State\", \"President\", \"Presidency\"])\n  }).render();\n}\n```\n\n#### Reading from a tsv file:\n\n```javascript\nvar dataPromise = dex.io.readTsv('/dexjs/data/io/presidents.tsv')\n  .then(function(csv) { renderChart(csv)});\n\nfunction renderChart(csv) {\n  var chart = new dex.charts.d3.ParallelCoordinates({\n    parent: \"#Chart\",\n    csv: csv.include([\"Party\", \"Home State\", \"President\", \"Presidency\"])\n  }).render();\n}\n```\n\n#### Reading from an XML file:\n\nReading from an xml file is a bit different.  Each column must be\nexpressed as it's own xpath expression.  This allows us a great deal\nof flexibility.\n\nWe can read an xml of the form:\n\n```xml\n\u003ccsv\u003e\n  \u003crow\u003e\u003cfirstName\u003ejoe\u003c/firstName\u003e\u003cage\u003e22\u003c/age\u003e\u003c/row\u003e\n  \u003crow\u003e\u003cfirstName\u003ejim\u003c/firstName\u003e\u003cage\u003e33\u003c/age\u003e\u003c/row\u003e\n  \u003crow\u003e\u003cfirstName\u003esue\u003c/firstName\u003e\u003cage\u003e44\u003c/age\u003e\u003c/row\u003e\n\u003c/csv\u003e\n```\n\nvia:\n\n```javascript\nvar dataPromise = dex.io.readXml('/dexjs/data/io/people.xml')\n  .then(function (csv) {\n    renderChart(csv)\n  });\n```\n\nGiven an xml files in alternate forms, we can supply an apprpriate transform:\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003cdata\u003e\n    \u003cletter id=\"A\"\u003e\u003cfrequency\u003e.08167\u003c/frequency\u003e\u003c/letter\u003e\n    \u003cletter id=\"B\"\u003e\u003cfrequency\u003e.01492\u003c/frequency\u003e\u003c/letter\u003e\n    ...\n    \u003cletter id=\"Y\"\u003e\u003cfrequency\u003e.01974\u003c/frequency\u003e\u003c/letter\u003e\n    \u003cletter id=\"Z\"\u003e\u003cfrequency\u003e.00074\u003c/frequency\u003e\u003c/letter\u003e\n\u003c/data\u003e\n```\n\nThe following will create a csv with columns 'letter' and 'frequency':\n\n```javascript\n  var xpaths = {\n    letter: \"//letter/@id\",\n    frequency: \"//frequency\"\n  };\n\n  var dataPromise = dex.io.readXml('/dexjs/data/io/letterFrequency.xml',\n    dex.io.transform.xml.xpath({letter:\"//letter/@id\",frequency:\"//frequency\"})\n    .then(function (csv) {\n      renderChart(csv)\n    });\n```\n\n#### Reading from JSON files:\n\nMost often, we will want to read in data from JSON files and RESTful services.\nBy default, we accept json files which are arrays of shallow name value pairs\nsuch as:\n\n```javascript\n[\n  { name: \"jack\", age: 100 },\n  { name: \"jill\", age: 99 }\n]\n```\n\nHere we call a RESTful service which already returns data in the expected name/value pair form:\n\n```javascript\n  var dataPromise = dex.io.readJson('https://jsonplaceholder.typicode.com/todos')\n    .then(function (csv) {\n      renderChart(csv)\n    });\n\n  function renderChart(csv) {\n    dex.charts.d3.ParallelCoordinates({\n      parent: \"#Chart\",\n      csv: csv\n    }).render();\n  }\n```\n\nHere is a slightly more complex example where we must supply a custom\ntransformation in order to map the json into the form we require:\n\n```javascript\n  function transform(json) {\n    var transformed = [];\n    for (key in json.bpi)\n    {\n      var row = json.bpi[key];\n      row.currency = key;\n      transformed.push(row);\n    }\n    return new dex.csv(transformed);\n  }\n\n  var dataPromise = dex.io.readJson(\n    'https://api.coindesk.com/v1/bpi/currentprice.json', transform)\n    .then(function (csv) {\n      renderChart(csv)\n    });\n\n  function renderChart(csv) {\n    dex.charts.d3.ParallelCoordinates({\n      parent: \"#Chart\",\n      csv: csv\n    }).render();\n  }\n```\n\n## Visualizing the data\n\nNow lets talk about data visualization.  We first start off by supplying a\ntarget div container for our chart.\n\n```html\n  \u003cdiv id='Chart'\u003e\u003c/div\u003e\n```\n\nFrom there, we can visualize the data in a number of interesting ways such as\nparallel coordinates:\n\n```javascript\nvar chart = new dex.charts.d3.ParallelCoordinates({\n  parent: '#Chart',\n  csv: csv});\n```\n\nor via a tree (aka dendrogram):\n\n```javascript\nvar chart = new dex.charts.d3.Dendrogram({\n  parent: '#Chart',\n  csv: csv});\n```\n\nor a scatterplot:\n\n```javascript\nvar chart = new dex.charts.c3.Scatterplot({\n  parent: '#Chart',\n  csv: csv});\n```\n\nBy now I hope you've noticed that the interfaces between different visuals\nis quite consistent.\n\n## UI Components\n\n### Configuration Pane\n\nThe configuration pane is a special component which provides to main sections:\n\n\u003ca href=\"https://dexjs.net/examples/ui/ConfigurationPane.html\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/PatMartin/dexjs-site/master/static/images/ui/config_pane.png?raw=true\"\u003e\u003c/a\u003e\n\n* A data pane for ordering and filtering the data\n* A GUI pane for controlling the presentation of the visual.\n\n### Data Player\n\ndex.js offers the capability for dividing a dataset into frames via a sequence value and\ncombining any of the other charts via chart interaction in order to turn the data into\nan interactive movie of sorts.\n\n## Chart interaction\n\nCharts can listen and react to each other.  They do so via a publish subscribe\nmodel.  In dex.js, components communicate interesting changes via a publish operation.\nFor example, a data-filter component may communicate that the user has filtered\nout all data outside of a certain range.  Other charts and components may in turn\nlisten for these types of changes via subscribing and receiving and reacting\nto these changes in realtime.\n\n### Chart Interaction Example\n\nLet's assume that we have a US map component that allows the user to select\nindividual states and a grid component which wants to do something with that\ninformation.\n\n```javascript\n  var pcChart = new dex.charts.d3.ParallelCoordinates({\n      'parent': \"#ParallelCoordinates\",\n      'margin': {'top': 40, 'bottom': 30, 'left': 50, 'right': 50},\n      'csv': csv\n    }\n  );\n\n  // Configure a chart.\n  var chord = dex.charts.d3.Chord({\n      'parent': '#Chord',\n      'margin': {'top': 10, 'bottom': 20, 'left': 10, 'right': 10},\n      'csv': csv\n    }\n  );\n\n  chord.subscribe(pcChart, \"select\", function (msg) {\n    // Set the csv data of the chord diagram to the contents of\n    // the selected data from the Parallel Coordinates diagram.\n    chord.attr('csv', msg.selected).update();\n  });\n\n  pcChart.render();\n  chord.render();\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpatmartin%2Fdexjs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpatmartin%2Fdexjs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpatmartin%2Fdexjs/lists"}