从前天开始!制作应对LT演讲的演示应用程序的方法【GraphQL】
阅读本文后可以获得的内容
・当我冲动地报名参加LT之后,如何应对这一决定
如果你不想读冗长的句子,那么只需要阅读总结部分就可以了,因为我将以体验故事的方式来概括LT发表的经历!
事情的开端
夏季之初,我已逐渐适应了我的新入职工作(我觉得是这样),因此想要在外部积累一些实绩,于是考虑进行LT(15分钟技术演讲)的演讲。经由connpass网站,我正在寻找一些初学者也能参加的活动。恰好找到了几个初学者也能参加的LT会,因此首先尝试申请参与。
我想写下参加律师网举办的泡泡奶茶演讲会(https://bengo4.connpass.com/event/143609/)的经历,这是我申请参加的几场LT会中的一场。
在关于“粗糙的网络主题”这个话题中进行讨论是被允许的,所以我毫无具体主题地提交了申请。
由于从申请到活动举办之间有很长时间,所以我以为一定会想出一些话题,然而直到前一天的演讲我还没有任何想法。
为了应付这种窘境,我匆忙开始制作前一天的演讲资料。
选择一个主题
如果从事Web开发工作,可以通过分享与工作相关的内容来进行演讲等活动,但在平时工作中大多涉及机器学习方面的技术,因此并没有太多机会接触Web开发技术。
然而,我个人在业余时间开发了一些Web应用,并且有接触过React等相关技术,所以一开始我想谈谈这方面的经验。
我开始考虑使用redux-starter-kit进行应用开发,以及个人开发技术选型的讨论,但当我开始画出草图时,发现它们都不太理想。
我苦恼不知该怎么办时,眼前出现了这次LT会的主题名称”波霸LT”这个词。
既然如此,我也想做一个与波霸相关的演讲呢……最终经过思考犹豫,
如果把黑色的气泡图显示在容器的插图中,是不是看起来像珍珠奶茶呢?
决定了以此概念为基础的演讲主题。
由于我平时从事机器学习和数据分析的工作,所以对于图表等内容非常熟悉。此外,我个人还开发了一个Web应用,可以通过口碑分析来生成图表。因此,我决定只能使用这个Web应用进行演示。(在演讲前一天中午时刻做出决定)
虽然在这里并没有提到GraphQL的详情,但最终向运营人员传达的演讲主题是“从珍珠奶茶开始的GraphQL”。考虑到只制作泡泡图来进行演讲可能有些困难,所以决定结合之前一直想要尝试的GraphQL来进行。正是由LT(闪电演讲)所推动的开发!
创建演示应用程序
因为确定了演讲主题和要制作的演示,所以开始着手制作资料和演示(这时已经大约18点)。
由于时间紧迫,我们将制作一个具备最基本功能的演示应用程序。
只需要一种选项,以下是本土化的中文释义:
作为要件决定的是,
• 用气泡图表达类似于珍珠奶茶的事物。
• 为了进行API演示,创建一个简单的数据库,使其可以通过REST和GraphQL进行调用。
只有这两个选择,而且时间也不够。
在这次展示的气泡图中所使用的信息是从珍珠奶茶店的网页上收集的文本,并进行形态学分析以获取单词和单词出现的次数作为数据进行利用。
通过使用tf-idf方法,我们从数据中删除了那些看起来不太重要的单词,只展示与珍珠奶茶店特点相关的数据。
然而,尽管最终成功地创建了数据,但由于没有时间创建数据库并与前端连接,只能根据上述数据手动创建虚拟数据,并采取直接写入脚本内部的强硬手段。
考虑到未来没有使用计划,也许在某些时候和场合,仅为了五分钟的LT演讲而将其视作一种权宜之计。(借口)
之後建立的API端是這邊。
const express = require('express');
const app = express();
const port = process.env.PORT || 3030;
const ctSum =
[[ { label: "表参道", value: 3 ,color :"#663333"},
{ label: "クリーム", value: 2, color :"#663333"},
{ label: "Tea", value: 3,color :"#333300" },
{ label: "インスタ", value: 2 ,color :"#333300"},
{ label: "持ち帰り", value: 2 , color :"#333333"},
{ label: "スイカ", value: 2 , color :"#333333"},
{ label: "チーズ", value: 1 , color :"#330000"},
{ label: "カップ", value: 2 , color :"#330000"},
{ label: "恋人", value: 2 , color :"#000033"},
{ label: "ドリンク", value: 2 , color :"#000033"},
{ label: "女子", value: 3 , color :"#000000"},
{ label: "大人気", value: 2 , color :"#000000"},
{ label: "感動", value: 3 , color :"#440000"},
{ label: "テーブル", value: 2 , color :"#440000"},
{ label: "映え", value: 2 ,color :"#330000"},
{ label: "シェア", value: 2 ,color :"#330000"},
{ label: "飲み物", value: 3 ,color :"#220000" },
{ label: "職人", value: 2 ,color :"#220000" },
{ label: "ミルク", value: 2 ,color :"#663300"},
{ label: "自然", value: 2,color :"#663300" },
]
];
app.listen(port, () => console.log(`Listening on port ${port}...`));
app.get('/api/tapiokaInfo', (req, res) => {
res.send(ctSum);
});
REST一方面采用了Node.js和Express.js来创建了一个仅拥有最基本功能的API。
虽然我本来还想创建多个端点并与只有一个端点的GraphQL进行对比,但由于时间问题放弃了。
虽然坚持称之为REST API让我感到有些不自在,但毕竟它满足了REST的四个设计原则,所以我也就放弃了。
接下来是GraphQL部分。
这部分不连接前端,而是使用GraphiQL来进行实际数据提取的演示。
源代码在这里。
var express = require('express');
var express_graphql = require('express-graphql');
var { buildSchema } = require('graphql');
// GraphQL schema
var schema = buildSchema(`
type Query {
tapioka(name: String!):Tapioka
tapiokas(name: String!):[Tapioka]
},
type Tapioka{
name : String
label :String
value :Int
color :String
}
`
);
var tapiokaData = [
{
name:"LTタピオカ 渋谷店",
label: "表参道",
value: 3 ,
color :"#663333"
},
{
name:"LTタピオカ 渋谷店",
label: "クリーム",
value: 2,
color :"#663333"
},
{
name:"LTタピオカ 表参道店",
label: "Tea",
value: 3,
color :"#333300"
},
{
name:"LTタピオカ 表参道店",
label: "インスタ",
value: 2 ,
color :"#333300"
},
{
name:"LTタピオカ 表参道店",
label: "持ち帰り",
value: 2 ,
color :"#333333"
},
{
name:"LTタピオカ 表参道店",
label: "スイカ",
value: 2 ,
color :"#333333"
},
{
name:"LTタピオカ 表参道店",
label: "恋人",
value: 2 ,
color :"#000033"
},
{
name:"LTタピオカ 表参道店",
label: "チーズ",
value: 1 ,
color :"#330000"
},
{
name:"LTタピオカ 表参道店",
label: "カップ",
value: 2 ,
color :"#330000"
},
]
var getTapioka = function(args) {
var name = args.name;
return tapiokaData.filter(tapioka => {
return tapioka.name == name;
})[0];
}
var getTapiokas = function(args) {
var name = args.name;
return tapiokaData.filter(tapioka => {
return tapioka.name == name;});
}
// Root resolver
var root = {
tapioka:getTapioka,
tapiokas: getTapiokas
};
// Create an express server and a GraphQL endpoint
var app = express();
app.use('/graphql', express_graphql({
schema: schema,
rootValue: root,
graphiql: true
}));
app.listen(4000, () => console.log('Express GraphQL Server Now Running On local\
host:4000/graphql'));

差不多这样的感觉
在演示时特别有用,因为可以一眼看出查询了什么,并返回了什么结果。对于了解GraphQL的人来说,似乎只是做了理所当然的事情,但对初学者来说可能很好。
下一个是前端。
使用React,Redux和Node进行搭建,快速实现。
关键的珍珠部分打算使用D3.js来制作,但是根据查到的方法由于版本不同等原因无法正常运行,因此放弃了。
改用React-bubble-chart-d3进行实现。
源代码在这里
import React, {Component} from 'react';
import styles from './css/box.css'
import { connect } from 'react-redux';
import BubbleChart from '@weknow/react-bubble-chart-d3';
const Content = ({data,onIncrementClick}) =>{
return(
<div className={styles.box}>
<p>店名 : LTタピオカ 表参道店</p>
<BubbleChart
graph= {{
zoom: 0.9,
offsetX: 0.12,
offsetY: 0.9,
}}
width={320}
height={850}
fontFamily="Arial"
showLegend={false}
data={data}
/>
</div>
);
};
export default connect()(Content);
由於寫出全部的內容會變成相當長的量,因此只發佈有關珍珠奶茶製作部分的內容。
實際的實現畫面就像這樣。

左边有点偏,而且有些不舒服…
总之,看起来不像珍珠奶茶,也不是吗?
时间不多,所以我就这样带走了。
实际的演讲
当天虽然意外地成为第一个发言者,并且因工作延误险些迟到,参加过程相当匆忙,但终究还是能够完成演讲。
由于在演示中没有好好整理内容,不小心超时了5分钟,这是个可以反思的地方,但总体来说,我觉得还是能够成功克服的。(至少在我自以为的情况下)
对于演讲经验来说,我还是相当浅薄的,这次是第一次准备演示应用,但实际尝试下来,意外地发现问题总能解决,这让我觉得,勇敢尝试参加才是最重要的事情。
整理
在准备LT演示时要注意的重要事项!
– 制作给人深刻印象的视觉元素
– 不要过于纠结于细节功能的实施
– 即使质量低下,也要制作出可展示的产品
– 不要在五分钟内过多地拥挤功能
– 如果认为不可能,果断放弃。
虽然我放弃了一部分功能,但我认为放弃是相当重要的。在这次的演讲中,由于时间不允许,超过一半原本计划实施的功能被放弃了。尽管如此,我还是想尽办法使它变得尽可能完整,这才是最重要的。
最后
我希望在以后的日子里能积累更多的LT演讲和登台经验,所以如果有机会的话,欢迎那些希望有这样机会的人通过私信或回复给@mattya_monaca,我会非常乐意参加!我主要积累了一些关于机器学习和Web相关的素材,所以请多多关照!