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

[geo] add package geo #105

Merged
merged 8 commits into from
Jul 24, 2017
Merged

[geo] add package geo #105

merged 8 commits into from
Jul 24, 2017

Conversation

nschnierer
Copy link
Contributor

@nschnierer nschnierer commented Jul 23, 2017

I want to create a new package vx/geo with the ability to draw geoJSON/TopoJSON with different projections. Under the hood the d3-geo library.

This pull request isn't ready to merge now. The documentation isn't complete and a example is missing. I want to finish it in few days. However I think it's good time to get feedback and to review my code.

First example:
bildschirmfoto 2017-07-23 um 02 07 36
The example for vx-demo will be more beautiful ;)

render() {
  const width = 800;
  const height = 600;

  const world = topoJsonClient.feature(topology, topology.objects.units).features;

  return (
    <svg width={width} height={height}>
      <Mercator
        data={world}
        scale={110}
        translate={[width / 2, height / 2]}
        fill="#bbbbbb"
        projectionFunc={projection => {
          console.log('Get projection to use invert', projection);
        }}
        onClick={data => event => {
          console.log(`Clicked country: ${data.id}`);
        }}
      />
    </svg>
  );
}

I really like the vx concept. It's so much easier without d3. Good work ;)

);
}

Projection.propTypes = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<3 <3 <3 Proptypes! :D

fitSize: PropTypes.array,
centroid: PropTypes.func,
className: PropTypes.string
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might be wrong about this, but does Javascript let you add stuff to something "after" you export it? If so => COOL! :D

Copy link
Member

@hshoff hshoff Jul 23, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup! should be fine https://github.com/hshoff/vx/blob/master/packages/vx-pattern/src/patterns/Pattern.js

Looks like I haven't been consistent with my .propTypes placement. Some packages have them above the export others below... at some point I should pick one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the pattern to place it after it (like https://github.com/facebook/prop-types#usage). Maybe it's better to export the function after that, but I'm not sure.

@Flaque
Copy link
Contributor

Flaque commented Jul 23, 2017

This is super super cool! Let me know if you need any help with anything <3

Also: Your code is clean and nice <3

<path
className={classnames(`vx-${projection}`, className)}
d={path(feature)}
{...additionalProps(restProps, feature)}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we will likely want to pass the centroid and maybe the index i in the data part here.

something like we did with <Arc /> in @vx/shape: https://github.com/hshoff/vx/blob/master/packages/vx-shape/src/shapes/Arc.js#L44

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, good idea.

ret[cur] = callOrValue(restProps[cur], data);
return ret;
}, {});
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this comment is just a reminder for myself to follow up on #69

@@ -0,0 +1,3 @@
export { default as Albers } from './components/Albers';
export { default as Mercator } from './components/Mercator';
export { default as Orthographic } from './components/Orthographic';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor thing, could we rename the ./components/dir to ./projections/? this will help match convention with the other packages.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hshoff Yeah, sure. It think projections will be great. Is it a good idea to place the Projection.js into this folder. There is no export for Projection.

{centroid && centroid(path.centroid(feature), feature)}
</g>
)}
{projectionFunc && projectionFunc(currProjection)}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's projectionFunc for? just an outlet for rendering out something based on the currProjection?

Copy link
Contributor Author

@nschnierer nschnierer Jul 23, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hshoff Might be helpful to use invert (https://github.com/d3/d3-geo#projection_invert) x and y coordinates back to longitude and latitude. Not a good solution because you can set projection settings with props like scale, translate. Any ideas?

@hshoff
Copy link
Member

hshoff commented Jul 23, 2017

Fantastic work @nschnierer! A really great addition to vx thanks for making this happen.

Looking forward to the gallery tile. Let me know if things get confusing in vx-demo, I've been putting off cleaning it up...

@hshoff hshoff added this to the v0.0.132 milestone Jul 23, 2017
@nschnierer
Copy link
Contributor Author

@hshoff @Flaque Thanks a lot for the feedback ;) I will finish it soon.

@nschnierer
Copy link
Contributor Author

nschnierer commented Jul 23, 2017

vx/geo

Finished the work. I think that is a good result for the first release ;)

<Mercator />

bildschirmfoto 2017-07-24 um 00 53 30

The demo uses a topology with low resolution (110 metre, ~213kb).

<Orthographic />

vx-geo-orthographic

<Albers />

vx-geo-albers

I hope the color of the demo is fine ✌️

Next steps:

  • Add graticule
  • Add more projection's
  • Add pictures to readme ✅
  • Rethinking about the projectionFunc property 🤔


// TODO: Implement all projections of d3-geo
const projectionMapping = {
orthographic: geoOrthographic(),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if there are multiple instances on a page of one type of projection, would singleton instances result in mixed or lingering config / props being set on them (e.g., if one set clipAngle and another didn't, would they both have the specified clipAngle)?

you could get around it by making these factories as opposed to singletons?

Copy link
Contributor Author

@nschnierer nschnierer Jul 23, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@williaster Oh, good point. I think factories are better. So, maybe like this:

const projectionMapping = {
  orthographic: () => geoOrthographic(),
  // ...
};

Or better to use function instead of arrow function?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

arrow looks good to me. good catch @williaster!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's done 👍

</g>
);
})}
{/* TODO: Maybe find a different way to pass projection function to use for example invert */}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah it's a bummer there is no projection.copy() utility analogous to scales 🤔

import React from 'react';
import Projection from './Projection';

export default function Mercator({ ...restProps }) {
Copy link
Member

@hshoff hshoff Jul 24, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should have caught this in the first review but this is an unnecessary rest here.

let's go with:

export default function Mercator(props) {
  return <Projection projection="mercator" {...props} />;
}

and we'll need to update the other projections. this isn't a blocker. happy to change this after a merge.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ugh... Solved it. @hshoff

@hshoff
Copy link
Member

hshoff commented Jul 24, 2017

LGTM! Thanks again @nschnierer! 🏆

@hshoff hshoff merged commit 9a8b923 into airbnb:master Jul 24, 2017
@Flaque
Copy link
Contributor

Flaque commented Jul 24, 2017

Open Source is great <3

@williaster
Copy link
Collaborator

This is a great add, nice work @nschnierer 💯!

@nschnierer nschnierer deleted the nschnierer-geo branch July 25, 2017 06:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants