Project Dashboard Vote Shift View - GenusDev/genie-portal GitHub Wiki
SPRINT GOAL - “To create a tool that allows investor-users to cast votes for projects after comparing projects based on their capital requirements and overall valuation.”
Component Hierarchy
Token Dashboard
Project Dashboard Toggle Shift View
Location View ….(forcemap)
Vote View (SVG 1)Capital Being Raised line over time
Capital Raised Blue Square (props = capital raised) (SVG 2)
Deployed Project layerProject NOI circles (props = NOI, Project specific capital Raised Lines,)
Capital Raised Lines (props = Project specific capital Raised Lines, )
(recyclable component for each line)
Capital Being Raised Brown Square (props = capital being raised) (SVG 3)
PitchedProjectContainer
PitchedProjects (props = vote%, valuation, capitalNeeds)VoteBreakdown
CapitalNeedsExtention
ValuationExtension
(recyclable component for each box)
The primary input by the user is ‘votes’: When a user opens the project dashboard, projects are broken down by capital requirements and overall valuation. After analysis, the user enters new votes or allocates existing votes to desired projects.
Entry Action: The dashboard clears and focused on vote shift view after clicking on the respective circle in the project dashboard toggle, located at the base of the page.
User Action: User allocates votes to projects after click on the project. A vote toolbar is created that will allow the user to shift their votes to and from a project and a free pool of votes.
Feature Action: Shift vote order: if the user enters enough votes to change the standing of the projects, the chart rearranges to reflect the new order. #ChartAnimation
Feature Action: Project Deployment: If the user enters enough votes to deploy a project after the capital has been reached then the project will deploy and the pitched projects not deployed will shift up to a new capital raising cycle, while the deployed project joins the other deployed projects.
Outputs: There are three possible outcomes:
- vote fields are updated,
- the standing order of the projects is modified,
- a project is deployed, inciting a cascade of changes to projects, token holdings and their representation.
A deployed project will need some confirmation on the blockchain with each deployment. The user will notice that a portion of their token holdings have become active. Once deployed, an alert will send to all token holders to let them know that a project has deployed and what portion of their holdings are now active, and the tentative timeline for the projects development.
The components will be fed two key data structs - one for all projects, and one for capital raised over time.
Project Data: The project data will have information about each project, including their status as deployed or not deployed. Capital raised previously will come from database.
Variables pulled from event listeners on blockchain using the contract instance address
- Capital currently being raised
Vote share info
If it is not active, the voteShare is calculated by dividing totalProjectVotes / totalVotesCast - Active vs inactive project status
- CapitalRequired
- Deployment Date
CapitalRaisedOverTime: Capital raised over time will be pulled from a chain-based event listener, providing capital raised at weekly intervals. The line that uses this data should overlap across the two rect types.
Variables to pull from Blockchain Data pints at weekly intervals Derive start and end time implicitly Derive a capitalBeingRaised
![screenshot](https://github.com/GenusDev/genusdev-assets/raw/master/Product_ui_mockups_design/projectDashboard/voteShiftView/toggle.png)
The toggle should shift out various modes of the project dashboard by clicking the white portion of the toggle. On hover, the text on the right should change to text relevant to the mode being used. Use icons as shown for now. Third view has yet to be developed and will remain as a filler with no text info and a blank icon.
- build out toggle outline with curved edges
- set up icons and circles (three) Overlay two icons and position them
- set up text boxes
- integrate hover functionality
- integrate click functionality that clears out current view and shows the respective dashboard
- this can be accomplished by toggling state with each button click
- Build toggle viewer for view change {Steven T}
- Start this feature by building a top level container component that holds an SVG that future SVGs will be appended to. This SVG will have to scale with the height of the capital being raised + capital raised (both scaled using the same scale ) plus 400 pixels of buffer for the pitchedProjects table. Build scaling functions and pass them down as props to the sub components.
- Create scaling function for the svg that spans the width and is associated with the dates
- Create scaling function that translates 400 pixels as two times the height of the largest pitched or deployed project’s capital needs (should accommodate for situations where there are not pitched projects, and no deployed projects). I believe there is a setting in d3 that uses this a basis and allows for numbers beyond 400.
domain : 0, 2*HighestCapNeeds
Range : 0, 400
![screenshot](https://github.com/GenusDev/genusdev-assets/raw/master/Product_ui_mockups_design/projectDashboard/voteShiftView/blueSquare.png)
The blue rect will extend down from 400 pixels, at a set constant amount based on capital raised. The blue rect will then extend down further as new projects are introduced and new capital is deployed.
The intention is that this square is pushed backed significantly, meaning that the teal color shown is very transparent.
- Set up blue capitalRaised component as a rect whose height is based on capital raised (Pass capital raised as a prop to the component) in an absolute sense, meaning the rect should extend to the bottom of the page, starting at 400 pixels down the sVG to the bottom of the SVG, which should be where the dashboard toggle stops, with maybe some small buffer.
- Style blue but pass some projectClicked boolean as a prop that will trigger when a project is clicked, increasing the transparency further.
- Set text to midway in the rect in white to the capital raised. Potentially format in ‘k’s for brevity.
- Make the text hidden and show only on hover.
![screenshot](https://github.com/GenusDev/genusdev-assets/raw/master/Product_ui_mockups_design/projectDashboard/voteShiftView/brownSquare.png)
This component will append an SVG or rect that extends from 400 pixels down from the start of the main view SVG. This component will contain everything above the blue previous capital section. The top level of the svg should have a brown, moderately transparent (%50) rect that spans the width of the page and has a height determined, relatively by the capital raised in the current cycle. There will be a prop indicating the capital raised in the current cycle. Because this box is to sit above the previous line, it will be important for the svg to start where the other finishes.
- Append a rect whose width is the same as the SVG and whose height is scaled based capital raised to date.
- text and float placements
Text for both the amount raised and the capital being raised label should be placed in the middle of the current square, set some distance from the sides. And should only show on hover.
![screenshot](https://github.com/GenusDev/genusdev-assets/raw/master/Product_ui_mockups_design/projectDashboard/voteShiftView/overTime.png)
props
- capital (determined by a function of total capital - current cycle capital) data for the capital raised will come from inactive token purchase events.
- start time
- end time
- graph data (option 2 is probably better)
The line tracking the capital raised will need to span the entire top level SVG. It will need to integrate data on a time basis, and map to the same x-scale as the above time-based axis. Potentially this axis can be passed down by moving it up the hierarchy of components. The yAxis scale will be the same as the box lines.
- Set up x axis scale to match above axes Feed in and structure capital raised over time data for the d3 line as a prop
- Style white and ensure z-index is high so it overlays on top of all other components
- Potential things to integrate later
- Tooltip that connects deployments to the token chart on hover to reinforce x-axis - particularly important if many projects are displayed.
Graph Data option 1 { capitalByDay: [ {0: 10}, {1: 40}, {2: 70}, {3: 96}, … ], links: [ {source: 0, target: 1}, {source: 1, target: 2}, {source: 2, target: 3}, … ] }
capitalByDay has a key for the day with a value of the cumulative capital raised up until that day. for example, if day 0 raised 10 and day 1 raised 30, the value for day one should be 40. links represent data for how to connect lines between the days. For more documentation of this setup see https://bl.ocks.org/mbostock/533daf20348023dfdd76 Option 2 [ {date: 0, capital: 10}, {date: 1, capital: 40}, date: 2, capital: 70} ] here, the data structure is an array with data for each day. the day is the day, capital is the capital raised up until that day (the same as option 1) for more info on how to implement this, see http://bl.ocks.org/d3noob/8dc93bce7e7200ab487d
![screenshot](https://github.com/GenusDev/genusdev-assets/raw/master/Product_ui_mockups_design/projectDashboard/voteShiftView/deployedLayer.png)
Project NOI circles (props = NOI, Project specific capital Raised Lines,)
Will have to pass time x scale and y scale down as props. Text hovers show when over blue rect, so may also pass down on hover state variable. Make the circle and line component structure recyclable so you can loop through them for each project.
- Create project circle width set to the NOI of each project
- Situate circles based on deployment date and capital raised (X,Y)
- Create text hovers for project name, directly below dot
- Clicking the buttons makes the project modules pop up
Capital Raised Lines (props = Project specific capital Raised Lines, )
- Extend lines from the circles to the max width of the screen on the left side
2px thick - Create capital raised text hovers the sit just below the lines
Prospective Projects will be a recyclable component layer that feeds in vote%, valuation, capitalNeeds as props. The prospectiveProjects layer will sit directly on top of the blue rect, situated 400 pixels below the start of the upper SVG, with a slight 30 pixel buffer for the ratio breakdown.
- Pass the vote percentages as props for both the vote ratio breakdown and the value/capReq components.
- Potentially also pass scaling functions for the ⅓ of the screen to both
- Projects are to be ordered based on votes provided.
- If only one project is show, potentially hide vote percent breakdown.
- Potentially may need to pass order as prop that re-renders with each new vote cast
- Will potentially also need to pass down state of market cap reached or not as props to sub-components.
![screenshot](https://github.com/GenusDev/genusdev-assets/raw/master/Product_ui_mockups_design/projectDashboard/voteShiftView/voteBreakdown.png)
Props
- vote percentage (represented as a decimal from .01-1.0)
The base of the pitchedProjectsDisplay will sit just below the end of the blue rect.
- Set height to be 30 pixels and width to be 1.3rd of the width of the screen/svg
- You should be able to use the treemap library to create this breakdown dynamically https://d3indepth.com/layouts/
- Place text midway (probably better if greyish white)
Props
- capital required
- valuation
- vote percentage (represented as a decimal from .01-1.0)
- Name
Unlike in the designs below, there will be a small buffer on each side of the capital needs as it extends up, even the edge cases. You could append rects whose start and ends correspond with their vote percentages, or you could make this an extension of the d3 partition layout. For now we will assume you are just appending rects.
![screenshot](https://github.com/GenusDev/genusdev-assets/raw/master/Product_ui_mockups_design/projectDashboard/voteShiftView/capNeeds.png)
- Append rects to the svg whose x base is 400, whose width is the vote share with a 10% buffer on each side.
- Height is determined by the capital required to deploy the project.
Will need a separate y-scaling function for this that takes 0 to two times the height of two times the largest capital requirement of both pitched and deployed projects as the domain and 0-400 as the range. - Color will be solid brown if there is not enough capital in the current cycle to deploy it
- If the capital requirement has been met, the color will shift blue
- Cap Needs Text to display on Hovers for capital needs, is white. Should hug the upper line below and above, as show in designs.
- Also name for project should show on hover in the color that matches the square color (not as shown in designs)
- Boxes are outlined white - potentially only on hover, with vote % breakdown also white outline.
- Integrate onClick functionality that opens up voteModal.
- If clicked twice, potentially open up projectModal for more info
![screenshot](https://github.com/GenusDev/genusdev-assets/raw/master/Product_ui_mockups_design/projectDashboard/voteShiftView/valExtension.png)
This is a sub-component of CurrentVotingCycle. It is an svg nested within the outer svg which contains visualizations of all the pitched projects, as seen in the image above. On hover, text will appear as shown in the image above.
- Height is determined by the valuation - capital required.
- width is the same as the bottom rec
- Color will be transparent brown if there is not enough capital in the current cycle to deploy it
- If the capital requirement has been met, the color will shift transparent blue
- Text to display on Hovers for valuation is grey, should hug the upper line below and above, as show in designs.
![screenshot](https://github.com/GenusDev/genusdev-assets/raw/master/Product_ui_mockups_design/projectDashboard/voteShiftView/voteShift1.png)
![screenshot](https://github.com/GenusDev/genusdev-assets/raw/master/Product_ui_mockups_design/projectDashboard/voteShiftView/voteShift2.png)
![screenshot](https://github.com/GenusDev/genusdev-assets/raw/master/Product_ui_mockups_design/projectDashboard/voteShiftView/voteShift3.png)
Props:
- Votes per project
- Votes not dedicated
- On Click, all projects but the project clicked fade back, and the detals about that project are displayed statically.
- Structure data by votes - per project and votes not dedicated
- Build svg for tool with a brown rect with curved edges
- Put in two small sub rects,
potentially using the same partition method as the vote percentage breakdown, whose widths dimensions match vote breakdown. fill left side of vote shift tool blue, fill the right side white - Build vote shift line
that is placed between the two rects with a small 5px bufferv - Create drag effects for bar in vote shift tool
- Add text indicating project votes and open votes
- initialize position of vote bar as a function of ratio of project votes to open votes
- add log button
- log button does not show unless vote bar has been moved
- hover effects changes colors when clicked, voting tool closes
- On log click, call is made to the blockchain and vote shift tool exits and the upper component re-renders potentially shifting order of projects
- When clicking significantly out of the vote shift tool or on another project, vote shift tool closes without making a call to the blockchain. Log button is required for shift.
- Add up/down arrows buttons, keep hover text for projects when clicked,
Projects will be updated in two ways: Change in voteShare and change in activation status
- figure out batch calls (so users don't have to sign looped transactions) for the vote calls Examples of batch sending: https://peepeth.com/
- figure out how to pay for other peoples blockchain calls (so users don't pay a constant fee regardless of how many projects there are)
- reset ui in the case that vote changes are not saved to the blockchain
- looping - need signatures for every function call. Get one sig for following calls to blockchain
- cost alignment to activity
- figure out batch calls (so users don't have to sign looped transactions) figure out how to pay for other peoples blockchain calls (so users pay a constant fee regardless of how many projects there are).
We need to rewrite the voteWithCredit and removeVotesFromProject (currently called addVoteCredit) functions. they will work very much like to voteForCandidate function from the contract in this tutorial:
https://medium.com/zastrin/how-to-save-your-ethereum-dapp-users-from-paying-gas-for-transactions-abd72f15e14d.
pitchProject
- this function will need to be modified to take in a hash that represents a vote for the pitchedProject. It will be used to verify that votes are for a valid project.
we will need a mapping from project name to its valid vote hash.
We will use OpenZeppelin’s ERecovery library to authenticate signed transactions. See more info in the link listed in the first bullet point of this section.
Pitching Projects
- when a project is pitched, we need to send the blockchain a ‘valid voting hash’ generated by eth-sig-util’s typedSignatureHash function.
Voting
- When a user confirms their vote redistribution, we create transaction hashes for each project we are changing votes for via metamasks’s eth_signTypedData method
We will determine which projects need to be modified according to the following logic:
- When the vote shift tool is mounted, we store the current vote distribution in the state. This will be used as a reference for what the true current state of the blockchain while the user tampers with voting data in the ui.
- whenever a user changes votes in the ui, a separate slice of state is updated.
- when the user submits their changes, the two slices of state are compared to generate transaction hashes.
We are using ethereum.rb to make transactions to the blockchain with a private key generated by the ruby-eth gem.
BlockChain.rb
the Blockchain class has two variables:
- @client - establishes a connection to our infura node via the ethereum.rb gem
- @crowdsaleInstance - an object for interacting with our deployed contract via ethereum.rb
self.new_key
this method creates a new private key with the ruby-eth gem
distributeVotes
- arguments
- private_key: the private key that will sign our transaction
- vote_removals: [signed_transaction1, signed_transaction2…] this argument is an array of transactions signed by the user via metamask. it will be processes before the following argument. each signed transaction is a javascript object (ruby hash). it contains the same of the project, the account of the voter, and the signed transaction hash. Each of these components are necessary for verifying votes on the blockchain.
- vote_additions: [signed_transaction1, signed_transaction2…] this argument is similar to the first, but it contains transactions that are adding votes to projects rather those those remove votes.
- procedure
- for each has in the vote_removals hash: use etherem.rb gem to call the ‘remove_vote’ function on @crowdsaleInstance with the hash, project name, user account, and our private_key, . do the same for each in the vote_addition hash, but with @crowdsaleInstance’s ‘vote’ function instead.
BlockChainAccount.rb
this class is a database model that contains data for keys generated by ruby-eth.
BlockChainController.rb
this controller will interact with both BlockChainAccount.rb and BlockChain.rb to make calls to the blockchain.
methods
- vote
- arguments
- vote_removals: [signed_transaction1, signed_transaction2…] this argument is an array of transactions signed by the user via metamask.
- vote_additions: [signed_transaction1, signed_transaction2…] this argument is similar to the first, but it contains transactions that are adding votes to projects rather those those remove votes
- procedure
- first, the function creates a new instance of the BlockChain class
- next, it retrieves our private_key from the first record in our BlockChainAccount model. this will be used to sign transactions in the BlockChain instance.
- finally, it calls the distributeVotes function on the BlockChain instance with the private_key and its two arguments.
VoteShiftTool:
- Animate transition from project to vote view, make project circles transform/align to bars
[list minor fixes that can be done quickly or at a later dates]
[notes for developer]