Giter VIP home page Giter VIP logo

visualizer's Introduction

UI-Router State Visualizer and Transition Visualizer

Try the Demo plunker

Image of Visualizer

What

Visualizes the state tree and transitions in UI-Router 1.0+.

This script augments your app with two components:

  1. State Visualizer: Your UI-Router state tree, showing the active state and its active ancestors (green nodes)

    • Clicking a state will transition to that state.
    • If your app is large, state trees can be collapsed by double-clicking a state.
    • Supports different layouts and zoom.
  2. Transition Visualizer: A list of each transition (from one state to another)

    • Color coded Transition status (success/error/ignored/redirected)
    • Hover over a Transition to show which states were entered/exited, or retained during the transition.
    • Click the Transition to see details (parameter values and resolve data)

How

The Visualizer is a UI-Router plugin. Register the plugin with the UIRouter object.

Locate the Plugin

  • Using a <script> tag

    Add the script as a tag in your HTML.

    <script src="//unpkg.com/@uirouter/visualizer@4"></script>

    The visualizer Plugin can be found (as a global variable) on the window object.

    var Visualizer = window['@uirouter/visualizer'].Visualizer;
  • Using require or import (SystemJS, Webpack, etc)

    Add the npm package to your project

    npm install @uirouter/visualizer
    
    • Use require or ES6 import:
    var Visualizer = require('@uirouter/visualizer').Visualizer;
    import { Visualizer } from '@uirouter/visualizer';

Register the plugin

First get a reference to the UIRouter object instance. This differs by framework (AngularJS, Angular, React, etc. See below for details).

After getting a reference to the UIRouter object, register the Visualizer plugin

var pluginInstance = uiRouterInstance.plugin(Visualizer);

 


Configuring the plugin

You can pass a configuration object when registering the plugin. The configuration object may have the following fields:

  • state: (boolean) State Visualizer is not rendered when this is false
  • transition: (boolean) Transition Visualizer is not rendered when this is false
  • stateVisualizer.node.label: (function) A function that returns the label for a node
  • stateVisualizer.node.classes: (function) A function that returns classnames to apply to a node

stateVisualizer.node.label

The labels for tree nodes can be customized.

Provide a function that accepts the node object and the default label and returns a string:

function(node, defaultLabel) { return "label"; }

This example adds (future) to future states. Note: node.self contains a reference to the state declaration object.

var options = {
  stateVisualizer: {
    node: {
      label: function (node, defaultLabel) {
        return node.self.name.endsWith('.**') ? defaultLabel + ' (future)' : defaultLabel;
      },
    },
  },
};

var pluginInstance = uiRouterInstance.plugin(Visualizer, options);

stateVisualizer.node.classes

The state tree visualizer can be configured to add additional classes to nodes. Example below marks every node with angular.js view with is-ng1 class.

var options = {
  stateVisualizer: {
    node: {
      classes(node) {
        return Object.entries(node.views || {}).some((routeView) => routeView[1] && routeView[1].$type === 'ng1')
          ? 'is-ng1'
          : '';
      },
    },
  },
};

var pluginInstance = uiRouterInstance.plugin(Visualizer, options);

Getting a reference to the UIRouter object

Angular 1

Inject the $uiRouter router instance in a run block.

// inject the router instance into a `run` block by name
app.run(function ($uiRouter) {
  var pluginInstance = $uiRouter.plugin(Visualizer);
});

Angular 2

Use a config function in your root module's UIRouterModule.forRoot(). The router instance is passed to the config function.

import { Visualizer } from "@uirouter/visualizer";

...

export function configRouter(router: UIRouter) {
  var pluginInstance = router.plugin(Visualizer);
}

...

@NgModule({
  imports: [ UIRouterModule.forRoot({ config: configRouter }) ]
  ...

React (Imperative)

Create the UI-Router instance manually by calling new UIRouterReact();

var Visualizer = require('@uirouter/visualizer').Visualizer;
var router = new UIRouterReact();
var pluginInstance = router.plugin(Visualizer);

React (Declarative)

Add the plugin to your UIRouter component

var Visualizer = require('@uirouter/visualizer').Visualizer;

...
render() {
  return <UIRouter plugins=[Visualizer]></UIRouter>
}

visualizer's People

Contributors

christophercr avatar christopherthielen avatar dblvs avatar dependabot-preview[bot] avatar dependabot[bot] avatar jlhwung avatar jrencz avatar navarroaxel avatar npmcdn-to-unpkg-bot avatar phdlove42 avatar reeceward-vpm avatar uirouterbot 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

visualizer's Issues

JSX element type 'ReactElement<any>' is not a constructor function for JSX elements.

If you import @uirouter/visualizer into a React + Typescript project using @types/react, you get an error when rendering a Functional Component from in some cases.

The typings for @uirouter/visualizer include the individual component classes definitions, so somebody can theoretically render the components themselves using preact. However, even importing 'preact' anywhere in the project causes a conflict in the merged JSX.Element definition. Importing @uirouter/visualizer implicitly imports preact.

This issue can be seen with this simple proof of concept:

npm init -y
npm install @types/[email protected] [email protected] [email protected] [email protected]
echo 'import * as React from "react";
import "preact";

const FunctionalComponent: React.FC = () => <h1>foo</h1>;
class ClassComponent extends React.Component {
  render() {
    return <FunctionalComponent/>;
  }
}' > test.tsx;
npx tsc ./test.tsx --skipLibCheck --jsx react
test.tsx:7:12 - error TS2605: JSX element type 'ReactElement<any>' is not a constructor function for JSX elements.
  Type 'ReactElement<any>' is missing the following properties from type 'Element': nodeName, attributes, children

7     return <FunctionalComponent/>;
             ~~~~~~~~~~~~~~~~~~~~~~

This issue in the preact repo may be related: preactjs/preact#1036 but I'm not sure.

Issue with a strict Content Security Policy (CSP)

Hello,

I've tried using the visualizer with my application but noticed the following errors in the console:

Refused to load the stylesheet 'blob:http%3A//localhost%3A3000/9ec665e3-b7f8-433f-a4f8-be6d8a0bf92c' because it violates the following Content Security Policy directive: "style-src 'self''".
updateLink @ addStyles.js:242addStyle @ addStyles.js:172addStylesToDom @ addStyles.js:77module.exports @ addStyles.js:37(anonymous function) @ stateVisualizer.css...
addStyles.js:242Refused to load the stylesheet 'blob:http%3A//localhost%3A3000/70a09723-daa2-4135-a979-6e32da4f23f6' because it violates the following Content Security Policy directive: "style-src 'self'".
...

I left out some details, but apparently the code tries to add inline styles to the page through the addStylesToDom function (addStylesToDom(newStyles, options);).

The issue with this is that with a Content Security Policy (CSP) active and hardened, using inline styles is forbidden.

I see two solutions to this issue:

  • avoid using inline styles entirely (i.e., add/remove classes instead of inline styles)
  • provide a way to configure a nounce so that it can be set by your library on the places where you use inline styles and configured in the CSP so that it does not complain about these

I would prefer solution #1 if doable.

Do you think you could solve this?

Thanks for the nice visualizer though :)

[State tree] large app

Possible enhancements:

  • use middle click to expand/collapse tree
  • show only the first level

selection_020

update dependency preact to 8.2.xx

I am using latest visualizer with Typescript 2.4.2. In the build I get this error:

ERROR in ...\node_modules\@uirouter\visualizer\node_modules\preact\dist\preact.d.ts
(40,17): error TS2559: Type 'Component<PropsType, StateType>' has no propert

This error is already fixed in preactjs/preact#735 and preact v8.2 is already released, but visualizer keeps installing v7.xx.

Please update the depencency. Currently I am using a workaround and shinkwrap the version.

Cannot run visualizer in an angular project.

Any thoughts?
Unable to resolve some modules:

"./ReactElementValidator" in
/D/dev/meteor-angular-socially/node_modules/ui-router-visualizer/release/visualizer.min.js
(web.browser)
"./ReactDebugTool" in
/D/dev/meteor-angular-socially/node_modules/ui-router-visualizer/release/visualizer.min.js
(web.browser)
"./ReactDOMDebugTool" in
/D/dev/meteor-angular-socially/node_modules/ui-router-visualizer/release/visualizer.min.js
(web.browser)
"./ReactComponentTreeDevtool" in
/D/dev/meteor-angular-socially/node_modules/ui-router-visualizer/release/visualizer.min.js
(web.browser)

click on an abstract state + state with params

  • Abstract state
    When I click on on an abstract state I get the following error
Error: Cannot transition to abstract state ''

I think it should be ignored if it doesn't have redirect_to.

  • State with params
    Add ability to specify the state params

Build errors

I am getting the following errors when trying to require the visualizer into my app.

[18:09:30] gulp-notify: [Compile Error] Error: Cannot find module '!!./../../node_modules/css-loader/index.js!./transitionHistory.css' from 'c:\Development\foursee\app\node_modules\ui-router-visualizer\release'
[18:09:30] gulp-notify: [Compile Error] Error: Cannot find module '!!./../../node_modules/css-loader/index.js!./vis.css' from 'c:\Development\foursee\app\node_modules\ui-router-visualizer\release'

RADIAL_EDGE && TREE_EDGE functions fail on missing node._parent (possible fix)

I had a problem with the RADIAL_EDGE && TREE_EDGE functions failing when the var node was presented without a ['_parent']. This might not be a typical case, as I'm new to using the latest version of ui-router (v1.0.14) and visualizer, and I might be implementing things differently (timing issues, etc). Anyway, the problem seemed to come from the "nodes.filter" part of the _this.nodeForState function returning a node for the value of node.name and state.name both being the undefined string (''). Not sure why I get this and other aren't, but the fix is relatively trivial, so here it is:

function TREE_EDGE(node, renderer) {
    var strokeWidth = renderer.baseStrokeWidth * renderer.zoom;
    var makeLinkPath = function (node) {
        var s = { x: node.animX, y: node.animY }; // statevisnode
        var p = {
			x: node._parent ? node._parent.animX : node.animX,
			y: node._parent ? node._parent.animY : node.animY
		}; // parent
        var yAvg = (s.y + p.y) / 2;
        return "M " + s.x + " " + s.y + " C " + s.x + " " + yAvg + ", " + p.x + " " + yAvg + ", " + p.x + " " + p.y;
    };
    return preact_1.h("path", { d: makeLinkPath(node), "stroke-width": strokeWidth, className: 'link' });
}

I just check for the existance of _parent in node first. My app worked fine thereafter, and the node._parent node seems to be updated in the next iteration anyway. I didin't see any difference in positioning from the demo available on the web. So, this is just a suggestion as I am no expert on ui-router and visualizer. Really like the way visualizer.js presents UI-Router states.

Compatibility with D3 v4

Is it possible to change the code to use an isolated D3 scope so later versions of D3 can be used in the application without affecting the visualizer.

At the moment if you are using a later version of D3 in your project you can't use the visualizer as it loads d3 into the global scope.

Dependency injection causing this module to not work at all

I'm seeing dependency injection errors while trying to use this module:

angular.js:13708 Error: [$injector:strictdi] function($transitions, $timeout, d3ng, easing, uirTransitionsViewConfig) is not using explicit annotation and cannot be invoked in strict mode

After digging into the release/visualizer.js source I see this (amungst others):

statevis_module_1.app.run(function ($rootScope, $injector, uirStateVisService) {

Shouldn't this look like this?

statevis_module_1.app.run(['$rootScope', '$injector', 'uirStateVisService', function ($rootScope, $injector, uirStateVisService) {

Display custom data properties in Transition Popover

From what I can tell, "data" properties are not displayed in the data popover for a given state. I think it would be valuable to show these properties along with resolved data.

E.g. for state mymessages, we have

export const mymessagesState = {
  parent: 'app',
  name: "mymessages",
  url: "/mymessages",
  resolve: {
    // All the folders are fetched from the Folders service
    folders: (Folders) => Folders.all()
  },
  // If mymessages state is directly activated, redirect the transition to the child state 'mymessages.messagelist'
  redirectTo: 'mymessages.messagelist',
  component: 'mymessages',
  // Mark this state as requiring authentication.  See ../routerhooks/requiresAuth.js.
  data: { requiresAuth: true, pageTransition: true, layoutTransition: 'mymessages' }
};

requiresAuth, pageTransition and layoutTransition would be displayed at this state level in the popover. This would be handled similarly to "Resolved Data"

Allow comments in the tsconfig.json file

My tsconfig.json file contains:

  "exclude": [
    // IDEs should not type-check the different node_modules directories of the different packages.
    // This would cause the IDEs to be slower and also linters would check the node_modules.
    "node_modules/",
    "typings"
  ]

The ngd command failed:

14:55 $ ngd
[14:55:36] using tsconfig: /home/stephane/dev/js/projects/angular/musicng/tsconfig.json
internal/modules/cjs/loader.js:1188
    throw err;
    ^

SyntaxError: /home/stephane/dev/js/projects/angular/musicng/tsconfig.json: Unexpected token / in JSON at position 1017

After removing the comments, the same command succeeded.

When clicked State Visualizer dissapears

As said, and to get it back I have to reload page (SPA) so this misses the point....
Visualizer version: 3.1.3
UI Router version 1.0.0-rc.1
AngularJS version 1.6,5
TypeScript version 2.3.4
Browser: Chrome 60.0.3112.90 (Official Build) (64-bit)

Visualizer for Sticky and DSR states ?

Hi,
I use the lastest @ui-router/visualizer with sticky and dsr states, but I've seen visualizer like this this on a previous versions, which contain details about sticky and dsr behavior.
Problem is with multiple try, I don't get the previous visualizer working. And it could be very helpfull ^^.
Is exist a way to make that visualizer with @ui-router ? or this need to be develop ?

Thx.

<uir-transitions-view></uir-transitions-view> didn't work

Hi, I got a error when html load first time.
In my Chrome console, showes this message.
Cannot convert undefined or null to object
at UirTransitionView.paramsForNode
at Array.map (native)

And uir-transitions-view directive, show raw code and didn't bind transition params.
Transition #{{::vm.trans.$id}}
From State: {{::vm.trans.from().name || '(root)'}}
To State: {{::vm.trans.to().name || '(root)'}}
Parameters:
Outcome: {{vm.status}}: {{vm.rejection}}
From Path To Path

Can you give me some suggestions about what's going wrong.

7.2.0 seems to break apps in IE11

Hi there, just a heads up... I updated to 7.2.0 and I was getting an error in the console for IE11 and the app wouldn't run--clicking on the error for the file brought me to the line in my screenshot below. There seems to be an arrow function that's not getting transpiled. 7.1.0 was doing the same so for the time being I've gone back to 7.0.

image

Transition tracing (debug)

Add a checkbox in State Visualizer to enable/disable trace.

 import {trace} from 'ui-router-ng2';
 trace.enable();

Problems with lazy loaded states

StateSelector doesn't update with the new states.

The StateVis is throwing an error about entering.map(node).forEach(n => n.entering) where n is undefined. It's then not updating the currently active state.

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on all branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because it uses your CI build statuses to figure out when to notify you about breaking changes.

Since we didn’t receive a CI status on the greenkeeper/initial branch, it’s possible that you don’t have CI set up yet. We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.

If you have already set up a CI for this repository, you might need to check how it’s configured. Make sure it is set to run on all new branches. If you don’t want it to run on absolutely every branch, you can whitelist branches starting with greenkeeper/.

Once you have installed and configured CI on this repository correctly, you’ll need to re-trigger Greenkeeper’s initial pull request. To do this, please delete the greenkeeper/initial branch in this repository, and then remove and re-add this repository to the Greenkeeper App’s white list on Github. You'll find this list on your repo or organization’s settings page, under Installed GitHub Apps.

a bug of visualizer.d.ts for ng2

In node_modules/@uirouter/visualizer/lib/visualizer.d.ts:

import { UIRouter, UIRouterPlugin } from "@uirouter/core";
should be:
import { UIRouter, UIRouterPlugin } from "@uirouter/angular";

If not, the following code will not be compiled:

import {UIRouter} from "@uirouter/angular";
import {Visualizer} from "@uirouter/visualizer";

/** UIRouter Config  */
export function uiRouterConfigFn(router: UIRouter) {
  router.urlService.rules.otherwise({state: 'hello'});

  router.plugin(Visualizer);
}

And the error message is:
ERROR in .../src/app/config/router.config.ts (11,17): Argument of type 'typeof Visualizer' is not assignable to parameter of type 'PluginFactory<UIRouterPlugin>'. Type 'typeof Visualizer' provides no match for the signature '(router: UIRouter, options?: any): UIRouterPlugin'.
Because the UIRouter comes from different files, although they have the same contents.

dependencies:

  "@angular/animations": "^4.0.0",
  ...
  "@uirouter/angular": "^1.0.0-beta.7",
  "@uirouter/visualizer": "^4.0.2",

Hooks not deregistering after component is destroyed

Im using angular 1.6.6 and @ui-router/angularjs 1.0.3. I'm registering onStart hooks in the constructor on the controller of one of my components. When ever I leave and reenter the component the hook registers itself again. I verify this by logging $transitions.getHooks('onStart')

Is this behaviour the expected one? I understood that hooks died after the component died as well.

[Feature][Chrome extension]

This can take advantage of having the visualizer in a separate window.
Thank you in advance for the great work!

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on all branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because it uses your CI build statuses to figure out when to notify you about breaking changes.

Since we didn’t receive a CI status on the greenkeeper/initial branch, it’s possible that you don’t have CI set up yet. We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.

If you have already set up a CI for this repository, you might need to check how it’s configured. Make sure it is set to run on all new branches. If you don’t want it to run on absolutely every branch, you can whitelist branches starting with greenkeeper/.

Once you have installed and configured CI on this repository correctly, you’ll need to re-trigger Greenkeeper’s initial pull request. To do this, please delete the greenkeeper/initial branch in this repository, and then remove and re-add this repository to the Greenkeeper App’s white list on Github. You'll find this list on your repo or organization’s settings page, under Installed GitHub Apps.

Cannot read property 'isCanceled' of undefined

If a transition hook rejects a transition with undefined, the visualizer pukes inside its catch block.

error_handler.js:54 EXCEPTION: Uncaught (in promise): TypeError: Cannot read property 'isCanceled' of undefined
TypeError: Cannot read property 'isCanceled' of undefined
    at a (http://localhost:4200/vendor.bundle.js:108228:4658)
    at ZoneDelegate.invoke (http://localhost:4200/polyfills.bundle.js:6559:26)
    at Object.onInvoke (http://localhost:4200/vendor.bundle.js:30885:37)
    at ZoneDelegate.invoke (http://localhost:4200/polyfills.bundle.js:6558:32)
    at Zone.run (http://localhost:4200/polyfills.bundle.js:6430:43)
    at http://localhost:4200/polyfills.bundle.js:6852:57
    at ZoneDelegate.invokeTask (http://localhost:4200/polyfills.bundle.js:6592:35)
    at Object.onInvokeTask (http://localhost:4200/vendor.bundle.js:30876:37)
    at ZoneDelegate.invokeTask (http://localhost:4200/polyfills.bundle.js:6591:40)
    at Zone.runTask (http://localhost:4200/polyfills.bundle.js:6468:47)
    at drainMicroTaskQueue (http://localhost:4200/polyfills.bundle.js:6750:35)
    at ZoneTask.invoke (http://localhost:4200/polyfills.bundle.js:6666:25)
    at data.args.(anonymous function) (http://localhost:4200/polyfills.bundle.js:7693:25)

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.