mirror of
https://github.com/apache/zeppelin
synced 2026-05-24 09:38:26 +00:00
### What is this PR for? Implemented **Spell** as one of Helium categories. *Technically, it's the frontend interpreter* runs on browser not backend. Spell can provide many benefits. 1. Anyone can install, remove easily using helium package registry by #1936 2. Implementing spell is extremely easier rather than adding backend interpreter 3. Can use existing javsacript libraries. (e.g [flowchart.js](http://flowchart.js.org/), [sequence diagram js](https://github.com/bramp/js-sequence-diagrams), ...). This enable us to add many visualization tools. Imagine that you can implement some custom interpreters with few lines of code like [flowchart-spell-example](https://github.com/apache/zeppelin/compare/master...1ambda:ZEPPELIN-2008/introduce-spell?expand=1#diff-364845b20d68e4d94688e44fef03da98) 4. The most important thing is, spell is not only interpreter but also display system. Because it runs on browser. So we can use spell display system with another spell **Display System with Spell** (see the screenshot section below) **In future**, we will be able to combine existing backend interpreters with spell like (**not supported in this PR cause we need to modify backend code a lot**) ``` // if we have markdown spell, we can use `%markdown` display in the spark interpreter %spark val calculated = doSomething() println(s"%markdown _${calculated}) ``` I added some examples. Checkout `echo`, `markdown`, `translator`, `flowchart` spells. ### What type of PR is it? [Feature] ### Todos * [x] - Add `SPELL` as one of Helium categories. * [x] - Implement framework code (`zeppelin-spell`) * [x] - Make some examples (flowchart, google translator, markdown, echo) * [x] - Support custom display system * [x] - Fix some bugs in `HeliumBundleFactory` * [x] - Save spell rendering result into `note.json` while broadcasting to other websocket clients * [x] - Fix `renderText` for stream output ### What is the Jira issue? [ZEPPELIN-2008](https://issues.apache.org/jira/browse/ZEPPELIN-2008) ### How should this be tested? - Build `mvn clean package -Phelium-dev -Pexamples -DskipTests;` - Go to helium page `http://localhost:8080/#/helium` - Enable all spells - Go to a notebook and refresh - Follow actions in the screenshots below. ### Screenshots (if appropriate) #### Flowchart Spell (Sample)  #### Google Translator Spell (Sample)  #### Display System with Spell  ### Questions: * Does the licenses files need update - NO * Is there breaking changes for older versions? - NO * Does this needs documentation? - YES, but framework can be enhanced so i would like to defer to write document right now. Author: 1ambda <[email protected]> Closes #1940 from 1ambda/ZEPPELIN-2008/introduce-spell and squashes the following commits:c1b5356[1ambda] fix: RAT issuese07ecd3[1ambda] fix: Set width for spell usage6c91892[1ambda] feat: Display magic, usage for spell5be2890[1ambda] feat: Support spell info822a1d8[1ambda] style: Remove useless func wrap for helium35d0fcc[1ambda] fix: Update desc for spell examples49e03fc[1ambda] fix: List visualziation bundles only in order4029c02[1ambda] fix: ParagraphIT, parameterizedQueryForm08eba10[1ambda] refactor: renderGraph in result.controller.js69ce880[1ambda] fix: Resolve append (stream) output0f2d8b6[1ambda] fix: Resolve output issuefc4389e[1ambda] fix: Resolve RAT issuesc8c8f0e[1ambda] fix: Add setErrorMessage method to Job4fec44c[1ambda] refactor: NotebookServer.java1227d7d[1ambda] refactor: result controller retry9fb7438[1ambda] feat: Save spell result and propagate3cdf2da[1ambda] fix: NPM installation error72aadbf[1ambda] feat: Enhance translator spellbd2b3ef[1ambda] style: Rename generator -> datacac0667[1ambda] style: Rename to Spelle81cb03[1ambda] example: Add echo, markdown0fa7eda[1ambda] feat: Support custom displayc906da6[1ambda] feat: Update examples to use single FrontIntpRes5c49e6e[1ambda] feat: Automated display type checking in result5810bf1[1ambda] feat: Apply frontend interpreter to paragrapha163044[1ambda] feat: Add flowchart, translator examples247d00f[1ambda] feat: Add frontend interpreter frameworke925967[1ambda] feat: Support FRONTEND_INTERPRETER type in frontendc02d00a[1ambda] feat: Support FRONTEND_INTERPRETER type in backend
108 lines
3.1 KiB
JavaScript
108 lines
3.1 KiB
JavaScript
/*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership.
|
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
* (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
import {
|
|
SpellBase,
|
|
SpellResult,
|
|
DefaultDisplayType,
|
|
} from 'zeppelin-spell';
|
|
|
|
import flowchart from 'flowchart.js';
|
|
|
|
export default class FlowchartSpell extends SpellBase {
|
|
constructor() {
|
|
super("%flowchart");
|
|
}
|
|
|
|
interpret(paragraphText) {
|
|
/**
|
|
* `flowchart` library requires an existing DOM to render.
|
|
* but the DOM is not created yet when `interpret` is called.
|
|
* so Zeppelin allows to return callback function which accept a DOM element id.
|
|
* the callback function will executed when the DOM is ready.
|
|
*/
|
|
const callback = (targetElemId) => {
|
|
let diagram = flowchart.parse(paragraphText);
|
|
diagram.drawSVG(targetElemId, this.getOption());
|
|
};
|
|
|
|
/**
|
|
* `interpret` method can return multiple results using `add()`
|
|
* but now, we return just 1 result
|
|
*/
|
|
return new SpellResult(
|
|
callback
|
|
);
|
|
}
|
|
|
|
getOption() {
|
|
return {
|
|
'x': 0,
|
|
'y': 0,
|
|
'line-width': 3,
|
|
'line-length': 50,
|
|
'text-margin': 10,
|
|
'font-size': 14,
|
|
'font-color': 'black',
|
|
'line-color': 'black',
|
|
'element-color': 'black',
|
|
'fill': 'white',
|
|
'yes-text': 'yes',
|
|
'no-text': 'no',
|
|
'arrow-end': 'block',
|
|
'scale': 1,
|
|
// style symbol types
|
|
'symbols': {
|
|
'start': {
|
|
'font-color': 'red',
|
|
'element-color': 'green',
|
|
'fill': 'yellow'
|
|
},
|
|
'end':{
|
|
'class': 'end-element'
|
|
}
|
|
},
|
|
// even flowstate support ;-)
|
|
'flowstate' : {
|
|
'past' : { 'fill' : '#CCCCCC', 'font-size' : 12},
|
|
'current' : {'fill' : 'yellow', 'font-color' : 'red', 'font-weight' : 'bold'},
|
|
'future' : { 'fill' : '#FFFF99'},
|
|
'request' : { 'fill' : 'blue'},
|
|
'invalid': {'fill' : '#444444'},
|
|
'approved' : { 'fill' : '#58C4A3', 'font-size' : 12, 'yes-text' : 'APPROVED', 'no-text' : 'n/a' },
|
|
'rejected' : { 'fill' : '#C45879', 'font-size' : 12, 'yes-text' : 'n/a', 'no-text' : 'REJECTED' }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|