Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support data accessor functions #84

Closed
coopy opened this issue Dec 3, 2015 · 18 comments
Closed

Support data accessor functions #84

coopy opened this issue Dec 3, 2015 · 18 comments
Assignees
Labels
Type: Enhancement ✏️ An enhancement or feature proposal that will be addressed after the next release

Comments

@coopy
Copy link
Contributor

coopy commented Dec 3, 2015

Requirements: Ability to pass in props to any component to specify how to get (x, y) data, which is either:

  • A string with (deep) property key; or
  • A function

It would be great if this were implemented as a mixin/composable that could be imported from victory-util.

@coopy coopy added this to the Beta milestone Dec 3, 2015
@boygirl
Copy link
Contributor

boygirl commented Dec 10, 2015

more detail:

Right now the data prop is pretty naive. Just a array (or array of arrays) of data objects that need to have x and y values to work. The data prop is probably going to stay pretty simple, but in the near future we will be adding accessor functions to make it more flexible. What I mean by that is...

data={{[
  {name: "cat", amount: "2234", error: 3},
  {name: "dog", amount: "4567", error: 4},
  {name: "bird", amount: "5555", error: 0}
]}}
x="name"
y={(data) => parseInt(data.amount) + data.error + 1}
  • support assigning an arbitrary key name as x or y (as in the x accessor above)
  • support assigning and transforming data via a function (as in the y accessor)

@knowbody knowbody added the Type: Enhancement ✏️ An enhancement or feature proposal that will be addressed after the next release label Dec 19, 2015
@philpoore
Copy link

+1

@dandelany
Copy link
Contributor

To-do list for supporting data accessors:

@dandelany
Copy link
Contributor

Here's how the data accessor API will look: All chart types may be passed x and y props which specify how to access x and y values for each data point. These may be:

  • Integers, which are used as array indices for array-type data, eg. props {x: 0, y: 1} for data like [[0, 0], [1, 2], [2, 5]].
  • Strings, which are used as property keys for object-type data, eg. props {x: 'x', y: 'y'} for data like [{x:0, y:0}, {x:1, y:2}].
  • Strings containing . or [], which are used as key paths for deeply nested data (see docs for _.get for details ). Eg. props {x: 'a.b[0].c', y: 'a.b[0].d'} for data like [{a:{b:[{c: 3, d: 5}]}}, {a:{b:[{c: 6, d: 9}]}}].
  • Functions, which are run on each datum - eg. props {x: (d) => 0.1 * d, y: (d) => Math.sin(d)} to generate a sine wave from data like [0, 1, 2, 3, 4].
  • null or undefined, in which case the datum itself is used as the x or y value, eg. props {x: null, y: null} to generate a diagonal line from data that looks like [0, 1, 2, 3, 4].

The default x and y props are the strings 'x' and 'y', which means that, by default, it will work correctly with data that looks like the existing standard {x: 1, y: 2} data format.

Since this replaces the old behavior for x and y props which was a bit different, it will require an update to the docs and a version bump as well. PRs coming soon.

@dandelany
Copy link
Contributor

@boygirl All of the PR's mentioned above are now ready for review! Please take a look and let me know what you think. Hit me up on chat if you have any questions/comments.

@dandelany
Copy link
Contributor

All of the PR's have been merged into the pre-release branch and should make it to master later this week (along with the react-art stuff).

@boygirl
Copy link
Contributor

boygirl commented Jan 29, 2016

update: react-art stuff is postponed, so this feature will go straight into master today / over the weekend. 🎉 Thanks @dandelany

@boygirl
Copy link
Contributor

boygirl commented Feb 1, 2016

victory@0.4.0 closes this issue

@boygirl boygirl closed this as completed Feb 1, 2016
@boygirl boygirl reopened this Feb 2, 2016
@boygirl boygirl closed this as completed Feb 2, 2016
@okonet
Copy link

okonet commented Feb 11, 2016

Does this also support using data ancestors in style. Something like:

<VictoryBar
                data={data}
                style={{ data: {
                    width: data => data.x,
                 }}}
            />

@boygirl
Copy link
Contributor

boygirl commented Feb 11, 2016

@okonet yep! Your example above will work. If you specify functions for style attributes they will be evaluated using the corresponding data point for each bar.

@okonet
Copy link

okonet commented Feb 11, 2016

I've tried it and it didn't work. Probably I miss something. Do you have a test/example for it?

@boygirl
Copy link
Contributor

boygirl commented Feb 11, 2016

<VictoryBar
  style={{
    data: {
      fill: (data) => data.y > 2 ?
        "red" : "blue"
    }
  }}
  data={[
    [
      {x: 1, y: 1},
      {x: 2, y: 2},
      {x: 3, y: 3}
    ],
    [
      {x: 1, y: 2},
      {x: 2, y: 1},
      {x: 3, y: 1}
    ],
    [
      {x: 1, y: 3},
      {x: 2, y: 4},
      {x: 3, y: 2}
    ],
  ]}
/>

@knowbody
Copy link
Contributor

awww @boygirl you beat me to it 😜

I was just creating a JSFiddle.

@okonet
Copy link

okonet commented Feb 11, 2016

I'm trying to do this with the VictoryLine and it seems there is a bug. The function will be called with the whole data object for each iteration.

<VictoryLine
 style={{data: {fill: data => { console.log(data)}}}}
    data={[
      {x: 0, y: 1},
      {x: 1, y: 3},
      {x: 2, y: 2},      
      {x: 3, y: 4},
      {x: 4, y: 3},
      {x: 5, y: 5}
    ]}
 />

outputs:

[Object, Object, Object, Object, Object, Object]

but

<VictoryBar
 style={{data: {fill: data => { console.log(data)}}}}
    data={[
      {x: 0, y: 1},
      {x: 1, y: 3},
      {x: 2, y: 2},      
      {x: 3, y: 4},
      {x: 4, y: 3},
      {x: 5, y: 5}
    ]}
 />

outputs

Object {x: 0, y: 1}
Object {x: 1, y: 3}
Object {x: 2, y: 2}
Object {x: 3, y: 4}
Object {x: 4, y: 3}
Object {x: 5, y: 5}
Object {x: 0, y: 1}
Object {x: 1, y: 3}
Object {x: 2, y: 2}
Object {x: 3, y: 4}
Object {x: 4, y: 3}
Object {x: 5, y: 5}

@knowbody
Copy link
Contributor

@okonet mind opening another issue and adding JSFiddle to it, with the issue?

@okonet
Copy link

okonet commented Feb 11, 2016

Will do!

@boygirl
Copy link
Contributor

boygirl commented Feb 11, 2016

Yeah lines are a little funny... Only a single component gets rendered for an entire dataset, so the style functions get the entire dataset. If you have a preferred behavior / use case I would love to hear about it.

@okonet
Copy link

okonet commented Feb 11, 2016

Oh I see now... and it makes sense, actually. Otherwise, you'll end up with creating tons of lines for each section...

divmain pushed a commit that referenced this issue Feb 16, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Enhancement ✏️ An enhancement or feature proposal that will be addressed after the next release
Projects
None yet
Development

No branches or pull requests

6 participants