Giter Site home page Giter Site logo

domkit's Introduction

domkit's People

Contributors

bh213 avatar espeuteclement avatar klabz avatar ncannasse avatar onehundredfeet avatar r32 avatar speedphoenix avatar thalesalexcin avatar tobil4sk avatar trethaller avatar yuxiaomao 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

domkit's Issues

Reset visible to true

When setting visible:false in CSS and removing it (in heaps), visibility is reset to default (false) instead of true. We should have a way to define the default value.

Multiple CSS files, how to handle

I have multiple CSS files, main one and component specific ones.

They are all initialized like this (pseudo code):

	public function new(?parent:Object) {
		super(parent);
		initComponent();
                final newStyle = new h2d.domkit.Style();
                newStyle.load(hxd.Res.comp_style);
                newStyle.addObject(x);

The problem is that if I insert component with its own CSS into another component with its own CSS, original styling seems to get lost.
Example: Component AComp has applied a.css. AComp is inserted into BComp, which has the following SRC:

static var SRC = <b>
   <A id="a">
</B>;

B has b.css applied which does NOT have the same content as a.css. Styling of A component is lost. If styling (=css content) from a.css is copied to b.css everything works fine.

Are multiple CSS files supported or I am supposed to have one huge CSS file for the whole project?

Multiple classes attributes

When having multiple classes, right now it's necessary to write

<flow class={"base"+(cond ? " opt" : "")+(cond2 ? " opt2" : "")}/>

Here's an alternate syntax proposal for same result (only for class attribute)

<flow class={"base" : true, "opt" : cond, "opt2" : cond2 }/>

Could also be:

<flow class="base" classes={ "opt" : cond, "opt2" : cond2 }/>

Default component type resolution

According to the docs:

you can add @:uiComp("name") metadata in order to customize the component name

Components are resolved by name by adding Comp to the capitalized component name. For instance will try to load SomethingComp class from local context.

"Customize" implies that @:uiComp("name") is optional, and only necessary if you want a non-default name for the component. With the default resolution rules, this seems like it should work:

class SomethingComp extends h2d.Object implements h2d.domkit.Object {}

class SampleView extends h2d.Flow implements h2d.domkit.Object {
    static var SRC =
        <sample-view>
            <something />
        </sample-view>;

    public function new(tile:h2d.Tile,?parent) {
        super(parent);
        initComponent();
    }
}

However, instead, it gives the error:
src/SampleView.hx:5: characters 14-23 : SomethingComp does not define component something

It only works if @:uiComp("something") is added to SomethingComp.

Since it doesn't seem possible for the component name to be anything other than "something" (see #24), it really makes it hard to understand why this metadata is necessary at all.

Cannot compile examples on Haxe 3.4.7

I've noticed the issue here: HeapsIO/heaps#397 and thought that your promise on keeping backwards compatibility also relates to domkit (correct me if I'm wrong). Currently I'm getting this error on building examples (whether in heaps or domkit itself):

$ haxe test.hxml
../domkit/MarkupParser.hx:5: characters 5-13 : Unexpected abstract

Adding Bitmap to domkit component, bitmap.dom is null

I have a custom component (pseudo-code):

@:uiComp("ttt")
class TTTComp extends Flow implements h2d.domkit.Object{
static var SRC =
;

public function new(?parent) {
	super(parent);
	initComponent();
}

}

if I do the following:

final tttcomp = new TTTComp(parent);
final bitmap = new h2d.Bitmap(tile);
tttcomp.addChild(bitmap);

bitmap.dom will be null. This might be by design but as dom property is present I would expect it is possible to set it at the run-time. Or can it only be set in component constructor ()?

Thanks!

HL bytecode hot reload and DomKit

Is it possible to use HL's bytecode hot reload functionality to reload changes to the SRC markup at runtime?

I am currently able to do the reload and clear the children of a component and recreate it from the DomkitML, however it doesn't seem to pick up the actual changes made to the SRC variable, they stay the same. Is this even possible? How does Shiro test quick iterations on the markup?

Cheers

Transitions

Add transitions on int/float values:

xxx {
    transition : [property] [time] [speed-value-ref?] [curve?];
}
  • property : any domkit property (int/float) color ?
  • time : fixed time (1s)
  • speed-value-ref : can be used to adjust speed based on distance (ex : 1s 100 means move by 100 per 1s)
  • curve : easing curve (extensible framework for custom curves) -- allow parameters such as vibrate(10)

Interpolation of values:

  • we start at S, target value is E, time is T
  • if we have speed-value-ref R value, duration is adjusted as T' = abs(E - S) * T / R
  • we update progress P% each frame
  • if there is a change during a transition, we update progress to account for current value (example : [0,100,1s] -> break at 50% (value=50) -> set new target 25 --> [100,25,1s] at 66%) (TODO:how this works on colors?)
  • transitions are set on the target class, not on the source one (transitions on source are lost when class gets updated)

Rebuild / Bind

In order to allow for UI self-rebuild and automatic update within DomkitML declaration, we will introduce new metadata:

<flow class="icons" if( @rebuild isMine() )>
  for( i in @rebuild getIcons() )
     <icon(i) value={@bind i.progress}/>
</flow>

Gets translated to:

<flow class="icons" if( registerCheckRebuild(()->isMine()) )>
  for( i in registerCheckRebuild(() -> getIcons()) ) {
     <icon(i) id="__tmp"/>
     registerBind(() __tmp.value = i.progress);
  }
</flow>

registerCheckRebuild can then be implemented on the framework base class to perform regular checks and rebuild the UI if data has changed, and registerBind for updating values regularly.

We also need something like:

@rebuild var p = getStruct();
for( i in @rebuild p.icons ) {
}

That translates to:

var p;
registerCheckRebuild(() -> { p = getStruct(); true; });
for( i in registerCheckRebuild(() -> p.icons) ) {
}

So some vars can be updated before following rebuilds take place.

Incorrect CSS Id selector for component arrays

This will correctly produce a CSS selector as #foo-item:

<div id="foo-item"/>

This however will unexpectedly produce a CSS selector as #fooItem:

<div id="foo-item[]"/>

I would expect both to produce #foo-item

Thanks in advance!

Failed to load module

When defining a typedef with an unknown type and loading this module through domkit, we don't get the actual error but instead (could not load module)

:odd and :even not being refreshed

Can domkit components be dynamically added or removed to the scene, e.g. as a result of button click and have CSS properly applied?

I also noticed that :first-child & :last-child don't work with such dynamically added components (=outside component constructor) ..

I'd like to add proper example of how to add and remove components if there exists an "official way". Thanks.

See https://github.com/bh213/heaps-domkit-sample

Domkit License unclear

DomKit has no explicit license set on GitHub. Haxelib.json says BSD. Is that correct? Heaps is MIT, any reason for the difference there?

Sorry for nagging so much ;-) Happy new year!

Multiple classes selector bug

This code:

	static var SRC =
	<mydiv class="foo">
		<mydiv public id="sub" class="bar"></mydiv>
	</mydiv>

together with this css:

.unused.bar {
	padding-left: 10;
}

will give sub a paddingLeft of 10. It looks like a bug since the .unused.bar multiple selector shouldn't match sub, which only has class bar.

domkit css parsing support broken in javascript

When using latest heaps and domkit, hashlink version works correctly while javascript css file parsing produces no rules.

I believe this was caused by 21c751a and I think that the issue is in this line as all classes are recognized as erased.

if( c.className == ERASED ) {

Didn't debug too deep so details might be wrong. Example:

This works:
https://github.com/bh213/heaps-domkit-sample

and this one does not (js only, hl works for both):
bh213/heaps-domkit-sample@ce416aa

Issue with for iterator

<h-hud>
			<bitmap class="f" src={icon} if( icon != null )/>
			<flow class="hp">
				for( i in 0...4 )
					<icon(Hp) class={((i >= hp) ? "grey" : "")}/>
			</flow>
</h-hud>

This does not work (Cannot use Void as value), because of 0...4 it seems

Type not found : Document

I'm trying to build the sample, however I'm getting:

domkit/Builder.hx:18: characters 54-65 : Type not found : Document

It looks like Document was removed many commits ago (July).

I'm using the git versions of heaps, and rc4 of Haxe (though have tried a few different version combinations). Are there any tricks to getting the sample to build?

Thank you :)

haxelib version is not up to date with Heaps

You can reproduce this problem by installing heaps and domkit from haxelib.

Build error is:
Unknown identifier : parseFloatPercent

parseFloatPercent is present inside domkit master branch but at 0.2.0 release(which is on haxelib) is not.

Array alloc in applyStyle

The call to obj.getChildren() causes an hl.types.$ArrayDyn.alloc on hashlink.

	var obj : Model<Dynamic> = e.obj;
	for( c in obj.getChildren() ) {
		var c : Model<Dynamic> = c;
		if( c.dom == null )
			continue;
		applyStyle(c.dom, force);
	}

Considering applyStyle is one of the performance critical spots, maybe a tiny #if domkit_heaps would be worth it here?

A simple component causes: "domkit.Identifier should be String"

If I compile the following example:

@:uiComp("view")
class ViewComp extends h2d.Flow implements h2d.domkit.Object {
    static var SRC = <view><text text="text" /></view>
}

class Main extends hxd.App {
    override function init() { }
    static function main() { new Main(); }
}

I always get the same error: "domkit.Identifier should be String" and not much more.
The full error is: "haxe\lib\heaps/1,10,0/h2d/domkit/BaseComponents.hx:550: characters 3-37 : domkit.Identifier should be String"

The installed modules are as follows:

domkit: [git]
format: [3.6.0]
heaps: [1.10.0]
hldx: [1.13.0]
hlopenal: [1.5.0]
hlsdl: [1.13.0]


I would expect this example to compile, or is there a wrong Id being passed for some reason?

[Regression] Text node issue

Starting with commit (9854301)
support for inline text is no longer working as expected and gives aInvalid Code Block error.

Example:

static var SRC = <somediv>
     Some Text //<--- no longer works
</somediv>

Domkit sample in Heaps + example in docs doesn't compile

Hello there ๐Ÿ‘‹ Beginner Heaps developer here. Got here because of the Unity mess and Heaps seems like a really cool and promising engine.

Disclaimer
Not sure if this issue belongs to this repo or to the Heaps repo. Let me know if you want me to report the same issue in the other repo.

The issue

I'm not able to compile either:

  1. The domkit sample in the Heaps repo.
  2. Adding the SampleView from the docs to the Hello Hashlink example.

Steps to reproduce #1

  1. Clone Heaps repo
  2. Follow the samples instruction in README.md.
    2b) Generate build directory
    2c) Compile for Hashlink using haxe ./build/domkit/domkit_hl.hxml from the samples directory.

The following error is shown:

/usr/local/lib/haxe/lib/heaps/1,10,0/hxd/impl/Allocator.hx:3: characters 1-7 : Warning : (WDeprecatedEnumAbstract) `@:enum abstract` is deprecated in favor of `enum abstract`
/usr/local/lib/haxe/lib/heaps/1,10,0/h3d/scene/Object.hx:3: characters 1-7 : Warning : (WDeprecatedEnumAbstract) `@:enum abstract` is deprecated in favor of `enum abstract`
/usr/local/lib/haxe/lib/heaps/1,10,0/h3d/mat/Material.hx:3: characters 1-7 : Warning : (WDeprecatedEnumAbstract) `@:enum abstract` is deprecated in favor of `enum abstract`
/usr/local/lib/haxe/lib/heaps/1,10,0/h3d/scene/Object.hx:391: characters 2-9 : Warning : (WDeprecated) `@:final` is deprecated in favor of `final`
/usr/local/lib/haxe/lib/heaps/1,10,0/h3d/scene/Object.hx:622: characters 2-9 : Warning : (WDeprecated) `@:final` is deprecated in favor of `final`
/usr/local/lib/haxe/lib/heaps/1,10,0/h3d/shader/Buffers.hx:3: characters 1-7 : Warning : (WDeprecatedEnumAbstract) `@:enum abstract` is deprecated in favor of `enum abstract`
/usr/local/lib/haxe/lib/heaps/1,10,0/hxd/Pixels.hx:84: characters 1-7 : Warning : (WDeprecatedEnumAbstract) `@:enum abstract` is deprecated in favor of `enum abstract`
/usr/local/lib/haxe/lib/hlsdl/1,13,0/sdl/Cursor.hx:5: characters 1-7 : Warning : (WDeprecatedEnumAbstract) `@:enum abstract` is deprecated in favor of `enum abstract`
/usr/local/lib/haxe/lib/hlsdl/1,13,0/sdl/Window.hx:7: characters 1-7 : Warning : (WDeprecatedEnumAbstract) `@:enum abstract` is deprecated in favor of `enum abstract`
/usr/local/lib/haxe/lib/hlsdl/1,13,0/sdl/Event.hx:23: characters 1-7 : Warning : (WDeprecatedEnumAbstract) `@:enum abstract` is deprecated in favor of `enum abstract`
/usr/local/lib/haxe/lib/hlsdl/1,13,0/sdl/Event.hx:51: characters 1-7 : Warning : (WDeprecatedEnumAbstract) `@:enum abstract` is deprecated in favor of `enum abstract`
/usr/local/lib/haxe/lib/heaps/1,10,0/h2d/Font.hx:110: characters 1-7 : Warning : (WDeprecatedEnumAbstract) `@:enum abstract` is deprecated in favor of `enum abstract`
/usr/local/lib/haxe/lib/heaps/1,10,0/hxd/Pixels.hx:84: characters 1-7 : Warning : (WDeprecatedEnumAbstract) `@:enum abstract` is deprecated in favor of `enum abstract`
/usr/local/lib/haxe/lib/heaps/1,10,0/h3d/shader/Buffers.hx:3: characters 1-7 : Warning : (WDeprecatedEnumAbstract) `@:enum abstract` is deprecated in favor of `enum abstract`
/usr/local/lib/haxe/lib/heaps/1,10,0/hxd/impl/Allocator.hx:3: characters 1-7 : Warning : (WDeprecatedEnumAbstract) `@:enum abstract` is deprecated in favor of `enum abstract`
/usr/local/lib/haxe/lib/heaps/1,10,0/h2d/Font.hx:110: characters 1-7 : Warning : (WDeprecatedEnumAbstract) `@:enum abstract` is deprecated in favor of `enum abstract`
/usr/local/lib/haxe/lib/heaps/1,10,0/hxd/res/Image.hx:3: characters 1-7 : Warning : (WDeprecatedEnumAbstract) `@:enum abstract` is deprecated in favor of `enum abstract`
/usr/local/lib/haxe/lib/heaps/1,10,0/hxd/fmt/hmd/Data.hx:3: characters 1-7 : Warning : (WDeprecatedEnumAbstract) `@:enum abstract` is deprecated in favor of `enum abstract`
/usr/local/lib/haxe/lib/hlsdl/1,13,0/sdl/Sdl.hx:238: characters 1-7 : Warning : (WDeprecatedEnumAbstract) `@:enum abstract` is deprecated in favor of `enum abstract`
/usr/local/lib/haxe/lib/heaps/1,10,0/h2d/domkit/BaseComponents.hx:550: characters 3-37 : domkit.Identifier should be String
/usr/local/lib/haxe/lib/heaps/1,10,0/hxd/fmt/hmd/Data.hx:3: characters 1-7 : Warning : (WDeprecatedEnumAbstract) `@:enum abstract` is deprecated in favor of `enum abstract`
/usr/local/lib/haxe/lib/heaps/1,10,0/hxd/res/Image.hx:3: characters 1-7 : Warning : (WDeprecatedEnumAbstract) `@:enum abstract` is deprecated in favor of `enum abstract`
/usr/local/lib/haxe/lib/heaps/1,10,0/hxd/Res.hx:4: characters 1-8 : Uncaught exception Failure("get_full_path")
/usr/local/lib/haxe/lib/heaps/1,10,0/hxd/res/FileTree.hx:47: characters 15-43 : Called from here
/usr/local/lib/haxe/lib/heaps/1,10,0/hxd/res/FileTree.hx:30: characters 16-33 : Called from here
/usr/local/lib/haxe/lib/heaps/1,10,0/hxd/res/FileTree.hx:383: characters 10-27 : Called from here
/usr/local/lib/haxe/lib/heaps/1,10,0/hxd/Res.hx:4: characters 1-8 : Called from here
/usr/local/lib/haxe/lib/heaps/1,10,0/hxd/Res.hx:4: characters 1-8 : For function argument 'r'
Domkit.hx:118: characters 11-20 : Class<hxd.Res> has no field initLocal

Steps to reproduce #2

  1. Clone this repo.
  2. Checkout branch try-domkit
  3. Compile the project by either:
    3b) Hitting F5 or...
    3c) Run haxe compile.hxml from the root of the repo.

The following error is shown:

/usr/local/lib/haxe/lib/heaps/1,10,0/hxd/impl/Allocator.hx:3: characters 1-7 : Warning : (WDeprecatedEnumAbstract) `@:enum abstract` is deprecated in favor of `enum abstract`
/usr/local/lib/haxe/lib/heaps/1,10,0/h2d/Font.hx:110: characters 1-7 : Warning : (WDeprecatedEnumAbstract) `@:enum abstract` is deprecated in favor of `enum abstract`
/usr/local/lib/haxe/lib/heaps/1,10,0/hxd/Pixels.hx:84: characters 1-7 : Warning : (WDeprecatedEnumAbstract) `@:enum abstract` is deprecated in favor of `enum abstract`
/usr/local/lib/haxe/lib/heaps/1,10,0/h3d/shader/Buffers.hx:3: characters 1-7 : Warning : (WDeprecatedEnumAbstract) `@:enum abstract` is deprecated in favor of `enum abstract`
/usr/local/lib/haxe/lib/heaps/1,10,0/hxd/impl/Allocator.hx:3: characters 1-7 : Warning : (WDeprecatedEnumAbstract) `@:enum abstract` is deprecated in favor of `enum abstract`
/usr/local/lib/haxe/lib/heaps/1,10,0/h2d/Font.hx:110: characters 1-7 : Warning : (WDeprecatedEnumAbstract) `@:enum abstract` is deprecated in favor of `enum abstract`
src/Main.hx:14: characters 13-25 : Unsupported code block
src/Main.hx:11: character 1 : Build failure

Thoughts

Seems to me (but hey I'm a noob to Hexe and Heaps) that domkit hasn't been updated to match the API changes in the heaps package. Or maybe there is a mismatch of my local deps. I followed the getting started guide to setup everything so I should have the lastest of all the packges though.

FlowComp does not define flow / compilation server (heaps domkit sample)

Testing domkit in heaps / samples / domkit -- I get the following error on the 2nd compile after a small change in sample's class Domkit, unless I restart the compilation server:

> Executing task: haxe --connect 6000 domkit_hl.hxml <

/home/jward/dev/domkit/domkit/Macros.hx:391: characters 3-8 : Uncaught exception UIKitError(h2d.domkit.FlowComp does not define component flow) 0
/home/jward/dev/domkit/domkit/Macros.hx:85: characters 4-78 : Called from here
/home/jward/dev/domkit/domkit/MetaComponent.hx:48: characters 38-69 : Called from here
/home/jward/dev/domkit/domkit/Macros.hx:360: characters 13-62 : Called from here
/home/jward/dev/heaps/h2d/domkit/InitComponents.hx:18: characters 10-37 : Called from here
./Domkit.hx:62: character 1 : Called from here
The terminal process command 'haxe --connect 6000 domkit_hl.hxml' failed to launch (exit code: 1)

Heaps and domkit are both git / master. This is against Haxe 4.0.0-rc3.

I tried a Haxe nightly from today, but the compilation server wouldn't start, with:

/home/jward/dev/heaps/hxsl/MacroParser.hx:170: characters 12-16 : haxe.macro.FunctionKind should be String
/home/jward/dev/heaps/hxsl/MacroParser.hx:170: characters 12-16 : For function argument 'f'
/home/jward/dev/heaps/hxsl/MacroParser.hx:168: lines 168-185 : Void should be hxsl.ExprDef
/home/jward/dev/heaps/hxsl/BatchShader.hx:3: character 1 : Build failure

Uncaught TypeError (JavaScript target)

After domkit commit 366bd67 and heaps commit HeapsIO/heaps@8e4ac8f
I get an error when trying to add object to style style.addObject(container);
Only happens on JavaScript target.

This is the error:

CssStyle.hx:350 Uncaught TypeError: Cannot read properties of undefined (reading 'fill')
    at h2d_domkit_Style.applyStyle (CssStyle.hx:350:3)
    at domkit_Properties.applyStyle (Properties.hx:95:3)
    at h2d_domkit_Style.addObject (Style.hx:36:3)
    at new game_stages_MainMenu (MainMenu.hx:34:3)
    at Application.init (Application.hx:49:13)
    at App.hx:148:4
    at Application.loadAssets (App.hx:176:3)
    at Application.setup (App.hx:146:3)
    at h3d_Engine.onCreate (Engine.hx:256:4)
    at onLoad (GlDriver.hx:1610:5)

@:uiComp metadata behavior

The purpose of @:uiComp is unclear to me. The documentation states "[...] add @:uiComp("name") metadata in order to customize the component name", which suggests that the component can be given a different Tag name from its class name. However the macro uses that custom name to find the class of the component in the search paths, which now differs and cannot be found. How is this intended to be used/be useful?

Example:

// BlinkingComp.hx
@:uiComp("blink")
class BlinkingComp extends h2d.Object implements h2d.domkit.Object {}

// Usage in some SRC
<blink/>

This won't work, as it will try to find BlinkComp class

h2d.domkit.FlowComp does not define component flow

Whenever I make an error in the code, I get

/home/mike/haxelib/domkit/git/domkit/Macros.hx:402: characters 3-8 : Uncaught exception UIKitError(h2d.domkit.FlowComp does not define component flow) 0
/home/mike/haxelib/domkit/git/domkit/Macros.hx:87: characters 4-78 : Called from here
/home/mike/haxelib/domkit/git/domkit/MetaComponent.hx:48: characters 38-69 : Called from here
/home/mike/haxelib/domkit/git/domkit/Macros.hx:371: characters 13-62 : Called from here
/home/mike/haxelib/heaps/1,7,0/h2d/domkit/InitComponents.hx:18: characters 10-37 : Called from here
ui/Main.hx:64: character 1 : Called from here
The terminal process terminated with exit code: 1

I have to restart the language sever and I can't see the actual bug in the code. Not a huge deal but a bit annoying.

Speed up rule selection

Currently we check all CSS rules for each object. It's very fast but it doesn't scale with huge CSS files.

I tried implementing the following approach : filter top rules by (component+id) but it didn't work out very well. Reduces checks by only about 30%, because

I guess we might need a more top-down approach were we reconstruct the Rule tree then filter based on parent-contextual rules.

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.