Coder Social home page Coder Social logo

syntagmatic / parallel-coordinates Goto Github PK

View Code? Open in Web Editor NEW
511.0 47.0 212.0 3.25 MB

A d3-based parallel coordinates plot in canvas. This library is no longer actively developed.

Home Page: http://syntagmatic.github.com/parallel-coordinates/

License: Other

CSS 0.89% HTML 14.33% JavaScript 84.47% Makefile 0.31%

parallel-coordinates's Introduction

Parallel Coordinates

CDNJS

An implementation of parallel coordinates in d3 as a reusable chart

This library is under only sporadic development by contributors using an outdated version of d3. Consider using this d3.v5 ES6 port by BigFatDog for a more modern approach.

Contributing

In order to obtain a linear history, please adhere to the workflow outlined by @bbroeksema.

Resources

Tutorials

Papers

Books

Videos

Software

API

# d3.parcoords(config)

Setup a new parallel coordinates chart.

# parcoords(selector)

Create the chart within a container. The selector can also be a d3 selection.

# parcoords.animationTime(milliseconds = 1100)

Allows you to set the time it takes for flipping an axis on double click.

// Flipping an axis will take half a second
parcoords.animationTime(500);

# parcoords.data([values])

Add data to the chart by passing in an array of values.

A single value may be either an object or an array. All values should be the same format.

// objects
var foods = [
  {name: "Asparagus", protein: 2.2, calcium: 0.024, sodium: 0.002},
  {name: "Butter", protein: 0.85, calcium: 0.024, sodium: 0.714},
  {name: "Coffeecake", protein: 6.8, calcium: 0.054, sodium: 0.351},
  {name: "Pork", protein: 28.5, calcium: 0.016, sodium: 0.056},
  {name: "Provolone", protein: 25.58, calcium: 0.756, sodium: 0.876}
];

// arrays
var cube = [
  [0, 0, 0],
  [1, 0, 0],
  [0, 1, 0],
  [1, 1, 0],
  [0, 0, 1],
  [1, 0, 1],
  [0, 1, 1],
  [1, 1, 1]
];

# parcoords.render()

Renders the polylines.

If no dimensions have been specified, it will attempt to detect quantitative dimensions based on the first data entry. If scales haven't been set, it will autoscale based on the extent for each dimension.

# parcoords.rotateLabels(enabled = false)

Whether scrolling on top of a label should result in the labels rotating.

# parcoords.dimensions(dimensions)

If dimensions is specified, sets the quantitative dimensions to be visualized and custom formatting. The format is an object of dimension objects. This will update the xscale domain, but will not trigger re-rendering of lines or axes.

var dimensions = {
	"name":
		{
			orient: 'right',
			type: 'string',
			tickPadding: 0,
			innerTickSize: 8
		},
	"protein": {type:"number"},
	"calcium": {type:"number"}};

If no dimensions are specified, then it returns the currently set dimensions.

Dimension attributes include:

"title": String label for dimension
"type": Possible values include: string, date and number. Detected types are automatically populated by detectDimensions using d3.parcoords.detectDimensionTypes.
"ticks": Number of horizontal ticks to include on y axis
"tickValues": Array of values to display for tick labels
"orient": Orientation of ticks and tickValues(left or right of axis)
"innerTickSize": Length of the horizontal ticks in between the top and bottom
"outerTickSize": Length of the horizontal ticks at the top and bottom
"tickPadding": Pixels to pad the tick title from the innerTickSize
"yscale": Type of scale to use for the axis(log, linear, ordinal). Reference D3 Scales "index": Integer position for ordering dimensions on the x axis

# parcoords.smoothness(double)

If double exists, polylines will be rendered with specified amount of curvature. NOTE: sylvester.js is a necessary dependency for this feature.

parcoords.smoothness(.2);

# parcoords.color(color)

If a color is a string, polylines will be rendered as that color. If color is a function, that function will be run for each data element and the polyline color will be the return value.

To set all lines to a transparent green:

parcoords.color("rgba(0,200,0,0.3)");

Function example

parcoords.color(function(d) {
    // d corresponds to the individual data object
    if (d.x < 100)
        return "red";
    else
        return "green";
});

If no color is specified, then it returns the currently set color.

# parcoords.flipAxes()

Allows you to flip axes without animation.

parcoords.flipAxes(["x", "y"]);

# parcoords.state()

Returns an object which contains the state of the chart. This is particularly useful for debugging with a JavaScript console.

# parcoords.state

Exposes the public state of parallel coordinates. Useful for debugging in a JavaScript console. Avoid modifying values directly, instead use methods such as parcoords.data() to update the state.

The design of this object is experimental and contributed by Ziggy Jonsson. Read more at this d3-js mailing list discussion.

When the public state is updated through a method, an event will fire.

# parcoords.createAxes()

Create static SVG axes with dimension names, ticks, and labels.

# parcoords.removeAxes()

Remove SVG axes.

# parcoords.updateAxes()

Update SVG axes. Call this after updating the dimension order.

# parcoords.brushMode(mode)

1D-axes
1D-axes-multi
2D-strums
angular

# parcoords.brushed()

For brushable plots, returns the selected data.

# parcoords.brushReset()

Reset all brushes.

# parcoords brushedColor()

Change coloring of brushed items. The default behavior is that brushed items get the original coloring. The example below will make all brushed items black.

parcoords.brushedColor("#000");

# parcoords alphaOnBrushed()

Change the alpha of the layer between the foreground and brushed items. This value defaults to 0, making the foreground invisible when items are brushed. Increasing the alpha value will result in a shadows effect, where the foreground items are increasingly more visible when alpha increases. Combined with brushedColor various highlight effects can be achieved on brushing.

// default behavior: brushed items are colored the same as foreground items,
// forground items are invisible.

// Add shadows: Brushed items are colored the same as foreground items, forground
// items are vaguely visible. Same effect is achieved by parcoords.shadows()
parcoords.alphaOnBrushed(0.1);

// Highlight brushed items with a different color. Foreground items are fully
// visibible, except those who are covered by brushed items.
parcoords
  .alphaOnBrushed(1)
  .brushedColor("#000");

# parcoords.reorderable()

Enable reordering of axes. Automatically creates axes if they don't exist.

The behavior is identical to that of the original reorderable d3.js parallel coordinates.

# parcoords.axisDots(size = 0.1)

Mark the points where polylines meet an axis with dots of radius size.

# parcoords.shadows()

Active greyed-out background shadows. See brushedColor and alphaOnBrushed

# parcoords.width()

parcoords.width(300)

# parcoords.height()

parcoords.height(300)

# parcoords.margin()

parcoords.margin({
  top: 100,
  left: 0,
  right: 0,
  bottom: 20
})

# parcoords.composite()

Change foreground context's globalCompositeOperation

  • source-over
  • source-in
  • source-out
  • source-atop
  • destination-over
  • destination-in
  • destination-out
  • destination-atop
  • lighter
  • darker
  • xor
  • copy

# parcoords.alpha()

Change the opacity of the polylines, also the foreground context's globalAlpha.

# parcoords.autoscale()

Set the xscale, yscale, and canvas sizes. Usually this is called automatically, such as on render() or resize() events

# parcoords.mode(type)

Toggle the rendering mode. Currently there are two options:

  • "default" renders instantaneously, but is less responsive with more than ~2000 rows of data
  • "queue" puts the data in a queue, and renders progressively. This way the user can interact with the chart during rendering.

# parcoords.rate(integer)

Change the number of lines drawn each frame when the rendering mode is set to "queue". Some suggested values for different machines are:

  • Mobile phone or iPad: 12-30
  • Normal PC with Firefox: 20-60
  • Normal PC with Chrome/Safari: 30-100
  • Fast PC with Chrome/Safari: 100-300

In the future, an automatic rate adjuster will be included to optimize this number on-the-fly.

# parcoords.detectDimensions()

Set the quantative dimensions using based on the first row of data.

# parcoords.highlight([values])

Pass an array of data to overlay the data on the chart, masking the foreground.

# parcoords.unhighlight([values])

Clear the highlighting layer. This is equivalent to calling parcoords.clear("highlight").

# parcoords.interactive()

Activate interactive mode for use with a JavaScript console. The concept is that for each method that modifies a chart, everything that needs to happen to update the rendered chart will run automatically.

Currently this only affects adding/removing/reordering dimensions. Normally the chart must be re-rendered and axes updated:

parcoords.dimensions([3,1,2])
  .render()
  .updateAxes()

In interactive mode, just specify the new dimensions array.

parcoords.dimensions([3,1,2])

# parcoords.clear(layer)

Clear the layer, which could be "foreground", "shadows", "marks", "extents" or "highlight".

# parcoords.canvas

An object containing the canvas elements.

# parcoords.ctx

An object containing the canvas 2d rendering contexts. Use this to modify canvas rendering styles, except for the foreground stroke which is controlled by parcoords.color().

# parcoords.on(event, listener)

Trigger a listener when an event fires. The value of this in the listener refers to parcoords. The data passed into the listener depends on type of event:

  • "render" returns no data
  • "resize" returns an object containing the width, height and margin
  • "highlight" returns the highlighted data
  • "brush" returns the brushed data

When values in the state are updated through methods, an event of the same name fires (except height, width and margin which fire resize). The data passed into the listener is an object containing the new value, value, and the old value, previous.

Custom values must be passed into the original chart config to register events.

  • "dimensions"
  • "data"
  • "color"
  • "composite"
  • "alpha"

Axes

Todo Axis configuration

Developing

The 'examples' directory contain a number of examples that demonstrate the various function of d3.parcoords.js. If you make any chances make sure to verify that these examples still work as expected.

Build

make runs the Makefile to concatenate d3.parcoords.js. This needs to be done after each modification to files in the src/ directory.

Test framework

Recently (as of Oct. 2014), we started to implement a vows-based test suite to more rigorously and in a more automated way, test the functionality of d3.parcoords.js. The test suite itself can be found under tests/.

To run the tests you'll need some initial setup. First, you'll need to have nodejs and npm installed. Next, to run the tests, first run:

$ npm install

** NOTE: *** The node canvas package, which is a requirement, might need some additional software to be installed. Please refer to this page for further instructions.

Now you should be able to run the test suite:

$ make test

Credits

This library created with examples, suggestions and contributions from Mike Bostock, Jason Davies, Mary Becica, Stephen Boak, Ziggy Jonsson, Ger Hobbelt, Johan Sundström, Raffael Marty, Hugo Lopez, Bob Monteverde, Vadim Ogievetsky, Chris Rich, Patrick Martin, Sean Parmelee, Alfred Inselberg, Scott Markwell, Julian Heinrich, and Bertjan Broeksema.

parallel-coordinates's People

Contributors

ajo2995 avatar andrer0cha avatar aravindgear4 avatar auxiliary avatar bbroeksema avatar brohammie avatar brycecr avatar dehli avatar dependabot[bot] avatar duaneatat avatar extend1994 avatar git-me-outta-here avatar iwfy avatar jmgelman avatar julianheinrich avatar kpwhiver avatar lukaw3d avatar m1neral avatar mbecica avatar sbryfcz avatar seanparmelee avatar shodanjr avatar smarkwell avatar smoitra-g avatar syntagmatic avatar targos avatar timelyportfolio avatar zuchaowang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

parallel-coordinates's Issues

Total for some data enhancement

I have also added another improvement in my test case: add total for highlighted/filtered values for some axis.
The code is something like:
// define axis for which we want total
var col_total = { "Total Cores":true, "Rmax":true, "Power": true } ;
...
axis.append("svg:text")
.attr("class", "title")
.attr("text-anchor", "middle")
.attr("y", -15)
.text(String) ;
axis.append("svg:text")
.attr("class", "title total")
.attr("text-anchor", "middle")
.attr("y", -5)
.each(function(p) { if (!col_total[p]) {
d3.select(this).style("visibility", "hidden") ;
} else {
d3.select(this).text (d3.sum (commande.map(function (d,i) {return +commande[i][p]})).toFixed(0)) ;
}});
...
totaux_labels = svg.selectAll(".total") ;
...
for instance, in brush:
foreground.classed("active", function(d) {
...
}
update_totaux ("active") ;
...

function update_totaux (classe)
{
// compute total for foreground elements with class "classe" set
var totaux = {} ;
d3.keys(col_total).forEach (function (p) {totaux[p]= +0; }) ;
foreground.each (function (p) { if (d3.select(this).classed(classe)) {
d3.keys(col_total).forEach (function (d) {totaux[d]+= +p[d]; }) ;
}} ) ;
totaux_labels.text (function (p) {if (totaux[p]) {return totaux[p].toFixed(0) ;} else return "";}) ;
}

You can see my test case at: http://nitisco.fr/top500/
I am not happy with that, because of bad performance. This is why I limited to 30 values only...
With parcoord.js, performances will be much better. I will loose mouseover effect but this is not interesting with a lot of values. And with your slickgrid example, we can highlight a value from the table, which is interesting.

Minimal alpha value

I'm trying out the "Upload CSV" example and want to visualize a set of more than 10'000 items. For patterns to be visible, the alpha value needs to be extremely small. I thus reset it using

parcoords.color("rgba(0,200,0,0.02)");

This still renders correctly. Setting the alpha value to 0.01, though, does render the lines "invisible".

parcoords.color("rgba(0,200,0,0.01)");

Something between 0.01 and 0.02 still works - but it appears that there is a minimal alpha value that can possibly be rendered.

I tried this in the latest version of Google Chrome.

Adding Tests

Any interest in adding tests? D3 uses Vows, but I'm open to any testing framework.

Changing data with active brushes

Calling data(newData) while there are brushes on the cart causes lines from the old data that were bound by the brushes to stay visible until you clear the brushes. What it should do is reapply the brush extents to the new data. Say for example you want to allow the user to filter the data in other ways than the brushes, but want the brushes they have set to remain active. They would expect the brushes to "release" the old data and apply to the new data only.

Sets in Parallel Coordinates

Hello guys i need help .
i need to have parallel coordinates with category values. to have a Vertical parallel sets.

underscore dependency in hideaxis

the hideAxis side effect code has a hard-to-spot dependency on the underscore library, as underscore uses a single underscore as its object whereas the base object in the parallel coordinates code uses a double underscore ('__')

fix:

 .on("hideAxis", function(d) {
      //pc.dimensions(_.without(__.dimensions, d.value));   // needs underscore
      pc.dimensions(__.dimensions.filter (
          function(elem) { return d.value.indexOf(elem) === -1; })
      );
  });

Smash dependencies

D3.js uses import statements and mbostock's smash to combine them.

Perhaps we should use that? Possibly we could provide an option to smash d3.parcoords.js with d3, and separate render-queue into a totally separate module.

https://github.com/mbostock/smash/wiki

Line width based on number of isolated rows

I'm rendering a lot of data with parcoords, and when I first load the file, I have the alpha at a low number so that it doesn't look like a big chunky mess. Then, when I go to brush the ranges, the number of lines reduce and the low alpha makes them difficult to differentiate between the isolated lines and those outside of the selected domains.

So here's the question: Is there an easy way to have either the stroke-width or the opacity of the lines to be a function of the number of lines isolated by the domains?

Automatic axis type detection enhancement

Many thanks for your excellent work.
I have tried d3.js for parallel coordinates with the help of jasondavies examples.
I have improved it with automatic data type detection: numeric, string or date.
I have something like that in my code:

  var col_string = {  } ; // you can force string type for some data
  var col_date = { } ; // you can force date type for some data
  var format_date = "%d/%m/%Y" ; // Cf d3.time.format 
  // and for automatic detection
  var exp_date = /^(\d){1,2}\/(\d){1,2}\/(\d){4}$/

...

  d3.csv("...csv", function(commande) {
    // Extract the list of dimensions
    // For each dimension, guess if numeric value or not and create vert scales
    all_dims = d3.keys(commande[0]) ;
    // Filter hidden dimensions
    dimensions = d3.keys(commande[0]).filter(function(key) {
      // guess if string values
    if (!col_string[key]) col_string[key] = commande.map(function(p){return p[key];}).some(function(p){return isNaN(p);})
       // guess if date values 
      if (!col_date[key])       {
        if ((col_string[key]) && (commande.map(function(p){return p[key];}).every(function(p){return (p.match (exp_date));})))
  { 
  col_date[key] = true ; 
  col_string[key] = false ;
  // convert in date format
  commande.forEach (function(p) {p[key] = d3_format_date.parse (p[key]);}) ;  
  }
} 

And after, I create the appropriate axis

      // if string data: ordinal scale
      if (col_string[key]) {
  return (vert_scales[key] = d3.scale.ordinal() .domain(commande.map(function(p) { return p[key]; }).sort()).rangePoints([h, 0],1));} 
     // else, scale linear 
else {
var interval ;
if (intervals[key])  interval = intervals[key] ;
else
{ 
 interval = d3.extent(commande, function(p) { return +p[key]; }); 
   // add padding (5%)
   var padding = (interval[1]- interval[0])*0.05 ; 
  interval[0] =  interval[0] - padding ;
   interval[1] =  interval[1] + padding ;
if (col_date[key])  return (vert_scales[key] = d3.time.scale().domain(interval) .range([h, 0]));
      else return (vert_scales[key] = d3.scale.linear().domain(interval).range([h,0]));
} });

I also specify the date format for the date axis (could be configurable):

    var axis = g.append("svg:g") 
     .attr("class", function(d) { return col_string[d] ? "axis label" : "axis";})
    .each(function(d)
      {                                                                                                                                                        
         if (col_date[d]) d3.select(this).call(axis.scale(vert_scales[d]).tickFormat(d3.time.format("%m/%y")));
          else d3.select(this).call(axis.scale(vert_scales[d]));}) ;

...

This allows me to add special features for ordinal axis: when I mouse over a label, I highlight all lines which have this value.

Finally, for brush extents:

    var extents = actives.map(function(p) { return vert_scales[p].brush.extent(); });
foreground.classed("active", function(d) {
return actives.every(function(p, i) {
  var val ;
  // string type
  if (col_string[p])   val = vert_scales[p](d[p]) ;
 // numeric axis
else  val = d[p]  ; 
 return extents[i][0] <= val && val <= extents[i][1]; 
    }) ;
 });                                                                                                                                                                            

With that, brushes are well managed either for numeric, string and date axis

Do you think that such features could be integrated in d3.parcoords.js?

Long label names in the left most dimension

I am running into a problem where the label on the scales in the left most dimension are getting cut off. IS there a way to get the chart to take into account the length of the label when it draws?
capture

also because the labels are longer on the left side it makes the chart look unbalanced, like I need to add padding to the left side. Can I re-center the chart taking into account the labels?

Canvas to SVG

Is there a quick way to convert parcoords to svg format? I'm trying to download parallel coordinates as an svg using SVG Crowbar. I'm not familiar with canvas, but downloading a vector file help with post work for publication.

repo clean-up

I'd like to propose some clean up of the code base:

  • The lib and data directories are both only required for the examples. As such I'd like to propose to move them into the examples directory and fix the examples accordingly.
  • There is no reason why d3 should be a git submodule. I think we could go with adding it the same way like all other dependencies for the examples: add d3.min.js to examples/lib (assuming lib moves down there).
  • The scratch directory seems to be an old left-over. I'd like to propose to remove it.

Any thoughts, comments? I can do the required work if you aggree.

Conflict

Looks like on line 728-735 you committed an unresolved conflict:

<<<<<<< HEAD
  if (actives.length === 0) return false;
=======
  //if (actives.length === 0) return false;

  // Resolves broken examples for now. They expect to get the full dataset back from empty brushes
  if (actives.length === 0) return __.data;
>>>>>>> gh-pages

Don't render unnecessarily on axis drag

For discussion: I think it would help perceived performance when we don't render the pc on drag. That is, we only trigger a render when the order of the axis has actually changed.

Now, I see that re-render on drag could be used to temporarily stretch the area between two axes to gain more space for the patterns in between them. However, I doubt if this is the most fruitful approach and worth the constant redrawing each time the axis moves.

As an in-between solution we could trigger the render when there is no axis movement for a given amount of time (e.g. one second).

Reasoning: I'm working mainly with large(ish) data sets (~40.000 items), and constant re-rendering during interaction is, well annoying. I'm open for discussion though for alternative approaches.

Curtailing Long Strings or Numbers on Ticks

Hi Kai and D3 Parcoords Community,

Thanks so much for providing all of your parallel coordinates code online - I've found it to be a tremendously valuable resource for visualizing various data sets. One issue that I have run across is not being able to read long strings of text or numbers, as they tend to overlap those of other axes (changing the height and width of the visualization isn't always the most visually attractive solution with these long strings or numbers).

parcoords problems

One feature I am trying to add is the ability to curtail the contents of the text elements that are rendered, while not changing the underlying data driving the visualization. A problem that I see with changing the underlying data is the erroneous consolidation of similar but distinct long strings and numbers (i.e. "supercalifragilisticexpialidocious_A" -> "supercalifragilisticexpial..." and "supercalifragilisticexpialidocious_B" -> "supercalifragilisticexpial...", making the visualization consolidate parcoords lines to just one tick mark where there should be two).

I wrote a function like the one below to append your library and accomplish this goal for axis headers:

function curtailText(text){
if(text.length >= 33){
text = text.substring(0,30) + "...";
}
return text;
};

However, I was not able to identify code in your library that is driving the generation of html text elements on ticks. Could you please help to point me in the right direction?

With much appreciation,
Stephen

.filter()

A function which filters the dataset prior to brushes.

Only the filtered dataset would appear on the background.

parcoords.brushedOut?

This may be a dumb question: The parcoords.brushed() is really helpful for finding the isolated data when brushing. Is there a single line of text to show the removed data? parcoords.shadowed() for example?

Example With Slickgrid Has Issue With Graph Highlighting Code

The following example has bad logic for highlighting the graph.

http://syntagmatic.github.io/parallel-coordinates/examples/slickgrid.html

The code works fine if you never toggle the pager and select 'Auto'. When toggled to 'Auto' and your results span multiple pages, you'll always return the id for the row you're highlighting, rows 0-10 in your example, not the actual array position of the item in your dataset. So page 1 works fine, but when you get to page 2 and beyond, you will always highlight the items 0-10 in the dataset even though you're looking at items further down the dataset.

This code block is flawed with the pager set to 'Auto'.

// highlight row in chart
  grid.onMouseEnter.subscribe(function(e,args) {
    var i = grid.getCellFromEvent(e).row;
    var d = parcoords.brushed() || data;
    parcoords.highlight([d[i]]);
  });

This updated code block should fix it. We want to get the number of the row from the grid, use that to get the id from the object, find that item id in the array and return its position. We now have the right element to highlight in the data array.

// highlight row in chart
  grid.onMouseEnter.subscribe(function(e,args) {
    // Get row number from grid
    var grid_row = grid.getCellFromEvent(e).row;

    // Get the id of the item referenced in grid_row
    var item_id = grid.getDataItem(grid_row).id;
    var d = pc1.brushed() || data;

    // Get the element position of the id in the data object
    elementPos = d.map(function(x) {return x.id; }).indexOf(item_id);  

    // Highlight that element in the parallel coordinates graph
    parcoords.highlight([d[elementPos]]);  
  });

Parcoords.color

I'm trying to update the parcoords.color() in a session using the code below. I'm getting a strange result: the script is activated with a button click, yet the color does not change unless I click the button twice. Could this be an issue in the library?

var parcolor=function(d) {
return colorScale(d[curCol[0]]);} ;
parcoords.color(parcolor);

How to set scale tick values of each dimension?

This is a usage question, not a bug. If there is a more appropriate place for me to submit this, please let me know.

Given the following data, which represents results of demographic queries against a point located in a US Census block, I can graph the data as one parallel coordinate set, but it appears as a flat line with not tick values on the graph. This does not happen if I have multiple rows of results, which as I understand is because something autoscales the min/max values of ticks for each dimension. How can I manually set a range of min/max values for each axis? Many thanks for any advice on this.

Here is an example of what I want to plot, a set of key/values in an array (resultsArr):

[{"POPGRWCYFY":0.24,"AVGHHSZ10":2.64,"TOTPOP_CY":1237,"FEMALES_CY":691,"PFEMALE_CY":55.9,"MALES_CY":546,"PMALE_CY":44.1,"MEDAGE_CY":30.3}]

The parallel coordinates then loads it like this:

var pc = d3.parcoords()("#paraCoordsDiv")
                    .data(resultsArr)
                    .alpha(0.4)
                    .render()
                    .ticks(20)
                    .createAxes();

For the one row (one object) plot, it appears like this screenshot:

pc_single_feature

I'd like to have scale tick values similar to what gets presented when there is more than one object plotted, like this screenshot:

pc_multiple_features

Many thanks.

default is a reserved keyword

in /src/render.js line 284.
This shows as syntax errors in eclipse and stops the minifier from processing d3.parcoords.js

Can be fixed by using pc.render["default"] = function() { instead of pc.render.default = function() {

Rescale axes

I'm trying to rescale the axes after changing the data and would like to do so without rebuilding the whole chart or axes (mainly, because I've added a few customizations to the axes after they're built). updateAxes() doesn't seem to do the trick, at least not on its own. Even calling createAxes() does rescale them as I expected, so I except that simply changing the data isn't sufficient to rescale the underlying dimensions. How would I go about doing this? Basically I'm trying to emulate the "keep" and "remove" behavior you implemented (here)[http://exposedata.com/parallel/] with this library.

add coordinates to the brush box

Hi Kai,

Thanks for your great work! I am wondering is there an each way to add the coordinate text to the brush box, so that when I brush I will know exactly what is the range of the coordinates I am choosing?

Thanks,

Yan

Multiple vertical selections on brushing

Thanks for the great library. One enhancement I'd like is the ability for adding multiple regions for brushing on the same axis. Possibly by using a meta key (ALT/Command ?) to indicate to add to the brush selection instead of removing the existing one.

Need a little help here

I'm new to here so be gentle if I am supposed to know more...

I downloaded all the files, and import them in aptana.
end.js, render.js, d3.parcoords.js throw out errors. two of them are about
pc.render.default = function() {
error msg is unexpected token "default"
first time I removed the function and run the htmls in example, didn't work.
second time I ignored the error and run htmls, still don't work.

please give a hello world example so that I can gradually learn to use this.
Thanks.

Intersection Brushing

Select lines by drawing an intersecting line anywhere between the axes, rather than on the axes themselves.

The intersection tests may need to follow the render-queue pattern to prevent slowing down interactions on large-ish datasets.

http://bl.ocks.org/syntagmatic/5441022

render timer and onDrag event...

Hello. Currently I'm build parcoord in our project (pSeven). I want to suggest fix two small but very ugly features.
First: render timer (in queue render mode) is incapsulate in parcoord and I haven't access to it. As a result when the window with parcoord is closing I can't stop it.
Second: I was not found any event which happen when the user change order of axes in draggable state of parcoord. At now we just test order of axes each two seconds.
P.C. You create nice library. Thanks for that.

Resize events

Emit an event when the container has been resized

Custom Axis Datatypes

The data that I am loading contains IP addresses formatted as such: 192.168.1.1. Using sample code from your veterans example I was able to get all of my data loaded into the slickgrid component however it is never rendered in the parallel coordinate.

I have done some investigation and it appears the autoscale function detects it as a string and gives it an ordinal axis. I added code to autoscale function that checks for my special case, converts the IP address into a decimal and then creates a special linear axis for it. This plots successfully (other than a decimal label value that has no meaning) but I lose all brushing capability on that axis.

How would you go about plotting a series of IP addresses on a parallel coordinate with parcoords.js?

Fixed scale dimension

Hi, many compliments for the library 👍

maybe i´m wrong, but i´m not able to find a way to fix the dimensions manually;

say that I have 3 axes (indeed 3 Dimensions) and I want that every of them has the min and max value from the bigger and the smaller of the 3:
for instance
Dimension1) Min 10 max 100
Dimension2) Min -10 max 1000
Dimension3) Min -100 max 10
I would like that every axes has -100 and 1000 as extremes

there´s a way to do that?

many thanks

Landscape to Portrait Mode

Just delving into parcoords and it's really impressive! Any chance the library can switch from a horizontal layout to a vertical one?

DateTime dimension support

Hi, just add DateTime dimension support , but not knowing how to send them. So I put them here:
In lastest version, add following code to pc.autoscale -> defaultScales
"date":function(k) {
return d3.time.scale()
.domain(d3.extent(__.data, function(d) {
if(d[k])return d[k].getTime();
else return 0;
}))
.range([h()+1, 1])
}
And add these to selected() -> within
"date": function(d,p,dimension) {
return extents[dimension][0] <= d[p] && d[p] <= extents[dimension][1]
}
I have tested these codes in veterans.html example.

setting dimension titles manually

I added a small feature to set the dimension titles manually (currently when using dimensions() with an array containing strings an error is received)

there are 4 new/modified lines (marked with '<== NEW' or '<== MOD')

d3.parcoords = function(config) {

  var __ = {
    data: [],
    dimensions: [],
    dimensionTitles: [],  //<== NEW
    types: {},
    brushed: false,
    mode: "default",
    rate: 10,
    width: 600,
    height: 300,
    margin: { top: 24, right: 0, bottom: 12, left: 0 },
    color: "#069",
    composite: "source-over",
    alpha: "0.7"
  };

.
.
.
pc.createAxes = function() {
    if (g) pc.removeAxes(); 

    // Add a group element for each dimension.
    g = pc.svg.selectAll(".dimension")
        .data(__.dimensions, function(d) { return d; })
      .enter().append("svg:g")
        .attr("class", "dimension")
        .attr("transform", function(d) { return "translate(" + xscale(d) + ")"; })

    // Add an axis and title.
    g.append("svg:g")
        .attr("class", "axis")
        .attr("transform", "translate(0,0)")
        .each(function(d) { d3.select(this).call(axis.scale(yscale[d])); })
      .append("svg:text")
        .attr({
          "text-anchor": "middle",
          "y": 0,
          "transform": "translate(0,-12)",
          "x": 0,
          "class": "label"
        })
        .text(function(d, i) {    // <== MOD
                 return __.dimensionTitles[i] || String(d);  // <== NEW
        })  //<== MOD

    flags.axes= true;
    return this;
  };

How to highlight when mouse-over ?

I am a new user of d3js and parallel coordinates,
could you point me to an example on how to highlight a curve when touched by the mouse ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.