Giter Site home page Giter Site logo

CLJS serialization story for SVG about geom HOT 12 CLOSED

thi-ng avatar thi-ng commented on August 26, 2024
CLJS serialization story for SVG

from geom.

Comments (12)

postspectacular avatar postspectacular commented on August 26, 2024 3

Hi @den1k - just checked in 2 pieces of functionality which now cause no more warnings when using the viz module with Reagent (still not tried with sablono or any other Om related libs).

Seqs of elements in SVG groups now have one level less of nesting and you'll need to insert a call to inject-element-attribs (in the thi.ng.geom.svg.adapter ns). This fn will generate unique IDs for each element in the SVG hiccup structure.

The below is a complete reagent component for reference:

(defn visualization
  "Takes a geom.viz visualization spec map and generates a SVG component.
  The call to inject-element-attribs ensures that all SVG elements have
  an unique :key attribute, required for React.js."
  [spec]
  (->> spec
       (viz/svg-plot2d-cartesian)
       (svgadapt/inject-element-attribs svgadapt/key-attrib-injector)
       (svg/svg {:width 600 :height 600})))

It'd be great if you could test this with any of the other libs.
Latest release version is: [thi.ng/geom "0.0.908"]

from geom.

postspectacular avatar postspectacular commented on August 26, 2024

I'm more of a reagent kinda person, so no 1st hand experience with sablono / om... But am really suprised that the bar graph fails of all the methods (which only uses rects & lines). Do you get an error or it just doesn't produce a DOM fragment? The svg-plot2d-cartesian just produces hiccup vectors with nothing special. However for React components the issue is that attribs like :fill, :stroke etc. need to be nested under the :style key in the :attribs map. So instead of:

:attribs {:fill "none" :stroke "#0af"}

...you'll need to state these as:

:attribs {:style {:fill "none" :stroke "#0af"}}

(I don't know if that's the same in Om, but I guess so...)

For a non-React based example, check out the SVG physics demo here:

Source: https://github.com/thi-ng/demos/blob/master/geom/src/physics_demos/strands.cljs
Live: http://demo.thi.ng/geom/physics/strands.html

This demo uses the hiccup serializer in the domus lib

from geom.

den1k avatar den1k commented on August 26, 2024

The line-plot actually renders perfectly, apparently chrome also accepts tag attributes for properties like fill. I got really excited when it worked. I thought: finally a D3 replacement where I could add event handlers in a data transformation step before passing it to sablono.
The bar graph breaks something in sablono's html macro. The grid renders properly. Everything else ends up outside of the svg tag, rendered in spans as react does with strings:
screen shot 2015-10-13 at 9 36 58 pm

from geom.

postspectacular avatar postspectacular commented on August 26, 2024

I think this is really a shortcoming of sablono and other serializers. The bar graph hiccup looks like this below and serializes fine into an SVG DOM using my domus lib or in CLJ w/ hiccup:

[:g
 nil
 ([:g
   {:stroke "#ccc", :stroke-dasharray "1 1"}
   (([:line {:x1 "50.00", :y1 "280.00", :x2 "50.00", :y2 "20.00"}]
     [:line {:x1 "81.18", :y1 "280.00", :x2 "81.18", :y2 "20.00"}]
     ...)
    ([:line {:x1 "50.00", :y1 "267.00", :x2 "580.00", :y2 "267.00"}]
     [:line {:x1 "50.00", :y1 "241.00", :x2 "580.00", :y2 "241.00"}]
     ...))]
  ([:g
    {:stroke "#0af", :stroke-width "19px"}
    (([:line {:x1 "81.18", :y1 "195.10", :x2 "81.18", :y2 "280.00"}]
      ...))])
  [:g
   {:stroke "black"}
   (([:line {:x1 "50.00", :y1 "280.00", :x2 "50.00", :y2 "290.00"}]
     ...)
    ()
    [:g
     {:stroke "none",
      :fill "black",
      :font-family "Arial, sans-serif",
      :font-size 10,
      :text-anchor "middle"}
     (([:text {:x "50.00", :y "300.00"} 1999]
       ...))]
    [:line {:x1 "50.00", :y1 "280.00", :x2 "580.00", :y2 "280.00"}])]
  [:g
   {:stroke "black"}
   (([:line {:x1 "50.00", :y1 "280.00", :x2 "40.00", :y2 "280.00"}]
     ...)
    ([:line {:x1 "50.00", :y1 "267.00", :x2 "45.00", :y2 "267.00"}]
     ...)
    [:g
     {:stroke "none",
      :fill "black",
      :font-family "Arial, sans-serif",
      :font-size 10,
      :text-anchor "end"}
     (([:text {:x "35.00", :y "280.00"} "0.00"]
       ...))]
    [:line {:x1 "50.00", :y1 "280.00", :x2 "50.00", :y2 "20.00"}])])]

I guess, it's the nested seqs which cause the serialization "hiccup" (pun intended! :) Will have to check if I can switch to mapcat somewhere.

from geom.

den1k avatar den1k commented on August 26, 2024

thanks @postspectacular I'm a huge fan of the geom toolkit. Looking forward to use it more & more in the future!

from geom.

den1k avatar den1k commented on August 26, 2024

Thanks @postspectacular for adding keys! The bar chart now renders properly. I checked the line chart which has extra numbers in it's last svg group node.
It appears that the group should contain svg text nodes but instead it has plain numbers which react renders as spans.

This is the group:

[:g
   {:stroke "none",
    :fill "black",
    :font-family "Arial, sans-serif",
    :font-size 10,
    :text-anchor "middle",
    :key "G__2367"}
   -1
   -0.8
   -0.6000000000000001
   -0.4000000000000001
   -0.20000000000000007
   -5.551115123125783e-17
   0.19999999999999996
   0.39999999999999997
   0.6
   0.8
   1]

Render Output:
om tutorial 2015-11-10 14-23-17

Full output with injected keys:

[:g
 {:key "G__2370"}
 [:g
  {:stroke "#caa", :stroke-dasharray "1 1", :key "G__2319"}
  ([:line
    {:x1 "50.00",
     :y1 "250.00",
     :x2 "50.00",
     :y2 "20.00",
     :key "G__2285"}]
   [:line
    {:x1 "182.50",
     :y1 "250.00",
     :x2 "182.50",
     :y2 "20.00",
     :key "G__2286"}]
   [:line
    {:x1 "315.00",
     :y1 "250.00",
     :x2 "315.00",
     :y2 "20.00",
     :key "G__2287"}]
   [:line
    {:x1 "447.50",
     :y1 "250.00",
     :x2 "447.50",
     :y2 "20.00",
     :key "G__2288"}]
   [:line
    {:x1 "580.00",
     :y1 "250.00",
     :x2 "580.00",
     :y2 "20.00",
     :key "G__2289"}])
  ([:line
    {:x1 "50.00",
     :y1 "238.50",
     :x2 "580.00",
     :y2 "238.50",
     :key "G__2290"}]
   [:line
    {:x1 "50.00",
     :y1 "215.50",
     :x2 "580.00",
     :y2 "215.50",
     :key "G__2291"}]
   [:line
    {:x1 "50.00",
     :y1 "192.50",
     :x2 "580.00",
     :y2 "192.50",
     :key "G__2292"}]
   [:line
    {:x1 "50.00",
     :y1 "181.00",
     :x2 "580.00",
     :y2 "181.00",
     :key "G__2293"}]
   [:line
    {:x1 "50.00",
     :y1 "169.50",
     :x2 "580.00",
     :y2 "169.50",
     :key "G__2294"}]
   [:line
    {:x1 "50.00",
     :y1 "158.00",
     :x2 "580.00",
     :y2 "158.00",
     :key "G__2295"}]
   [:line
    {:x1 "50.00",
     :y1 "146.50",
     :x2 "580.00",
     :y2 "146.50",
     :key "G__2296"}]
   [:line
    {:x1 "50.00",
     :y1 "135.00",
     :x2 "580.00",
     :y2 "135.00",
     :key "G__2297"}]
   [:line
    {:x1 "50.00",
     :y1 "123.50",
     :x2 "580.00",
     :y2 "123.50",
     :key "G__2298"}]
   [:line
    {:x1 "50.00",
     :y1 "112.00",
     :x2 "580.00",
     :y2 "112.00",
     :key "G__2299"}]
   [:line
    {:x1 "50.00",
     :y1 "100.50",
     :x2 "580.00",
     :y2 "100.50",
     :key "G__2300"}]
   [:line
    {:x1 "50.00",
     :y1 "89.00",
     :x2 "580.00",
     :y2 "89.00",
     :key "G__2301"}]
   [:line
    {:x1 "50.00",
     :y1 "77.50",
     :x2 "580.00",
     :y2 "77.50",
     :key "G__2302"}]
   [:line
    {:x1 "50.00",
     :y1 "66.00",
     :x2 "580.00",
     :y2 "66.00",
     :key "G__2303"}]
   [:line
    {:x1 "50.00",
     :y1 "54.50",
     :x2 "580.00",
     :y2 "54.50",
     :key "G__2304"}]
   [:line
    {:x1 "50.00",
     :y1 "43.00",
     :x2 "580.00",
     :y2 "43.00",
     :key "G__2305"}]
   [:line
    {:x1 "50.00",
     :y1 "31.50",
     :x2 "580.00",
     :y2 "31.50",
     :key "G__2306"}]
   [:line
    {:x1 "50.00",
     :y1 "20.00",
     :x2 "580.00",
     :y2 "20.00",
     :key "G__2307"}]
   [:line
    {:x1 "50.00",
     :y1 "250.00",
     :x2 "580.00",
     :y2 "250.00",
     :key "G__2308"}]
   [:line
    {:x1 "50.00",
     :y1 "227.00",
     :x2 "580.00",
     :y2 "227.00",
     :key "G__2309"}]
   [:line
    {:x1 "50.00",
     :y1 "204.00",
     :x2 "580.00",
     :y2 "204.00",
     :key "G__2310"}]
   [:line
    {:x1 "50.00",
     :y1 "181.00",
     :x2 "580.00",
     :y2 "181.00",
     :key "G__2311"}]
   [:line
    {:x1 "50.00",
     :y1 "158.00",
     :x2 "580.00",
     :y2 "158.00",
     :key "G__2312"}]
   [:line
    {:x1 "50.00",
     :y1 "135.00",
     :x2 "580.00",
     :y2 "135.00",
     :key "G__2313"}]
   [:line
    {:x1 "50.00",
     :y1 "112.00",
     :x2 "580.00",
     :y2 "112.00",
     :key "G__2314"}]
   [:line
    {:x1 "50.00",
     :y1 "89.00",
     :x2 "580.00",
     :y2 "89.00",
     :key "G__2315"}]
   [:line
    {:x1 "50.00",
     :y1 "66.00",
     :x2 "580.00",
     :y2 "66.00",
     :key "G__2316"}]
   [:line
    {:x1 "50.00",
     :y1 "43.00",
     :x2 "580.00",
     :y2 "43.00",
     :key "G__2317"}]
   [:line
    {:x1 "50.00",
     :y1 "20.00",
     :x2 "580.00",
     :y2 "20.00",
     :key "G__2318"}])]
 ([:polygon
   {:fill "#0af",
    :points
    "50.00,135.00 52.65,133.25 55.30,132.15 57.95,134.87 60.60,140.39 63.25,143.96 65.90,141.29 68.55,132.58 71.20,122.96 73.85,119.11 76.50,124.66 79.15,137.62 81.80,151.35 84.45,158.32 87.10,154.21 89.75,140.13 92.40,122.00 95.05,107.68 97.70,103.45 100.35,111.46 103.00,129.08 105.65,150.21 108.30,167.65 110.95,175.64 113.60,171.61 116.25,156.65 118.90,134.91 121.55,112.13 124.20,93.97 126.85,84.67 129.50,86.15 132.15,97.89 134.80,117.33 137.45,140.65 140.10,163.61 142.75,182.43 145.40,194.32 148.05,197.82 150.70,192.80 153.35,180.30 156.00,162.20 158.65,140.85 161.30,118.69 163.95,97.97 166.60,80.51 169.25,67.63 171.90,60.05 174.55,57.96 177.20,61.12 179.85,68.92 182.50,80.52 185.15,94.95 187.80,111.23 190.45,128.41 193.10,145.63 195.75,162.19 198.40,177.51 201.05,191.18 203.70,202.93 206.35,212.61 209.00,220.19 211.65,225.72 214.30,229.30 216.95,231.12 219.60,231.35 222.25,230.21 224.90,227.91 227.55,224.66 230.20,220.66 232.85,216.09 235.50,211.11 238.15,205.86 240.80,200.48 243.45,195.07 246.10,189.71 248.75,184.48 251.40,179.44 254.05,174.63 256.70,170.08 259.35,165.81 262.00,161.85 264.65,158.20 267.30,154.86 269.95,151.83 272.60,149.11 275.25,146.68 277.90,144.54 280.55,142.67 283.20,141.05 285.85,139.67 288.50,138.52 291.15,137.57 293.80,136.81 296.45,136.22 299.10,135.77 301.75,135.44 304.40,135.23 307.05,135.10 309.70,135.03 312.35,135.00 315.00,135.00 317.65,135.00 320.30,134.97 322.95,134.90 325.60,134.77 328.25,134.56 330.90,134.23 333.55,133.78 336.20,133.19 338.85,132.43 341.50,131.48 344.15,130.33 346.80,128.95 349.45,127.33 352.10,125.46 354.75,123.32 357.40,120.89 360.05,118.17 362.70,115.14 365.35,111.80 368.00,108.15 370.65,104.19 373.30,99.92 375.95,95.37 378.60,90.56 381.25,85.52 383.90,80.29 386.55,74.93 389.20,69.52 391.85,64.14 394.50,58.89 397.15,53.91 399.80,49.34 402.45,45.34 405.10,42.09 407.75,39.79 410.40,38.65 413.05,38.88 415.70,40.70 418.35,44.28 421.00,49.81 423.65,57.39 426.30,67.07 428.95,78.82 431.60,92.49 434.25,107.81 436.90,124.37 439.55,141.59 442.20,158.77 444.85,175.05 447.50,189.48 450.15,201.08 452.80,208.88 455.45,212.04 458.10,209.95 460.75,202.37 463.40,189.49 466.05,172.03 468.70,151.31 471.35,129.15 474.00,107.80 476.65,89.70 479.30,77.20 481.95,72.18 484.60,75.68 487.25,87.57 489.90,106.39 492.55,129.35 495.20,152.67 497.85,172.11 500.50,183.85 503.15,185.33 505.80,176.03 508.45,157.87 511.10,135.09 513.75,113.35 516.40,98.39 519.05,94.36 521.70,102.35 524.35,119.79 527.00,140.92 529.65,158.54 532.30,166.55 534.95,162.32 537.60,148.00 540.25,129.87 542.90,115.79 545.55,111.68 548.20,118.65 550.85,132.38 553.50,145.34 556.15,150.89 558.80,147.04 561.45,137.42 564.10,128.71 566.75,126.04 569.40,129.61 572.05,135.13 574.70,137.85 577.35,136.75 580.00,135.00 580.00,250.00 50.00,250.00",
    :key "G__2320"}])
 [:g
  {:stroke "black", :key "G__2337"}
  ([:line
    {:x1 "50.00",
     :y1 "250.00",
     :x2 "50.00",
     :y2 "260.00",
     :key "G__2321"}]
   [:line
    {:x1 "182.50",
     :y1 "250.00",
     :x2 "182.50",
     :y2 "260.00",
     :key "G__2322"}]
   [:line
    {:x1 "315.00",
     :y1 "250.00",
     :x2 "315.00",
     :y2 "260.00",
     :key "G__2323"}]
   [:line
    {:x1 "447.50",
     :y1 "250.00",
     :x2 "447.50",
     :y2 "260.00",
     :key "G__2324"}]
   [:line
    {:x1 "580.00",
     :y1 "250.00",
     :x2 "580.00",
     :y2 "260.00",
     :key "G__2325"}])
  ([:line
    {:x1 "116.25",
     :y1 "250.00",
     :x2 "116.25",
     :y2 "255.00",
     :key "G__2326"}]
   [:line
    {:x1 "248.75",
     :y1 "250.00",
     :x2 "248.75",
     :y2 "255.00",
     :key "G__2327"}]
   [:line
    {:x1 "381.25",
     :y1 "250.00",
     :x2 "381.25",
     :y2 "255.00",
     :key "G__2328"}]
   [:line
    {:x1 "513.75",
     :y1 "250.00",
     :x2 "513.75",
     :y2 "255.00",
     :key "G__2329"}])
  [:g
   {:stroke "none",
    :fill "black",
    :font-family "Arial, sans-serif",
    :font-size 10,
    :text-anchor "middle",
    :key "G__2335"}
   [:text {:x "50.00", :y "270.00", :key "G__2330"} "-3.14"]
   [:text {:x "182.50", :y "270.00", :key "G__2331"} "-1.57"]
   [:text {:x "315.00", :y "270.00", :key "G__2332"} "0.00"]
   [:text {:x "447.50", :y "270.00", :key "G__2333"} "1.57"]
   [:text {:x "580.00", :y "270.00", :key "G__2334"} "3.14"]]
  [:line
   {:x1 "50.00",
    :y1 "250.00",
    :x2 "580.00",
    :y2 "250.00",
    :key "G__2336"}]]
 [:g
  {:stroke "black", :key "G__2369"}
  ([:line
    {:x1 "50.00",
     :y1 "250.00",
     :x2 "40.00",
     :y2 "250.00",
     :key "G__2338"}]
   [:line
    {:x1 "50.00",
     :y1 "227.00",
     :x2 "40.00",
     :y2 "227.00",
     :key "G__2339"}]
   [:line
    {:x1 "50.00",
     :y1 "204.00",
     :x2 "40.00",
     :y2 "204.00",
     :key "G__2340"}]
   [:line
    {:x1 "50.00",
     :y1 "181.00",
     :x2 "40.00",
     :y2 "181.00",
     :key "G__2341"}]
   [:line
    {:x1 "50.00",
     :y1 "158.00",
     :x2 "40.00",
     :y2 "158.00",
     :key "G__2342"}]
   [:line
    {:x1 "50.00",
     :y1 "135.00",
     :x2 "40.00",
     :y2 "135.00",
     :key "G__2343"}]
   [:line
    {:x1 "50.00",
     :y1 "112.00",
     :x2 "40.00",
     :y2 "112.00",
     :key "G__2344"}]
   [:line
    {:x1 "50.00",
     :y1 "89.00",
     :x2 "40.00",
     :y2 "89.00",
     :key "G__2345"}]
   [:line
    {:x1 "50.00",
     :y1 "66.00",
     :x2 "40.00",
     :y2 "66.00",
     :key "G__2346"}]
   [:line
    {:x1 "50.00",
     :y1 "43.00",
     :x2 "40.00",
     :y2 "43.00",
     :key "G__2347"}]
   [:line
    {:x1 "50.00",
     :y1 "20.00",
     :x2 "40.00",
     :y2 "20.00",
     :key "G__2348"}])
  ([:line
    {:x1 "50.00",
     :y1 "238.50",
     :x2 "45.00",
     :y2 "238.50",
     :key "G__2349"}]
   [:line
    {:x1 "50.00",
     :y1 "215.50",
     :x2 "45.00",
     :y2 "215.50",
     :key "G__2350"}]
   [:line
    {:x1 "50.00",
     :y1 "192.50",
     :x2 "45.00",
     :y2 "192.50",
     :key "G__2351"}]
   [:line
    {:x1 "50.00",
     :y1 "181.00",
     :x2 "45.00",
     :y2 "181.00",
     :key "G__2352"}]
   [:line
    {:x1 "50.00",
     :y1 "169.50",
     :x2 "45.00",
     :y2 "169.50",
     :key "G__2353"}]
   [:line
    {:x1 "50.00",
     :y1 "158.00",
     :x2 "45.00",
     :y2 "158.00",
     :key "G__2354"}]
   [:line
    {:x1 "50.00",
     :y1 "146.50",
     :x2 "45.00",
     :y2 "146.50",
     :key "G__2355"}]
   [:line
    {:x1 "50.00",
     :y1 "135.00",
     :x2 "45.00",
     :y2 "135.00",
     :key "G__2356"}]
   [:line
    {:x1 "50.00",
     :y1 "123.50",
     :x2 "45.00",
     :y2 "123.50",
     :key "G__2357"}]
   [:line
    {:x1 "50.00",
     :y1 "112.00",
     :x2 "45.00",
     :y2 "112.00",
     :key "G__2358"}]
   [:line
    {:x1 "50.00",
     :y1 "100.50",
     :x2 "45.00",
     :y2 "100.50",
     :key "G__2359"}]
   [:line
    {:x1 "50.00",
     :y1 "89.00",
     :x2 "45.00",
     :y2 "89.00",
     :key "G__2360"}]
   [:line
    {:x1 "50.00",
     :y1 "77.50",
     :x2 "45.00",
     :y2 "77.50",
     :key "G__2361"}]
   [:line
    {:x1 "50.00",
     :y1 "66.00",
     :x2 "45.00",
     :y2 "66.00",
     :key "G__2362"}]
   [:line
    {:x1 "50.00",
     :y1 "54.50",
     :x2 "45.00",
     :y2 "54.50",
     :key "G__2363"}]
   [:line
    {:x1 "50.00",
     :y1 "43.00",
     :x2 "45.00",
     :y2 "43.00",
     :key "G__2364"}]
   [:line
    {:x1 "50.00",
     :y1 "31.50",
     :x2 "45.00",
     :y2 "31.50",
     :key "G__2365"}]
   [:line
    {:x1 "50.00",
     :y1 "20.00",
     :x2 "45.00",
     :y2 "20.00",
     :key "G__2366"}])
  [:g
   {:stroke "none",
    :fill "black",
    :font-family "Arial, sans-serif",
    :font-size 10,
    :text-anchor "middle",
    :key "G__2367"}
   -1
   -0.8
   -0.6000000000000001
   -0.4000000000000001
   -0.20000000000000007
   -5.551115123125783e-17
   0.19999999999999996
   0.39999999999999997
   0.6
   0.8
   1]
  [:line
   {:x1 "50.00",
    :y1 "250.00", 
    :x2 "50.00", 
    :y2 "20.00", 
    :key "G__2368"}]]]

from geom.

postspectacular avatar postspectacular commented on August 26, 2024

That's weird - in this demo here (using Reagent) it all works perfectly: http://demo.thi.ng/ws-ldn-1/geom-viz/

will take another look tonight after the workshop...

from geom.

den1k avatar den1k commented on August 26, 2024

@postspectacular the bar chart works fine, try the line chart.

from geom.

postspectacular avatar postspectacular commented on August 26, 2024

I don't know what you're seeing with that above linked demo, but I get the same (good & expected) results in Chrome (46.0.2490.86), FF(42.0) and even Safari 6.0.5 (8536.30.1):




Screenshots from Chrome, but worrying that you seem to be seeing something else... I also don't see any React warnings in the console for any of these viz methods. What browser & version you're testing with?

If you want to try, the source for that demo is in this repo: https://github.com/thi-ng/ws-ldn-1

from geom.

Polyrhythm avatar Polyrhythm commented on August 26, 2024

Is there a way to provide a simple example of a working Reagent-based SVG for working with, say, shapes?

I'm trying the following and it's not working out:

(defn svg-component [width body]
  [:div
   [(->> body
         (svgadapt/inject-element-attribs svgadapt/key-attrib-injector)
         (svg/svg {:width width :height width}))]])

(defn simple []
  (svg-component 300 (svg/group {:stroke "blue" :fill "none"} (c/circle 20))))

(defn ^:export on-js-reload []
  (r/render [simple]
            (js/document.getElementById "app")))

I get Error rendering component (in things.core.simple and Uncaught Error: Invalid arity: 1 with pretty useless stack traces.

I've done my due diligence looking around the demo examples and couldn't quite find what I needed.

from geom.

postspectacular avatar postspectacular commented on August 26, 2024

Hi @Polyrhythm - there're two things wrong with your example:

  1. In svg-component - you don't want to wrap the child of the inner form in a vector, since then your structure would look like this: [:div [[:svg ... ]]] and this causes part of the trouble
  2. The other issue is that you forgot to call svgadapt/all-as-svg before injecting the :key attribs

So corrected, this works without a hitch:

(defn svg-component [width body]
  [:div
   (->> body
        (svgadapt/all-as-svg)
        (svgadapt/inject-element-attribs svgadapt/key-attrib-injector)
        (svg/svg {:width width :height width}))])

(defn simple []
  (svg-component 300 (svg/group {:stroke "blue" :fill "none"} (c/circle 20))))

(defn ^:export main []
  (reagent/render
   [simple]
   (js/document.getElementById "app")))

from geom.

Polyrhythm avatar Polyrhythm commented on August 26, 2024

@postspectacular thank you for the quick and thorough reply. Now I can get started learning this awesome set of tools. 👍

from geom.

Related Issues (20)

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.