felixfbecker / dom-to-svg Goto Github PK
View Code? Open in Web Editor NEWLibrary to convert a given HTML DOM node into an accessible SVG "screenshot".
License: MIT License
Library to convert a given HTML DOM node into an accessible SVG "screenshot".
License: MIT License
Tried converting a dom with existing svg contained with a gradient element in it, the rest of the svg renders except the gradient element
Hello,
I want to convert an html page into pdf with puppeteer. I have some maps witch i would like to convert into svg before putting in the pdf file.
Can I use this lib in nodejs with puppeteer? If yes, Does exist some examples?
Even though it's probably very hard or even close to impossible, I wish we could capture animations as part of the SVGs as well.
Probably using SMIL:
EDIT:
Maybe SMIL isn't ideal, but bringing the CSS along in a <style>
might be of similar (high) difficulty.
Using https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API it's getting more feasible in my mind.
My use case:
Wanting to capture this modal including the spin-animation of the badge on open/mouseenter.
First of all, thanks very much for creating dom-to-svg as well as svg-screenshots!
From all the HTML-to-SVG stuff I've tried, dom-to-svg works best, almost perfect.
One thing that appears to be missing though is support for Shadow DOM/Custom elements, correct?
Probably easiest to discuss on my use case:
I'm looking into building "svgcaniuse", SVGs of caniuse.com, e.g. https://caniuse.com/web-share.
Using svg-screenshots to capture the viewport of https://caniuse.com/web-share results in this:
Because the DOM looks like this:
I've tried my way around the first shadow-root like so using DevTools:
const { elementToSVG, inlineResources } = await import('https://cdn.skypack.dev/dom-to-svg');
// notice the shadowRoot
const svgDocument = elementToSVG(document.querySelector('ciu-feature-list').shadowRoot.querySelector('.feature-list-wrap'));
await inlineResources(svgDocument.documentElement)
const svgString = new XMLSerializer().serializeToString(svgDocument);
But "of course" the resulting svgString only contains the equivalents of .feature-list-wrap
and <ciu-feature>
(without any children since it's got the next shadow-root), i.e. just a brown background:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" data-stacking-context="true" aria-owns="feature-list-wrap1" width="1316.21875" height="656.40625" viewBox="56.890625 194 1316.21875 656.40625"><!-- Generated by dom-to-svg from https://caniuse.com/web-share --><style>@font-face { font-family: "open sans"; src: url("https://caniuse.com/fonts/open-sans-regular.woff2") format("woff2"); font-display: swap; font-weight: normal; font-style: normal; }
@font-face { font-family: "open sans"; src: url("https://caniuse.com/fonts/open-sans-300.woff2") format("woff2"); font-display: swap; font-weight: 300; font-style: normal; }
@font-face { font-family: "open sans"; src: url("https://caniuse.com/fonts/open-sans-700.woff2") format("woff2"); font-display: swap; font-weight: 700; font-style: normal; }
</style><g data-stacking-layer="rootBackgroundAndBorders"/><g data-stacking-layer="childStackingContextsWithNegativeStackLevels"/><g data-stacking-layer="inFlowNonInlineNonPositionedDescendants"/><g data-stacking-layer="nonPositionedFloats"/><g data-stacking-layer="inFlowInlineLevelNonPositionedDescendants"/><g data-stacking-layer="childStackingContextsWithStackLevelZeroAndPositionedDescendantsWithStackLevelZero"/><g data-stacking-layer="childStackingContextsWithPositiveStackLevels"/><g data-tag="div" id="feature-list-wrap1" class="feature-list-wrap" data-z-index="auto" data-stacking-context="true" aria-owns="web-share"><g data-tag="ciu-feature" id="web-share" data-z-index="auto" data-stacking-context="true"><g data-stacking-layer="rootBackgroundAndBorders"><rect width="1316.21875" height="656.40625" x="56.890625" y="194" fill="rgb(37, 32, 23)"/></g></g><text color="rgb(0, 0, 0)" dominant-baseline="text-after-edge" font-family=""Open Sans", Helvetica, Arial, sans-serif" font-size="16px" font-stretch="100%" font-style="normal" font-variant="normal" font-weight="400" direction="ltr" letter-spacing="normal" text-decoration="none solid rgb(0, 0, 0)" text-anchor="start" text-rendering="auto" unicode-bidi="normal" word-spacing="0px" writing-mode="horizontal-tb" user-select="auto" fill="rgb(0, 0, 0)"/><text color="rgb(0, 0, 0)" dominant-baseline="text-after-edge" font-family=""Open Sans", Helvetica, Arial, sans-serif" font-size="16px" font-stretch="100%" font-style="normal" font-variant="normal" font-weight="400" direction="ltr" letter-spacing="normal" text-decoration="none solid rgb(0, 0, 0)" text-anchor="start" text-rendering="auto" unicode-bidi="normal" word-spacing="0px" writing-mode="horizontal-tb" user-select="auto" fill="rgb(0, 0, 0)"/></g></svg>
Not sure if that would suffice, but basically something like this could make it work:
if (element.childElementCount === 0 && element.shadowRoot !== null) {
// use element.shadowRoot to continue traversal
}
I've had a look at the source but wasn't confident enough to start a PR.
Would be great though if dom-to-svg would work with Shadow DOM :)
In cases such as this:
<div>
<svg class="small">
<circle cx="50%" cy="50%" r="50%" class="svg-circle"/>
</svg>
</div>
the circle does not calculate its width relative to its parent class "small", but relative to window I think
I found the "SVG Screenshot" extension on Super User. In order to test it, I tried to take a screenshot of this particular Super User page.
But it hangs.
After some debugging I discovered that the hang is caused by this element near the Stack Exchange logo:
When dom-to-svg handles ::before
pseudo-element, it creates a span
child inside this span
element. But the span
child also has ::before
pseudo-element because of styles, and dom-to-svg handles the span
child and creates another span
child inside this span
child. Since it also has ::before
pseudo-element, dom-to-svg handles it and creates span
inside span
inside span
... and so on.
There is a minimal reproducible example. Try to documentToSVG(document)
and it will hang.
<!DOCTYPE html>
<html>
<head>
<style>
.foo span::before { content: "foo"; }
</style>
</head>
<body>
<div class="foo">
<span>bar</span>
</div>
</body>
</html>
In the captured SVG I can see:
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
data-stacking-context="true"
aria-owns="chart-container1"
width="832" height="394"
viewBox="0 22 832 394">
While the source looks like:
<svg
width="170"
height="42.5"
version="1.1"
viewBox="0 0 303 42.5"
xmlns="http://www.w3.org/2000/svg"
x={width - 164}
y={y - 19}
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:asharq="http://www.asharq.com/namespaces/asharq"
>
Attributes from the custom namespace do exist in the generated SVG, but lack of declaration breaks the SVG effectively.
it seems that it is not working with icon fonts , background-position , overflow clip with border radius
https://demo.interface.club/limitless/demo/template/html/layout_1/full/form_layout_vertical.html
For example this page from Storybook: https://5a375b97f4b14f0020b0cda3-uahseqezca.chromatic.com/iframe.html?id=ui-sidebar-sidebar--simple&viewMode=story (all Storybook URLs have this form)
This yields an error like:
error on line 1 at column 301: Double hyphen within comment: <!-- Generated by dom-to-svg from https://5a375b97f4b1
(I'm using the Chrome addon)
I suspect the solution is to use <![CDATA[ Generated by dom-to-svg from ... ]]>
rather than a comment.
Excellent library by the way!
On react 18.2 and dom-to-svg 0.12.2, I get the following error when trying to inlineResources:
TypeError: nanoid is not a function
at new Input (input.js:58:1)
at Module.parse (parse.js:8:1)
at inline.ts:80:1
at inlineResources (inline.ts:102:1)
When using elementToSVG on an element containing and SVG the nested SVG is not rendered correctly in Firefox.
This appears to be a long standing bug / difference of interpretation of the SVG spec between Firefox and Chrome.
The issue stems arround the getCTM method (used in svg.ts) returning a matrix with e, f = 0 in Firefox.
Example files attached, one generated in Chrome the other in Firefox
I have requirement to Support for converting dom to svg for selected area or multiple elements . is this possible ?
Hi,
While testing your addon out on a few random webpages, I found that it is unable to capture from the website https://whirlpool.net.au, either an area or a viewport. The error it returns is:
An error happened while capturing the page: value is undefined
Check the developer console for more information.
The developer console has the following when capturing the viewport:
Loading failed for the <script> with source โhttps://whirlpool.net.au/cdn-cgi/bm/cv/669835187/api.jsโ. whirlpool.net.au:112:1
Content script running content.ts:14:7
Capturing captureViewport content.ts:43:7
TypeError: value is undefined
exports parse.js:29
ValueParser index.js:8
ValueParser index.js:11
elementToSVG index.ts:44
documentToSVG index.ts:12
capture content.ts:52
main content.ts:23
ozpp content.js:59037
newRequire generate.js:60
parcelRequire generate.js:99
char-code-definitions.js:134
content.ts:28:8
main content.ts:28
ozpp content.js:59037
newRequire generate.js:60
parcelRequire generate.js:99
char-code-definitions.js:134
Changing any settings does not affect this bug.
System:
Ubuntu 20.04
Firefox 85.0.1 (64-bit)
Other Addons:
uBlock Origin
GNOME Shell Integration
Turning off the other addons makes no difference.
Thanks.
Hello.
First of all, thanks for library. It's very helpfull.
But I have this error in console:
It seems, some troubles with nanoid import. Here is issue - ai/nanoid#205
Any ideas, how to fix it?
I'm using last version of dom-to-svg
package = @0.12.2
When I have this gradient in dom:
<div style="background: linear-gradient(to right, rgb(29, 62, 89) 0%, rgb(29, 62, 89) 33.3333%, rgb(128, 128, 128) 33.3333%, rgb(128, 128, 128) 66.6667%, rgb(158, 21, 53) 66.6667%, rgb(158, 21, 53) 100%);"></div>
after conversion I got magically this:
<g data-tag="div" id="variant-color-circle1" class="variant-color-circle" data-z-index="auto" data-stacking-context="true">
<g data-stacking-layer="rootBackgroundAndBorders">
<linearGradient x1="0%" y1="0%" x2="100%" y2="0%" id="linear-gradient1">
<stop offset="0%" stop-color="rgb(29,62,89)" stop-opacity="1"/>
<stop offset="20%" stop-color="rgb(29,62,89)" stop-opacity="1"/>
<stop offset="40%" stop-color="rgb(128,128,128)" stop-opacity="1"/>
<stop offset="60%" stop-color="rgb(128,128,128)" stop-opacity="1"/>
<stop offset="80%" stop-color="rgb(158,21,53)" stop-opacity="1"/>
<stop offset="100%" stop-color="rgb(158,21,53)" stop-opacity="1"/>
</linearGradient>
<rect width="37.78125" height="37.78125" x="276.015625" y="452.90625" fill="url(#linear-gradient1)" stroke="rgb(0, 0, 0)" stroke-width="1px" rx="18.890625" ry="18.890625"/>
</g>
</g>
instead of this:
<g data-tag="div" id="variant-color-circle1" class="variant-color-circle" data-z-index="auto" data-stacking-context="true">
<g data-stacking-layer="rootBackgroundAndBorders">
<linearGradient x1="0%" y1="0%" x2="100%" y2="0%" id="linear-gradient1">
<stop offset="0%" stop-color="rgb(29,62,89)" stop-opacity="1"/>
<stop offset="33.3333%" stop-color="rgb(29,62,89)" stop-opacity="1"/>
<stop offset="33.3333%" stop-color="rgb(128,128,128)" stop-opacity="1"/>
<stop offset="66.6667%" stop-color="rgb(128,128,128)" stop-opacity="1"/>
<stop offset="66.6667%" stop-color="rgb(158,21,53)" stop-opacity="1"/>
<stop offset="100%" stop-color="rgb(158,21,53)" stop-opacity="1"/>
</linearGradient>
<rect width="37.78125" height="37.78125" x="276.015625" y="452.90625" fill="url(#linear-gradient1)" stroke="rgb(0, 0, 0)" stroke-width="1px" rx="18.890625" ry="18.890625"/>
</g>
</g>
Is there any shadow dom support in master? I've been looking through you PRs and seen that you had done some work for that
I am trying to convert a html table to a SVG file. All the converted elements all have the dominant-baseline
attribute. However, Adobe Illustrator doesn't support the dominant-baseline
attribute or the alignment-baseline
attribute, so all the converted SVGs look weird. I wonder whether you could improve the library and export the element without those two attributes.
E.g. in background
. google.com uses this on buttons.
HTML:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="fontface.css" />
</head>
<body>
<div class="foo">bar</div>
</body>
</html>
CSS:
@font-face {
font-family: Roboto;
font-style: normal;
font-weight: 300;
src: local('Roboto Light');
}
.foo {
font-family: Roboto;
font-weight: 300;
}
Chrome works fine, but when trying to documentToSVG(document)
in Firefox, dom-to-svg throws this error:
TypeError: value is undefined
exports parse.js:29
ValueParser index.js:8
ValueParser index.js:11
elementToSVG index.ts:44
documentToSVG index.ts:12
It's caused by this line:
Line 43 in a377921
For some reason rule.style.src
works fine in Chrome but is undefined
in Firefox.
It seems this can be replaced with rule.style.getPropertyValue('src')
โ it works for both Chrome and Firefox.
Hi,
When I use the library via npm in Blazor project, I get a 'Failed to resolve module specifier "tty"' message in the browser console on a page loading. I found that the "tty" module was added to my project's dependencies, but it is removed from npm now.
If we have an img tag with an SVG as src, it is not displayed on the output SVG. The library throws an error that the inlined SVG tag does not have an owner document. More specifically line 109 fails on file svg.ts
I am using elementToSVG to convert html portion of page to svg . but looks like the x and y positions is based on the dom , is the way i can control this
The code I am using
elementToSVG(document.querySelector(contentId));
Before I begin, thank you for this awesome library.
inlineResources is not working:
This error was introduced in version 0.11.5 (issue #113, fix #116). Version 0.11.4 works fine. See screenshots below.
I suspect that fetchURL doesn't know to look in xlink:href instead of href.
Therefore element.href.baseVal is undefined and it outputs No URL passed
(inline.ts, line 27)
JavaScript code used
I'm using the CDN version as recommended in #135. I've tested both versions.
async function takeSVGScreenshot(){
console.log('[IK SVG] Importing dependencies...');
const { elementToSVG, inlineResources } = await import('https://cdn.skypack.dev/[email protected]'); // or 0.11.4
console.log('[IK SVG] Taking snapshot...');
const svgDocument = elementToSVG(document.querySelector('#qtlw13'));
console.log('[IK SVG] Inlining resources...');
await inlineResources(svgDocument.documentElement); // <-- this is where the error occurs
console.log('[IK SVG] Serializing...');
const svgString = new XMLSerializer().serializeToString(svgDocument);
console.log('[IK SVG] Sending data back to server...');
callHTMLClient( '{"Sender":"TakeSVGScreenshot", "Data":"' + svgString.replace(/\"/g, '\\"') + '"}');
console.log('[IK SVG] Done');
}
This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
Warning
These dependencies are deprecated:
Datasource | Name | Replacement PR? |
---|---|---|
npm | @types/pollyjs__core |
|
npm | @types/pollyjs__persister-fs |
|
npm | @types/prettier |
|
npm | @types/puppeteer |
|
npm | parcel-bundler |
These updates are currently rate-limited. Click on a checkbox below to force their creation now.
pixelmatch
, @types/pixelmatch
)@pollyjs/adapter
, @pollyjs/core
, @pollyjs/persister-fs
)mocha
, @types/mocha
)prettier
, @types/prettier
)@pollyjs/adapter
, @pollyjs/core
, @pollyjs/persister-fs
)These updates have been manually edited so Renovate will no longer make changes. To discard all commits and start over, click on a checkbox.
mime-types
, @types/mime-types
)These updates have all been created already. Click a checkbox below to force a retry/rebase of any.
content-type
, @types/content-type
)chai
, @types/chai
)mocha
, @types/mocha
)prettier
, @types/prettier
)puppeteer
, @types/puppeteer
)@commitlint/cli
, @commitlint/config-conventional
)These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.
.github/workflows/test.yml
actions/checkout v2
actions/setup-node v2
actions/upload-artifact v2
package.json
gradient-parser ^1.0.2
postcss ^8.3.5
postcss-value-parser ^4.1.0
@commitlint/cli ^11.0.0
@commitlint/config-conventional ^11.0.0
@pollyjs/adapter ^5.0.0
@pollyjs/core ^5.0.0
@pollyjs/persister-fs ^5.0.0
@sourcegraph/eslint-config ^0.24.0
@sourcegraph/prettierrc ^3.0.3
@types/chai ^4.2.19
@types/content-type ^1.1.3
@types/lodash-es ^4.17.4
@types/mime-types ^2.1.0
@types/mocha ^8.2.2
@types/node ^14.17.4
@types/parcel-bundler ^1.12.3
@types/pixelmatch ^5.2.3
@types/pngjs ^6.0.0
@types/pollyjs__core ^4.3.2
@types/pollyjs__persister-fs ^2.0.1
@types/prettier ^2.2.3
@types/puppeteer ^5.4.3
@types/type-is ^1.6.3
chai ^4.3.4
chardet ^1.3.0
content-type ^1.0.4
delay ^4.4.0
eslint ^7.30.0
husky ^4.3.0
lodash-es ^4.17.21
mime-types ^2.1.30
mocha ^8.3.2
parcel-bundler ^1.12.5
pixelmatch ^5.2.1
pngjs ^6.0.0
prettier ^2.2.1
puppeteer 5.4.0
rxjs ^7.1.0
semantic-release ^17.2.4
source-map-support ^0.5.19
tagged-template-noop ^2.1.1
ts-node ^9.1.1
typescript ^4.3.5
xml-formatter ^2.4.0
When converting to SVG a DOM element that has inline SVG elements inside, the id
fields of the svg are mutated with svg1-
prefix, breaking the original svg.
https://codesandbox.io/s/don-to-svg-bug-x80pg?file=/src/index.js
Hey there!
I've just found this library but can't test it on a new angular app because of the ES2020. I've tried some workarrounds but no sucess, how can I specify it on the compiler options so typescript understands it?
] Error: ./node_modules/dom-to-svg/lib/index.js 34:34
[ng] Module parse failed: Unexpected token (34:34)
[ng] File was processed with these loaders:
[ng] * ./node_modules/@angular-devkit/build-angular/src/babel/webpack-loader.js
[ng] * ./node_modules/@ngtools/webpack/src/ivy/index.js
[ng] You may need an additional loader to handle the result of these loaders.
[ng] | }
[ng] | // Make font URLs absolute (need to be resolved relative to the stylesheet)
[ng] > for (const rule of rules ?? []) {
[ng] | if (!css_1.isCSSFontFaceRule(rule)) {
[ng] | continue;
I use "elementToSVG" to convert part of my page into svg.
It seems, that if DOM element get offsetWidth or offsetHeight, the output svg has them in "viewbox" properties. So, the final svg has offsets too.
Any ideas, how to solve this?
Currently borders are drawn as the stroke of a rect, which supports border-radius. However, the way SVG draws borders is different from the CSS, the stroke is on the edge of the rect as opposed to outside like in CSS. Also, currently non-uniform borders cannot have border-radius. The solution is to always draw them with a <path>
.
hi,
i didn't have this issue with the 0.02, but i'm experiencing it now in the 0.03. it is happening deep in the bowels of our application, so i'm hoping there's enough information here that you can see what it is. otherwise, i can try and put together a reproducible example.
b.dataset.zIndex
is undefined.
with thanks
hi,
loving this project, however i've found the export of css rules to not take into account the location of the css file.
for example, if /subproject/index.html
refers to /main.css
with ../main.css
, which in turn references a font-face, then the font-face url in the svg will end up pointing to /subproject/blah
rather than /blah
https://github.com/felixfbecker/dom-to-svg/blob/main/src/index.ts#L50
with thanks
Is there a CDN version of dom to svg or can this executed from plain javascript
Bitmap pictures of SVG output are not visible in free vector editor named Inkscape. The reason is probably because image href attribute should be xlink:href. I tried changing following lines localy (c:\Users[username]\AppData\Roaming\Mozilla\Firefox\Profiles[profilename].default\extensions\[email protected]\src) in (content|background).js(|.map) which solved the issue for me:
// Inline binary images as base64 data: URL
const dataUrl = await blobToDataURL(blob);
element.dataset.src = element.href.baseVal;
element.setAttribute('xlink:href', dataUrl.href);
Please include Inkscape to your testing software.
In file text.ts, on line 86 the function getClientRects() fails on Safari browser.
This happened on text elements that had a whitespace to their left. Removing that whitespace, fixed the issue. Example:
<span> Text</span>
does not work, but this:
<span>Text<span>
works
I have web page which has large number of elements ( page includes charts , calendar and tables etc ) . The conversion takes mins ranging from 1 min to 5 mins and The performance is vert bad in FF compared to chorme .
Is there way to improve or batch conversion for selected elements or area . For example currently i am converting each element in serial order , can we do this in parallel
hi,
i notice the built .js files have lines like:
import { svgNamespace, isSVGImageElement, isSVGStyleElement } from './dom.js';
i'm finding that browserify barfs on these, and i have to incorporate babelify, etc. in order to use this library. i assume this is controlled by the tsconfig.js
file, which specifies "target": "ES2020",
. would it be possible to choose a less ambitious target? it would greatly simplify things for me, and probably others (it did take me quite a while to figure out how to use babelify).
with thanks
I think it's a very good idea the usage of this library to generate a pdf file of the HTML DOM, without generate a non vector image. Because currently generate a non vector image is the only way of how we can generate a pdf of the DOM in js. Please see:
parallax/jsPDF#3222
So, one feature that we probably need to achieve this goal is the ability of generate an svg per PDF pages and this then will required split the svg in several svg with the corresponding size of the pdf page.
One basic and initial idea to split the svg could be just cut it where we can and another much more complex will required enumerate all possibilities and evaluate the better approach later. I think the print setting of Firefox and Chromium should provide a good idea of how to split the things.
Hi,
When exporting DOM elements, everything works well except the Text elements in the SVG are not scaled properly, the position is correct but it's warped because of wrong size (too big).
While translating, the library adds some text to IDs affecting our SVG code. However, it does not update those same IDs in those fill=url(#ID) properties in SVGs. This results in ID incompatibility (the fill does not find the correct ID), thus SVG does not render correctly. Can you not modify our elements IDs or just update the fill property as well?
This plugin is great and works perfectly in Chrome browser. However, in Safari browser, after line breaks, it causes browser lag and doesn't have any effect. Here's a reproducible demo: https://codesandbox.io/p/devbox/silly-monad-v6p8c5
... due to missing defaultView after elementToSVG.
I converted an element and then in the inliningResources I get an error saying element.ownerDocument has no defaultView (it is null)... what am I doing wrong @felixfbecker ?
I am using primeicons for my project and on processing the font faces I am getting the following errors:
Error inlining http://localhost:9999/primeicons.eot?#iefix Error: Invalid response MIME type inlining font at http://localhost:9999/primeicons.eot?#iefix: Expected font MIME type, got application/vnd.ms-fontobject; charset=utf-8
Error inlining http://localhost:9999/primeicons.svg?#primeicons Error: Invalid response MIME type inlining font at http://localhost:9999/primeicons.svg?#primeicons: Expected font MIME type, got image/svg+xml; charset=utf-8
This can be fixed by changing and adding line 121 of inline.ts in your project:
blob.type !== 'application/vnd.ms-fontobject'
for:
!blob.type.startsWith('image/svg+xml') && !blob.type.startsWith('application/vnd.ms-fontobject')
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.