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

Responsive SVGs #6

Open
jbhatab opened this issue May 1, 2015 · 16 comments
Open

Responsive SVGs #6

jbhatab opened this issue May 1, 2015 · 16 comments

Comments

@jbhatab
Copy link

jbhatab commented May 1, 2015

I got D3 going and am making charts successfully, but the height width relationship is just crazy hard to understand. You set the height/width on the svg, in d3, and on the s3 container it seems. But getting it to responsively work with this relationship on every phone has not been working.

Here's the code.

var d3 = require('d3');
var jsdom = require('jsdom-jscore');
var React = require('react-native');
var { View, Text, StyleSheet, ScrollView, } = React;
var Svg = require('../../Svg');
var parseDate = d3.time.format("%d-%b-%y").parse;
var _ = require('underscore');
var PerspectiveWebAPIUtils = require('../../../utils/perspective_web_api_utils')
var ListenerMixin = require('alt/mixins/ListenerMixin');
var TimerMixin = require('react-timer-mixin');
var PerspectiveStore = require('../../../stores/perspective_store')

function getStateFromStores(id) {
  return {
    perspective: PerspectiveStore.find(id)
  };
}

var PerspectiveShow = React.createClass({
  mixins: [ListenerMixin, TimerMixin],
  getInitialState: function() {
    return getStateFromStores(this.props.perspective.id);
  },

  componentDidMount() {
    this.listenTo(PerspectiveStore, this._onChange);
    PerspectiveWebAPIUtils.getShow(this.props.perspective.id)
    this.loadDOM();
  },

  _onChange: function() {
    this.setState(getStateFromStores(this.props.perspective.id));
    this.loadDOM();
  },

  renderChart(window, el) {
    var margin = {top: 20, right: 20, bottom: 30, left: 40};
    var w = 600 - margin.left - margin.right,
        h = 600 - margin.top - margin.bottom;

    var data_size = this.state.perspective.efficiency_graph.data.length

    var svg = d3.select(el).append('svg')
      .attr('xmlns', 'http://www.w3.org/2000/svg')
      .attr('width', w + margin.left + margin.right)
      .attr('height', h + margin.top + margin.bottom)
      .append('g')
      .attr('transform', 'translate(' + margin.left + ', ' + margin.top + ')');

    var xScale = d3.scale.linear()
      .domain([0, data_size])
      .range([0, w]);


    var xAxis = d3.svg.axis()
      .scale(xScale)
      .orient('bottom')
      .ticks(5)
      .innerTickSize(6)
      .outerTickSize(12)
      .tickPadding(12);

    svg.append('g')
      .attr('stroke', 'black')
      .attr('stroke-width', '1px')
      .attr('transform', 'translate(0, '+ (h + 0) + ')')
      .call(xAxis)
      .selectAll('path')
      .style({'stroke': 'Black', 'fill': 'none', 'stroke-width': '1px'});

    var yMax = _.max(this.state.perspective.efficiency_graph.data, (item)=>{ return item})

    if( yMax < 100 ) {
      yMax = 100
    }

    var yScale = d3.scale.linear()
      .domain([0, yMax])
      .range([h, 0]);

    var yAxis = d3.svg.axis()
      .scale(yScale)
      .orient('left');

    svg.append('g')
      .attr('stroke', 'black')
      .attr('stroke-width', '1px')
      .attr('transform', 'translate(0, 0)')
      .call(yAxis)
      .selectAll('path')
      .style({'stroke': 'Black', 'fill': 'none', 'stroke-width': '1px'});

    svg.selectAll('rect')
      .data(this.state.perspective.efficiency_graph.data)
      .enter()
      .append('rect')
      .attr('fill', '#4485F3')
      .attr('x', function (d, i) {
        return (i * (w/data_size)+ 4);
      })
      .attr('y', function (d) {
        return yScale(d);
      })
      .attr('width', ((w/data_size) - 4))
      .attr('height', function (d) {
        return h - yScale(d);
      });
    this.setState({data: el.innerHTML});
  },

  loadDOM(n) {
    var self = this;

    jsdom.env('<body></body>', function(errors, window) {
      var el = window.document.querySelector('body');
      self.renderChart(window, el);
    })
  },

  render() {
    if (this.state && this.state.data) {
      return (
        <ScrollView style={{paddingTop: 40}}>
          <Svg width={600} height={600} style={{flex: 1, height: 400}} data={this.state.data} forceUpdate={(new Date()).toString()} />
          <View style={ styles.line }></View>
          <Svg width={600} height={600} style={{flex: 1, height: 400}} data={this.state.data} forceUpdate={(new Date()).toString()} />
          <View style={ styles.line }></View>
        </ScrollView>
      )
    } else {
      return <ScrollView />
    }
  },

});

var styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingTop: 400,
    backgroundColor: '#F6F6EF',
  },
  line: {
    flex: 1,
    height: 1,
    backgroundColor: 'green',
  }
});

module.exports = PerspectiveShow;

Here's what it looks like on the iphone 4s, iphone 6, and iphone 6 plus.

ios simulator screen shot may 1 2015 4 08 41 pm
ios simulator screen shot may 1 2015 4 09 33 pm
ios simulator screen shot may 1 2015 4 10 02 pm

@brentvatne
Copy link
Owner

Yeah this isn't the easiest thing to do at the moment.. If you have any ideas for what API would work well here, let me know!

@jbhatab
Copy link
Author

jbhatab commented May 2, 2015

Ok cool, wasn't sure if I was missing something. I'll think this over. Thanks.

@chroth7
Copy link

chroth7 commented May 4, 2015

@jbhatab FWIW, I looked into that too. I was using react-native-viewport and implemented it as you can see here: https://github.com/chroth7/react-native-svg/blob/master/Apps/Landing.js.

I get the dimensions on mount and also add a listener to capture rotations.

As you can see I had some minor issue with a race condition, so I set a small timeout, cheating. Also, I use a different setup to yours, but maybe you get something helpful out of my code...

@brentvatne
Copy link
Owner

Nice one @chroth7!

@jbhatab
Copy link
Author

jbhatab commented May 4, 2015

Thank you so much @chroth7! First thing I noticed was you aren't even using a style height and width which I think was adding even more confusion to my problem. I was just taking that from the demo though. I'll play with your code for sure.

@chroth7
Copy link

chroth7 commented May 4, 2015

glad you guys like the idea - hope it helps. Let me know if you have some questions - and please do let me know if you find a smarter way to do that!

@jbhatab
Copy link
Author

jbhatab commented May 6, 2015

Trying to get your setup going but I'm not enable to get the Viewport.getDimensions function to run for some reason. Any ideas?

@chroth7
Copy link

chroth7 commented May 6, 2015

are you sure you npm installed so that it is there? What sort of error are you getting?

@jbhatab
Copy link
Author

jbhatab commented May 6, 2015

Yup i installed it and it's there but it's just not doing anything. No error.

@chroth7
Copy link

chroth7 commented May 6, 2015

note that getDimensions(callback) is the proper way to use it, so maybe you want to try something like: Viewport.getDimesions(dim => {console.log('currentDim: ' + dim)}) or something like that (to make sure it is called and returning something (by the way: the console is the one in xCode).

@jbhatab
Copy link
Author

jbhatab commented May 7, 2015

My bad. Forgot to do all the xcode binary stuff. Gotta get used to that. I'm gonna play with it more and I'll post my findings.

@ColinUNC
Copy link

@chroth7 I installed your alpha-prototype version.. but got the following issue.
Can you tell me how to fix it?

screen shot 2015-06-25 at 3 48 20 pm

@chroth7
Copy link

chroth7 commented Jun 26, 2015

@ColinUNCG to be honest, I haven't checked if my prototype is still running on the new react-native versions. But that sounds familiar, I think I had a similar issue with the node_modules directory at that time, I solved it with hint 1 in the installation notes (see readme):
quote:
you might want to delete the contents of: ./node_modules/react-native-viewport/node_modules (I get problems building it because of recursive paths - even if I disable that)

can you check if that helps?

@MuruganDurai
Copy link

@chroth7 Hi Chris, Is there any chance that you have worked the same prototype with android If yes can you please share the details or share any idea to achieve the same results.

@chroth7
Copy link

chroth7 commented Jan 21, 2016

@MuruganDurai sorry, I haven't been working on these things for a good while now and am not really up to speed anymore, especially in terms of Android.

I hope to find time soon again to invest in ReactNative, but currently, I am afraid I cannot give a well-thought-through idea let alone solution for Android, sorry!

@MuruganDurai
Copy link

@chroth7 No issues. Thanks. @brentvatne Can you please shed some light?

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

No branches or pull requests

5 participants