This is an automated email from the ASF dual-hosted git repository.

ovilia pushed a commit to branch master
in repository 
https://gitbox.apache.org/repos/asf/echarts-wordcloud-generator.git

commit b24c4e583cddc401a101a43390bbb7726292ff08
Author: Ovilia <zwl.s...@gmail.com>
AuthorDate: Wed Dec 22 11:05:35 2021 +0800

    feat: colors
---
 package-lock.json          |  61 ++++++++++-
 package.json               |   2 +
 src/App.vue                |  66 ++++++------
 src/components/WChart.vue  |  42 +++++++-
 src/components/WConfig.vue | 264 +++++++++++++++++++++++++++++++++------------
 5 files changed, 328 insertions(+), 107 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index af8bb1e..2766bfc 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -308,6 +308,30 @@
                 "defer-to-connect": "^1.0.1"
             }
         },
+        "@types/color": {
+            "version": "3.0.2",
+            "resolved": 
"https://registry.npmmirror.com/@types/color/download/@types/color-3.0.2.tgz";,
+            "integrity": "sha1-N3kEPngvViqpFXtfxr0H4U/Y5/M=",
+            "dev": true,
+            "requires": {
+                "@types/color-convert": "*"
+            }
+        },
+        "@types/color-convert": {
+            "version": "2.0.0",
+            "resolved": 
"https://registry.npmmirror.com/@types/color-convert/download/@types/color-convert-2.0.0.tgz";,
+            "integrity": "sha1-j17muehj3L7lcD9aUX/7E9PqTiI=",
+            "dev": true,
+            "requires": {
+                "@types/color-name": "*"
+            }
+        },
+        "@types/color-name": {
+            "version": "1.1.1",
+            "resolved": 
"https://registry.npmmirror.com/@types/color-name/download/@types/color-name-1.1.1.tgz";,
+            "integrity": "sha1-HBJhu+qhCoBVu8XYq4S3sq/IRqA=",
+            "dev": true
+        },
         "@types/glob": {
             "version": "7.1.4",
             "resolved": 
"https://registry.nlark.com/@types/glob/download/@types/glob-7.1.4.tgz";,
@@ -1000,11 +1024,19 @@
             "integrity": "sha1-5jYpwAFmZXkgYNu+t5xCI50sUoc=",
             "dev": true
         },
+        "color": {
+            "version": "4.1.0",
+            "resolved": 
"https://registry.npmmirror.com/color/download/color-4.1.0.tgz";,
+            "integrity": 
"sha512-o2rkkxyLGgYoeUy1OodXpbPAQNmlNBrirQ8ODO8QutzDiDMNdezSOZLNnusQ6pUpCQJUsaJIo9DZJKqa2HgH7A==",
+            "requires": {
+                "color-convert": "^2.0.1",
+                "color-string": "^1.9.0"
+            }
+        },
         "color-convert": {
             "version": "2.0.1",
             "resolved": 
"https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz";,
             "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
-            "dev": true,
             "requires": {
                 "color-name": "~1.1.4"
             }
@@ -1012,8 +1044,16 @@
         "color-name": {
             "version": "1.1.4",
             "resolved": 
"http://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz";,
-            "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
-            "dev": true
+            "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI="
+        },
+        "color-string": {
+            "version": "1.9.0",
+            "resolved": 
"https://registry.npmmirror.com/color-string/download/color-string-1.9.0.tgz";,
+            "integrity": 
"sha512-9Mrz2AQLefkH1UvASKj6v6hj/7eWgjnT/cVsR8CumieLoT+g900exWeNogqtweI8dxloXN9BDQTYro1oWu/5CQ==",
+            "requires": {
+                "color-name": "^1.0.0",
+                "simple-swizzle": "^0.2.2"
+            }
         },
         "colors": {
             "version": "1.4.0",
@@ -3925,6 +3965,21 @@
             "integrity": "sha1-NmpGhNF1ucqyCB42gf2jdHtsUdc=",
             "dev": true
         },
+        "simple-swizzle": {
+            "version": "0.2.2",
+            "resolved": 
"https://registry.npmmirror.com/simple-swizzle/download/simple-swizzle-0.2.2.tgz";,
+            "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
+            "requires": {
+                "is-arrayish": "^0.3.1"
+            },
+            "dependencies": {
+                "is-arrayish": {
+                    "version": "0.3.2",
+                    "resolved": 
"http://registry.npm.taobao.org/is-arrayish/download/is-arrayish-0.3.2.tgz";,
+                    "integrity": "sha1-RXSirlb3qyBolvtDHq7tBm/fjwM="
+                }
+            }
+        },
         "slash": {
             "version": "3.0.0",
             "resolved": 
"https://registry.npm.taobao.org/slash/download/slash-3.0.0.tgz?cache=0&sync_timestamp=1618384508676&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fslash%2Fdownload%2Fslash-3.0.0.tgz";,
diff --git a/package.json b/package.json
index 1ba51f0..c79c5aa 100644
--- a/package.json
+++ b/package.json
@@ -9,6 +9,7 @@
     },
     "devDependencies": {
         "@babel/polyfill": "^7.12.1",
+        "@types/color": "^3.0.2",
         "@vitejs/plugin-vue": "^1.2.2",
         "@vue/compiler-sfc": "^3.0.11",
         "chalk": "^3.0.0",
@@ -23,6 +24,7 @@
         "yargs": "^6.6.0"
     },
     "dependencies": {
+        "color": "^4.1.0",
         "echarts": "^5.2.2",
         "echarts-wordcloud": "file:../echarts-wordcloud",
         "element-plus": "^1.0.2-beta.44",
diff --git a/src/App.vue b/src/App.vue
index bd3ffef..c5d1655 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -1,26 +1,26 @@
 <template>
-<el-container>
+  <el-container>
     <el-aside>
-        <h3>
-            {{$t('title')}}
-        </h3>
-        <el-tabs type="card" v-model="activeName">
-            <el-tab-pane label="样式" name="config">
-                <WConfig ref="wconfig" @change="onChange"></WConfig>
-            </el-tab-pane>
-            <el-tab-pane label="数据" name="data">
-                <WData ref="wdata" @change="onChange"></WData>
-            </el-tab-pane>
-            <el-tab-pane label="导出" name="export">导出</el-tab-pane>
-        </el-tabs>
+      <h3>
+        {{ $t('title') }}
+      </h3>
+      <el-tabs type="card" v-model="activeName">
+        <el-tab-pane label="样式" name="config">
+          <WConfig ref="wconfig" @change="onChange"></WConfig>
+        </el-tab-pane>
+        <el-tab-pane label="数据" name="data">
+          <WData ref="wdata" @change="onChange"></WData>
+        </el-tab-pane>
+        <el-tab-pane label="导出" name="export">导出</el-tab-pane>
+      </el-tabs>
     </el-aside>
     <el-main>
-        <WChart ref="wchart"></WChart>
+      <WChart ref="wchart"></WChart>
     </el-main>
-</el-container>
+  </el-container>
 </template>
 
-<script lang='ts' setup>
+<script lang="ts" setup>
 import { ref } from 'vue';
 import { useI18n } from 'vue-i18n';
 import WChart from './components/WChart.vue';
@@ -32,41 +32,43 @@ const wconfig = ref<any>(null);
 const wdata = ref<any>(null);
 const wchart = ref<any>(null);
 
-const {t} = useI18n({ useScope: 'global' });
+const { t } = useI18n({ useScope: 'global' });
 const activeName = 'config';
 
 function onChange() {
-    wchart.value?.run(wdata.value?.data, wconfig.value?.getConfig());
+  wchart.value?.run(wdata.value?.data, wconfig.value?.getConfig());
 }
 
 setTimeout(() => {
-    wdata.value?.setData(defaultData);
+  wdata.value?.setData(defaultData);
 });
 </script>
 
 <style>
 h4 {
-    margin: 10px 0;
+  margin: 10px 0;
 }
 </style>
 
 <style scoped lang="scss">
 #echarts-spa-app {
-    font-family: Avenir, Helvetica, Arial, sans-serif;
-    -webkit-font-smoothing: antialiased;
-    -moz-osx-font-smoothing: grayscale;
-    text-align: center;
-    color: #2c3e50;
+  font-family: Avenir, Helvetica, Arial, sans-serif;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+  text-align: center;
+  color: #2c3e50;
 
-    position: absolute;
-    left: 0;
-    right: 0;
-    top: 0;
-    bottom: 0;
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
 }
 
 .el-aside {
-    padding: 0 15px;
-    --el-aside-width: 400px;
+  padding: 0 15px;
+  --el-aside-width: 400px;
+  height: calc(100vh - 50px);
+  overflow: auto;
 }
 </style>
diff --git a/src/components/WChart.vue b/src/components/WChart.vue
index f351378..037d5ab 100644
--- a/src/components/WChart.vue
+++ b/src/components/WChart.vue
@@ -8,6 +8,7 @@
 import { onMounted, shallowRef, ref } from 'vue';
 import * as echarts from 'echarts';
 import 'echarts-wordcloud';
+import Color from 'color';
 
 // const props = defineProps({
 //   foo: String
@@ -20,7 +21,8 @@ defineExpose({
 });
 
 type Config = {
-  hue: number[];
+  bgColor: string;
+  themeColors: string[];
   saturation: number[];
   lightness: number[];
   alpha: number[];
@@ -33,8 +35,32 @@ type Config = {
 };
 
 function run(data?: [], config?: Config) {
-  config && console.log(config.width, config.height);
+  const hues = config
+    ? config.themeColors.map(
+        color =>
+          Color(color)
+            .hsl()
+            .object().h
+      )
+    : [];
+
+  function getHue() {
+    const index = Math.floor(Math.random() * hues.length);
+    return hues[index];
+  }
+
+  function getRandom(minMax: number[] | undefined) {
+    if (!minMax) {
+      return 0;
+    }
+    const max = minMax[1] == null ? 1 : minMax[1];
+    const min = minMax[0] == null ? 0 : minMax[0];
+    const range = max - min || 1;
+    return Math.random() * range + min;
+  }
+
   chart.value!.setOption({
+    backgroundColor: config!.bgColor,
     series: [
       {
         type: 'wordCloud',
@@ -46,7 +72,17 @@ function run(data?: [], config?: Config) {
         width: config?.width + '%',
         height: config?.height + '%',
         layoutAnimation: true,
-        keepAspect: true
+        keepAspect: true,
+        textStyle: {
+          color: (param: any) => {
+            const value = param.value;
+            const h = getHue();
+            const s = getRandom(config?.saturation);
+            const l = getRandom(config?.lightness);
+            const color = Color(`hsl(${h}, ${s}%, ${l}%)`);
+            return color.toString();
+          }
+        }
       }
     ],
     textStyle: {
diff --git a/src/components/WConfig.vue b/src/components/WConfig.vue
index 1085151..37a11ff 100644
--- a/src/components/WConfig.vue
+++ b/src/components/WConfig.vue
@@ -1,69 +1,88 @@
 <template>
   <el-collapse>
     <el-collapse-item title="颜色" name="color">
-      <!-- <h5>基础色</h5>
-            <div>
-                <el-color-picker
-                    v-for="(color, index) in themeColors"
-                    v-bind:key="index"
-                    v-model="themeColors[index]"
-                    size="small"
-                >
-                </el-color-picker>
-                <div class="color-picker-btn">
-                    <i class="el-icon-minus"></i>
-                </div>
-                <div class="color-picker-btn">
-                    <i class="el-icon-plus"></i>
-                </div>
-            </div> -->
+      <h5>配色方案</h5>
+      <div>
+        <div
+          class="color-palette"
+          v-for="palette in colorPalettes"
+          :style="{ background: palette.bgColor }"
+          @click="useColorPalette(palette)"
+        >
+          <div
+            class="color"
+            v-for="color in palette.themeColors"
+            :style="{ background: color }"
+          ></div>
+        </div>
+      </div>
+
+      <h5>背景色</h5>
+      <el-color-picker v-model="bgColor" size="small" @change="change">
+      </el-color-picker>
 
       <h5>色相范围</h5>
       <el-row>
-        <el-col :span="22" :offset="1">
-          <el-slider
-            v-model="hue"
-            range
-            show-tooltip
-            :max="1"
-            :step="0.05"
-            input-size="medium"
+        <el-col :span="14">
+          <el-color-picker
+            v-for="(color, index) in themeColors"
+            v-bind:key="index"
+            v-model="themeColors[index]"
+            size="small"
+            @change="changeColor"
           >
-          </el-slider>
+          </el-color-picker>
+          <div class="color-picker-btn" @click="removeThemeColor()">
+            <i class="el-icon-minus"></i>
+          </div>
+          <div class="color-picker-btn" @click="addThemeColor()">
+            <i class="el-icon-plus"></i>
+          </div>
+        </el-col>
+        <el-col :span="8" :offset="2">
+          <el-checkbox>关联数据大小</el-checkbox>
         </el-col>
       </el-row>
 
       <h5>饱和度范围</h5>
       <el-row>
-        <el-col :span="22" :offset="1">
+        <el-col :span="13" :offset="1">
           <el-slider
             v-model="saturation"
             range
             show-tooltip
-            :max="1"
-            :step="0.05"
+            :max="100"
+            :step="1"
             input-size="medium"
+            @change="change"
           >
           </el-slider>
         </el-col>
+        <el-col :span="8" :offset="2">
+          <el-checkbox>关联数据大小</el-checkbox>
+        </el-col>
       </el-row>
 
       <h5>亮度范围</h5>
       <el-row>
-        <el-col :span="22" :offset="1">
+        <el-col :span="13" :offset="1">
           <el-slider
             v-model="lightness"
             range
             show-tooltip
-            :max="1"
-            :step="0.05"
+            :max="100"
+            :step="1"
             input-size="medium"
+            @change="change"
           >
           </el-slider>
         </el-col>
+        <el-col :span="8" :offset="2">
+          <el-checkbox>关联数据大小</el-checkbox>
+        </el-col>
       </el-row>
 
-      <h5>透明度范围</h5>
+      <!-- <h5>透明度范围</h5>
       <el-row>
         <el-col :span="22" :offset="1">
           <el-slider
@@ -76,7 +95,7 @@
           >
           </el-slider>
         </el-col>
-      </el-row>
+      </el-row> -->
     </el-collapse-item>
 
     <el-collapse-item title="文字" name="font">
@@ -108,7 +127,7 @@
             v-model="fontSize"
             range
             show-tooltip
-            :max="100"
+            :max="200"
             :step="1"
             input-size="medium"
             @change="change"
@@ -191,68 +210,97 @@
 </template>
 
 <script setup lang="ts">
-import { ref } from "vue";
-// const themeColors = ref(['#720FEB', '#EB1AA9', '#B6DA02']);
-const hue = ref([0, 255]);
-const saturation = ref([0.5, 0.8]);
-const lightness = ref([0.5, 0.8]);
+import { ref } from 'vue';
+import Color from 'color';
+
+const colorPalettes = [
+  {
+    bgColor: '#f8eddc',
+    themeColors: ['#f19d70', '#b7b7a4', '#6b705c']
+  },
+  {
+    bgColor: '#eef6fa',
+    themeColors: ['#5470c6', '#91cc75', '#fac858', '#ee6666']
+  },
+  {
+    bgColor: '#dbf3ff',
+    themeColors: ['#4aa6d5', '#d3b16a', '#fb8500']
+  },
+  // {
+  //   bgColor: '#eae2b7',
+  //   themeColors: ['#003049', '#d62828', '#f77f00', '#fcbf49']
+  // },
+  {
+    bgColor: '#fbffd1',
+    themeColors: ['#132a13', '#90a955', '#ecf39e']
+  }
+];
+
+const bgColor = ref(colorPalettes[0].bgColor);
+const themeColors = ref(colorPalettes[0].themeColors);
+const saturation = ref([50, 80]);
+const lightness = ref([50, 80]);
 const alpha = ref([0.5, 0.8]);
-const selectedFontFamily = ref("Arial");
+const selectedFontFamily = ref('Arial');
 const fontSize = ref([4, 100]);
 const rotate = ref([-90, 90]);
 const width = ref(90);
 const height = ref(90);
-const selectedMask = ref("circle");
+const selectedMask = ref('circle');
 
 const fontFamilies = [
-  "Arial",
-  "Lato",
-  "Times New Roman",
-  "Courier New",
-  "Georgia",
-  "Helvetica",
-  "Lucida Sans",
-  "Tahoma",
-  "Verdana"
+  'Arial',
+  'Lato',
+  'Times New Roman',
+  'Courier New',
+  'Georgia',
+  'Helvetica',
+  'Lucida Sans',
+  'Tahoma',
+  'Verdana'
 ];
 const masks = [
   {
-    name: "椭圆",
-    value: "circle"
+    name: '椭圆',
+    value: 'circle'
   },
   {
-    name: "方形",
-    value: "square"
+    name: '方形',
+    value: 'square'
   },
   {
-    name: "菱形",
-    value: "diamond"
+    name: '菱形',
+    value: 'diamond'
   },
   {
-    name: "三角形",
-    value: "triangle"
+    name: '三角形',
+    value: 'triangle'
   },
   {
-    name: "五边形",
-    value: "pentagon"
+    name: '五边形',
+    value: 'pentagon'
   },
   {
-    name: "五角星",
-    value: "star"
+    name: '五角星',
+    value: 'star'
   },
   {
-    name: "爱心",
-    value: "cardioid"
+    name: '爱心',
+    value: 'cardioid'
     // }, {
     //     name: '自定义图片',
     //     value: 'image'
   }
 ];
 
-const emit = defineEmits(["change"]);
+const emit = defineEmits(['change']);
 
 defineExpose({ getConfig });
 
+setTimeout(() => {
+  changeColor();
+}, 0);
+
 function changeFontFamily() {
   change();
 }
@@ -261,13 +309,64 @@ function changeMask() {
   change();
 }
 
+function changeColor() {
+  let minS = 100;
+  let maxS = 0;
+  let minL = 100;
+  let maxL = 0;
+  themeColors.value.forEach(color => {
+    const c = Color(color);
+    const s = Math.round(c.saturationv());
+    const l = Math.round(c.lightness());
+    if (s < minS) {
+      minS = s;
+    }
+    if (s > maxS) {
+      maxS = s;
+    }
+    if (l < minL) {
+      minL = l;
+    }
+    if (l > maxL) {
+      maxL = l;
+    }
+  });
+  saturation.value = [minS, maxS];
+  lightness.value = [minL, maxL];
+  change();
+}
+
 function change() {
-  emit("change");
+  emit('change');
+}
+
+function useColorPalette(palette: { bgColor: string; themeColors: string[] }) {
+  themeColors.value = palette.themeColors;
+  bgColor.value = palette.bgColor;
+  changeColor();
+}
+
+function removeThemeColor() {
+  if (themeColors.value.length === 1) {
+    return;
+  }
+  themeColors.value.splice(themeColors.value.length - 1, 1);
+  emit('change');
+}
+
+function addThemeColor() {
+  themeColors.value.push(
+    themeColors.value.length === 0
+      ? '#555'
+      : themeColors.value[themeColors.value.length - 1]
+  );
+  emit('change');
 }
 
 function getConfig() {
   return {
-    hue: hue.value,
+    bgColor: bgColor.value,
+    themeColors: themeColors.value,
     saturation: saturation.value,
     lightness: lightness.value,
     alpha: alpha.value,
@@ -276,7 +375,7 @@ function getConfig() {
     rotate: rotate.value,
     width: width.value,
     height: height.value,
-    shape: selectedMask.value === "image" ? null : selectedMask.value
+    shape: selectedMask.value === 'image' ? null : selectedMask.value
   };
 }
 </script>
@@ -296,7 +395,8 @@ function getConfig() {
   margin-right: 5px;
 }
 
-.color-picker-btn {
+.color-picker-btn,
+.color-palette {
   display: inline-block;
   width: 30px;
   height: 30px;
@@ -309,6 +409,32 @@ function getConfig() {
   color: #409eff;
 }
 
+.color-palette {
+  display: inline-block;
+  margin-bottom: 5px;
+  width: auto;
+  height: 33px;
+  padding: 5px;
+  cursor: pointer;
+
+  .color {
+    display: inline-block;
+    width: 20px;
+    height: 20px;
+    margin-right: 5px;
+    border-radius: 3px;
+
+    &:last-child {
+      margin-right: 0;
+    }
+  }
+}
+
+.el-checkbox {
+  --el-checkbox-font-color: #888;
+  margin-top: 7px;
+}
+
 .text-pad {
   padding: 8px 0;
 }

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@echarts.apache.org
For additional commands, e-mail: commits-h...@echarts.apache.org

Reply via email to